merge with dev

This commit is contained in:
dianafa 2015-06-11 19:36:28 +02:00
commit 753e320027
9 changed files with 244 additions and 147 deletions

View file

@ -93,7 +93,7 @@ class PortableInfoboxParserTagController extends WikiaController {
$renderedValue = trim( json_encode( $renderedValue ), '"' );
}
$marker = $parser->uniqPrefix() . "-" . self::PARSER_TAG_NAME . "-{$this->markerNumber}-QINU";
$marker = $parser->uniqPrefix() . "-" . self::PARSER_TAG_NAME . "-{$this->markerNumber}\x7f-QINU";
$this->markers[ $marker ] = $renderedValue;
return [ $marker, 'markerType' => 'nowiki' ];
}

View file

@ -14,4 +14,8 @@ class DummyParser implements ExternalParser {
public function replaceVariables( $text ) {
return "replaceVariables($text)";
}
public function addImage( $title ) {
//do nothing
}
}

View file

@ -7,4 +7,6 @@ interface ExternalParser {
public function parseRecursive( $text );
public function replaceVariables( $text );
public function addImage( $title );
}

View file

@ -23,11 +23,17 @@ class MediaWikiParserService implements ExternalParser {
//fix for first item list elements
$wikitext = "\n" . $wikitext;
}
$parsedText = $this->getParserInstance()
->parse( $wikitext, $this->getParserTitle(), $this->getParserOptions(), false )
->getText();
//save current options state, as it'll be overridden by new instance when parse is invoked
$options = $this->getParserOptions();
$tmpOptions = clone $options;
$tmpOptions->setIsPartialParse( true );
$output = $this->parser->parse( $wikitext, $this->getParserTitle(), $tmpOptions, false, false )->getText();
//restore options state
$this->parser->Options( $options );
wfProfileOut( __METHOD__ );
return $parsedText;
return $output;
}
/**
@ -47,10 +53,21 @@ class MediaWikiParserService implements ExternalParser {
}
public function replaceVariables( $wikitext ) {
$output = $this->parser->replaceVariables ( $wikitext, $this->frame );
$output = $this->parser->replaceVariables( $wikitext, $this->frame );
return $output;
}
/**
* Add image to parser output for later usage
* @param string $title
*/
public function addImage( $title ) {
$file = wfFindFile( $title );
$tmstmp = $file ? $file->getTimestamp() : false;
$sha1 = $file ? $file->getSha1() : false;
$this->parser->getOutput()->addImage( $title, $tmstmp, $sha1 );
}
private function getParserTitle() {
return $this->parser->getTitle();
}
@ -60,11 +77,4 @@ class MediaWikiParserService implements ExternalParser {
$options->enableLimitReport( false );
return $options;
}
private function getParserInstance() {
if ( !isset( $this->localParser ) ) {
$this->localParser = new \Parser();
}
return $this->localParser;
}
}

View file

@ -1,6 +1,7 @@
<?php
namespace Wikia\PortableInfobox\Parser\Nodes;
use Wikia\PortableInfobox\Helpers\SimpleXmlUtil;
use Wikia\PortableInfobox\Parser\ExternalParser;
use Wikia\PortableInfobox\Parser\SimpleParser;
@ -14,7 +15,9 @@ class Node {
protected $xmlNode;
protected $parent = null;
/* @var $externalParser ExternalParser */
/**
* @var $externalParser ExternalParser
*/
protected $externalParser;
public function __construct( \SimpleXMLElement $xmlNode, $infoboxData ) {
@ -47,6 +50,7 @@ class Node {
if ( !isset( $this->externalParser ) ) {
$this->setExternalParser( new SimpleParser() );
}
return $this->externalParser;
}
@ -74,69 +78,79 @@ class Node {
/**
* @desc Check if node is empty.
* Note that a '0' value cannot be treated like a null
*
* @param $data
*
* @return bool
*/
public function isEmpty( $data ) {
$value = $data[ 'value' ];
return !( isset( $value ) ) || (empty( $value ) && $value != '0');
return !( isset( $value ) ) || ( empty( $value ) && $value != '0' );
}
protected function getValueWithDefault( \SimpleXMLElement $xmlNode ) {
$source = $this->getXmlAttribute( $xmlNode, self::DATA_SRC_ATTR_NAME );
$value = null;
if ( !empty( $source ) ) {
$value = $this->getInfoboxData( $source );
}
if ( !$value ) {
if ( $xmlNode->{self::DEFAULT_TAG_NAME} ) {
/*
* <default> tag can contain <ref> or other WikiText parser hooks
* We should not parse it's contents as XML but return pure text in order to let MediaWiki Parser
* parse it.
*/
$value = \Wikia\PortableInfobox\Helpers\SimpleXmlUtil::getInstance()->getInnerXML(
$xmlNode->{self::DEFAULT_TAG_NAME}
);
$value = $this->getExternalParser()->parseRecursive( $value );
}
$value = $this->extractDataFromSource( $xmlNode );
if ( !$value && $xmlNode->{self::DEFAULT_TAG_NAME} ) {
$value = $this->extractDataFromNode( $xmlNode->{self::DEFAULT_TAG_NAME} );
}
return $value;
}
protected function getRawValueWithDefault( \SimpleXMLElement $xmlNode ) {
$source = $this->getXmlAttribute( $xmlNode, self::DATA_SRC_ATTR_NAME );
$value = null;
if ( !empty( $source ) ) {
$value = $this->getRawInfoboxData( $source );
}
if ( !$value ) {
if ( $xmlNode->{self::DEFAULT_TAG_NAME} ) {
$value = (string)$xmlNode->{self::DEFAULT_TAG_NAME};
$value = $this->getExternalParser()->replaceVariables( $value );
}
$value = $this->getRawInfoboxData( $this->getXmlAttribute( $xmlNode, self::DATA_SRC_ATTR_NAME ) );
if ( !$value && $xmlNode->{self::DEFAULT_TAG_NAME} ) {
$value = $this->getExternalParser()->replaceVariables( (string)$xmlNode->{self::DEFAULT_TAG_NAME} );
}
return $value;
}
protected function getValueWithData( \SimpleXMLElement $xmlNode ) {
$value = $this->extractDataFromSource( $xmlNode );
return $value ? $value
: $this->extractDataFromNode( $xmlNode );
}
protected function getXmlAttribute( \SimpleXMLElement $xmlNode, $attribute ) {
if ( isset( $xmlNode[ $attribute ] ) )
return (string)$xmlNode[ $attribute ];
return null;
return ( isset( $xmlNode[ $attribute ] ) ) ? (string)$xmlNode[ $attribute ]
: null;
}
protected function getXmlAttributeFromSupported( \SimpleXMLElement $xmlNode, $attribute, $supportedAttributes ) {
$attr = $this->getXmlAttribute( $xmlNode, $attribute );
if ( isset($attr) && in_array( $attr, $supportedAttributes ) ) {
return $attr;
}
return self::DEFAULT_TAG_NAME;
}
protected function getRawInfoboxData ( $key ) {
$data = isset( $this->infoboxData[ $key ] ) ? $this->infoboxData[ $key ] : null;
return $data;
protected function getRawInfoboxData( $key ) {
return isset( $this->infoboxData[ $key ] ) ? $this->infoboxData[ $key ]
: null;
}
protected function getInfoboxData( $key ) {
return $this->getExternalParser()->parseRecursive( $this->getRawInfoboxData ( $key ) );
return $this->getExternalParser()->parseRecursive( $this->getRawInfoboxData( $key ) );
}
/**
* @param \SimpleXMLElement $xmlNode
*
* @return mixed
*/
protected function extractDataFromSource( \SimpleXMLElement $xmlNode ) {
$source = $this->getXmlAttribute( $xmlNode, self::DATA_SRC_ATTR_NAME );
return ( !empty( $source ) ) ? $this->getInfoboxData( $source )
: null;
}
/**
* @param \SimpleXMLElement $xmlNode
*
* @return string
*/
protected function extractDataFromNode( \SimpleXMLElement $xmlNode ) {
/*
* <default> tag can contain <ref> or other WikiText parser hooks
* We should not parse it's contents as XML but return pure text in order to let MediaWiki Parser
* parse it.
*/
return $this->getExternalParser()->parseRecursive( SimpleXmlUtil::getInstance()->getInnerXML( $xmlNode ) );
}
}

View file

@ -11,16 +11,13 @@ class NodeData extends Node {
return false;
}
}
return true;
}
public function getData() {
return [
'label' => $this->getExternalParser()->parseRecursive(
\Wikia\PortableInfobox\Helpers\SimpleXmlUtil::getInstance()->getInnerXML(
$this->xmlNode->{self::LABEL_TAG_NAME}
)
),
'label' => $this->getValueWithData( $this->xmlNode->{self::LABEL_TAG_NAME} ),
'value' => $this->getValueWithDefault( $this->xmlNode )
];
}

View file

@ -8,7 +8,9 @@ class NodeImage extends Node {
const CAPTION_TAG_NAME = 'caption';
public function getData() {
$title = $this->getImageAsTitleObject( $this->getRawValueWithDefault( $this->xmlNode ) );
$imageName = $this->getRawValueWithDefault( $this->xmlNode );
$title = $this->getImageAsTitleObject( $imageName );
$this->getExternalParser()->addImage( $title ? $title->getDBkey() : $imageName );
$ref = null;
$alt = $this->getValueWithDefault( $this->xmlNode->{self::ALT_TAG_NAME} );
$caption = $this->getValueWithDefault( $this->xmlNode->{self::CAPTION_TAG_NAME} );
@ -35,12 +37,15 @@ class NodeImage extends Node {
ImageFilenameSanitizer::getInstance()->sanitizeImageFileName( $imageName, $wgContLang ),
NS_FILE
);
return $title;
}
/**
* @desc returns image url for given image title
*
* @param string $title
*
* @return string url or '' if image doesn't exist
*/
public function resolveImageUrl( $title ) {
@ -50,6 +55,7 @@ class NodeImage extends Node {
return $file->getUrl();
}
}
return '';
}
}

View file

@ -13,4 +13,8 @@ class SimpleParser implements ExternalParser {
public function replaceVariables( $text ) {
return $text;
}
public function addImage( $title ) {
//do nothing
}
}

View file

@ -7,107 +7,167 @@ class PortableInfoboxParserNodesTest extends WikiaBaseTest {
parent::setUp();
}
public function testNodeTitle() {
$string = '<title source="nombre"><default>def</default></title>';
$xml = simplexml_load_string( $string );
/** @dataProvider titleNodeTestProvider */
public function testNodeTitle( $markup, $params, $expected ) {
$data = ( new Wikia\PortableInfobox\Parser\Nodes\NodeTitle( simplexml_load_string( $markup ), $params ) )
->getData();
$node = new Wikia\PortableInfobox\Parser\Nodes\NodeTitle( $xml, [ 'nombre' => 1 ] );
$nodeDefault = new Wikia\PortableInfobox\Parser\Nodes\NodeTitle( $xml, [ ] );
$this->assertTrue( $node->getData()[ 'value' ] == 1 );
$this->assertTrue( $nodeDefault->getData()[ 'value' ] == 'def' );
$this->assertEquals( $expected, $data );
}
public function testNodeData() {
$string = '<data source="Season"><label>Season(s)</label><default>Lorem ipsum</default></data>';
$xml = simplexml_load_string( $string );
$node = new Wikia\PortableInfobox\Parser\Nodes\NodeData( $xml, [ 'Season' => 1 ] );
$nodeDefault = new Wikia\PortableInfobox\Parser\Nodes\NodeData( $xml, [ ] );
$this->assertTrue( $node->getData()[ 'value' ] == 1 );
$this->assertTrue( $nodeDefault->getData()[ 'value' ] == 'Lorem ipsum' );
public function titleNodeTestProvider() {
return [
// markup, params, expected
[ '<title source="nombre"><default>def</default></title>',
[ 'nombre' => 1 ], [ 'value' => 1 ] ],
[ '<title source="nombre"><default>def</default></title>',
[ ], [ 'value' => 'def' ] ],
];
}
public function testNodeImage() {
$string = '<image source="image2">
<alt source="alt-source"><default>default-alt</default></alt>
<caption source="caption"><default>default caption</default></caption>
</image>';
$xml = simplexml_load_string( $string );
/** @dataProvider dataNodeTestProvider */
public function testNodeData( $markup, $params, $expected ) {
$data = ( new Wikia\PortableInfobox\Parser\Nodes\NodeData( simplexml_load_string( $markup ), $params ) )
->getData();
$nodeDefault = new Wikia\PortableInfobox\Parser\Nodes\NodeImage( $xml, [ ] );
$this->assertEquals( $expected, $data );
}
public function dataNodeTestProvider() {
return [
// markup, params, expected
[ '<data source="Season"><label>Season(s)</label><default>Lorem ipsum</default></data>',
[ 'Season' => 1 ], [ 'value' => 1, 'label' => 'Season(s)' ] ],
[ '<data source="Season"><label>Season(s)</label><default>Lorem ipsum</default></data>',
[ ], [ 'value' => 'Lorem ipsum', 'label' => 'Season(s)' ] ],
[ '<data source="Season"><label>Season 1</label><label>Season 2</label></data>',
[ 'Season' => 1 ], [ 'value' => 1, 'label' => 'Season 1' ] ],
[ '<data source="Season"><default>Season 1</default><default>Season 2</default></data>',
[ ], [ 'value' => 'Season 1', 'label' => '' ] ],
];
}
/** @dataProvider imageNodeTestProvider */
public function testNodeImage( $markup, $params, $imageUrl, $expected ) {
$node = $this->getMockBuilder( 'Wikia\PortableInfobox\Parser\Nodes\NodeImage' )
->setConstructorArgs( [ $xml, [ 'image2' => 'aaa.jpg',
'alt-source' => 'bbb',
'caption' => 'capt' ] ] )
->setMethods( [ 'resolveImageUrl' ] )
->getMock();
$node->expects( $this->any() )->method( 'resolveImageUrl' )->will( $this->returnValue( 'aaa.jpg' ) );
$this->assertTrue( $node->getData()[ 'url' ] == 'aaa.jpg', 'value is not aaa.jpg' );
$this->assertTrue( $node->getData()[ 'name' ] == 'Aaa.jpg', 'value is not aaa.jpg' );
$this->assertTrue( $node->getData()[ 'alt' ] == 'bbb', 'alt is not bbb' );
$this->assertTrue( $node->getData()[ 'caption' ] == 'capt', 'caption is not "capt"' );
$this->assertTrue( $nodeDefault->getData()[ 'alt' ] == 'default-alt', 'default alt' );
$this->assertTrue( $nodeDefault->getData()[ 'caption' ] == 'default caption', 'default caption' );
->setConstructorArgs( [ simplexml_load_string( $markup ), $params ] )
->setMethods( [ 'resolveImageUrl' ] )
->getMock();
$node->expects( $this->any() )->method( 'resolveImageUrl' )->will( $this->returnValue( $imageUrl ) );
$this->assertEquals( $expected, $node->getData() );
}
public function testNodeHeader() {
$string = '<header>Comandantes</header>';
$xml = simplexml_load_string( $string );
$node = new Wikia\PortableInfobox\Parser\Nodes\NodeHeader( $xml, [ ] );
$this->assertTrue( $node->getData()[ 'value' ] == 'Comandantes' );
public function imageNodeTestProvider() {
return [
// markup, params, mocked image name, expected
[ '<image source="image2"><alt source="alt-source"><default>default-alt</default></alt>
<caption source="caption"><default>default caption</default></caption></image>',
[ 'image2' => 'aaa.jpg', 'alt-source' => 'bbb', 'caption' => 'capt' ], 'aaa.jpg',
[ 'url' => 'aaa.jpg', 'name' => 'Aaa.jpg', 'key' => 'Aaa.jpg', 'alt' => 'bbb', 'caption' => 'capt',
'ref' => 0 ] ],
[ '<image source="image2"><alt source="alt-source"><default>default-alt</default></alt>
<caption source="caption"><default>default caption</default></caption></image>',
[ ], 'aaa.jpg',
[ 'url' => 'aaa.jpg', 'name' => '', 'key' => '', 'alt' => 'default-alt', 'caption' => 'default caption',
'ref' => null ] ],
];
}
public function testNodeFooter() {
$string = '<footer>123</footer>';
$xml = simplexml_load_string( $string );
$node = new Wikia\PortableInfobox\Parser\Nodes\NodeFooter( $xml, [ ] );
$this->assertTrue( $node->getData()[ 'value' ] == '123' );
/** @dataProvider headerNodeTestProvider */
public function testNodeHeader( $markup, $params, $expected ) {
$data = ( new Wikia\PortableInfobox\Parser\Nodes\NodeHeader( simplexml_load_string( $markup ), $params ) )
->getData();
$this->assertEquals( $expected, $data );
}
public function testNodeGroup() {
$string = '<group>
<data source="elem1"><label>l1</label><default>def1</default></data>
<data source="elem2"><label>l2</label><default>def2</default></data>
<data source="elem3"><label>l2</label></data>
</group>
';
$xml = simplexml_load_string( $string );
$node = new Wikia\PortableInfobox\Parser\Nodes\NodeGroup( $xml, [ 'elem1' => 1, 'elem2' => 2 ] );
$data = $node->getData();
$this->assertTrue( is_array( $data[ 'value' ] ), 'value is array' );
$this->assertTrue( $data[ 'value' ][ 0 ][ 'data' ][ 'value' ] == 1, 'first elem' );
$this->assertTrue( $data[ 'value' ][ 1 ][ 'data' ][ 'value' ] == 2, 'second elem' );
$this->assertTrue( $data[ 'value' ][ 1 ][ 'data' ][ 'label' ] == 'l2', 'second elem - label' );
$this->assertTrue( $data[ 'value' ][ 2 ][ 'isNotEmpty' ] == false, 'empty' );
public function headerNodeTestProvider() {
return [
// markup, params, expected
[ '<header>Comandantes</header>', [ ], [ 'value' => 'Comandantes' ] ]
];
}
public function testNodeComparison() {
$string = '<comparison>
<set>
<header>Combatientes</header>
<data source="lado1" />
<data source="lado2" />
</set>
<set>
<header>Comandantes</header>
<data source="comandantes1" />
<data source="comandantes2" />
</set>
</comparison>
';
$xml = simplexml_load_string( $string );
/** @dataProvider footerNodeTestProvider */
public function testNodeFooter( $markup, $params, $expected ) {
$data = ( new Wikia\PortableInfobox\Parser\Nodes\NodeFooter( simplexml_load_string( $markup ), $params ) )
->getData();
$this->assertEquals( $expected, $data );
}
$node = new Wikia\PortableInfobox\Parser\Nodes\NodeComparison( $xml, [ 'lado1' => 1, 'lado2' => 2 ] );
$data = $node->getData();
public function footerNodeTestProvider() {
return [
[ '<footer>123</footer>', [ ], [ 'value' => '123' ] ]
];
}
$this->assertTrue( is_array( $data[ 'value' ] ), 'value is array' );
$this->assertTrue( $data[ 'value' ][ 0 ]['data']['value'][ 0 ][ 'type' ] == 'header' );
$this->assertTrue( $data[ 'value' ][ 0 ]['data']['value'][ 0 ][ 'data' ][ 'value' ] == 'Combatientes' );
$this->assertTrue( $data[ 'value' ][ 0 ]['data']['value'][ 1 ][ 'type' ] == 'data' );
$this->assertTrue( $data[ 'value' ][ 0 ]['data']['value'][ 2 ][ 'data' ][ 'value' ] == 2 );
/** @dataProvider groupNodeTestProvider */
public function testNodeGroup( $markup, $params, $expected ) {
$data = ( new Wikia\PortableInfobox\Parser\Nodes\NodeGroup( simplexml_load_string( $markup ), $params ) )
->getData();
$this->assertEquals( $expected, $data );
}
public function groupNodeTestProvider() {
return [
[ '<group><data source="elem1"><label>l1</label><default>def1</default></data><data source="elem2">
<label>l2</label><default>def2</default></data><data source="elem3"><label>l2</label></data></group>',
[ 'elem1' => 1, 'elem2' => 2 ],
[ 'value' =>
[
[ 'type' => 'data', 'isEmpty' => false, 'data' => [ 'label' => 'l1', 'value' => 1 ] ],
[ 'type' => 'data', 'isEmpty' => false, 'data' => [ 'label' => 'l2', 'value' => 2 ] ]
]
] ],
];
}
/** @dataProvider comparisonNodeTestProvider */
public function testNodeComparison( $markup, $params, $expected ) {
$data = ( new Wikia\PortableInfobox\Parser\Nodes\NodeComparison( simplexml_load_string( $markup ), $params ) )
->getData();
$this->assertEquals( $expected, $data );
}
public function comparisonNodeTestProvider() {
return [
[ '<comparison><set><header>Combatientes</header><data source="lado1" /><data source="lado2" /></set>
<set><header>Comandantes</header><data source="comandantes1" /><data source="comandantes2" /></set>
</comparison>', [ 'lado1' => 1, 'lado2' => 2 ],
[ 'value' => [
[
'type' => 'set', 'isEmpty' => false, 'data' => [
'value' => [
[ 'type' => 'header', 'isEmpty' => false, 'data' => [ 'value' => 'Combatientes' ] ],
[ 'type' => 'data', 'isEmpty' => false, 'data' => [ 'label' => '', 'value' => 1 ] ],
[ 'type' => 'data', 'isEmpty' => false, 'data' => [ 'label' => '', 'value' => 2 ] ]
]
]
] ] ] ],
];
}
/** @dataProvider labelTestProvider */
public function testLabelTag( $markup, $params, $expected ) {
$data = ( new \Wikia\PortableInfobox\Parser\Nodes\NodeData( simplexml_load_string( $markup ), $params ) )
->getData();
$this->assertEquals( $expected, $data );
}
public function labelTestProvider() {
return [
// markup, params, expected
[ '<data source="test"><label source="test label">Test default</label></data>',
[ 'test' => 1, 'test label' => 2 ], [ 'label' => 2, 'value' => 1 ] ],
[ '<data source="test"><label source="test label">default</label></data>',
[ 'test' => 1 ], [ 'label' => 'default', 'value' => 1 ] ],
[ '<data source="test"><label>default</label></data>',
[ 'test' => 1 ], [ 'label' => 'default', 'value' => 1 ] ],
[ '<data source="test"></data>',
[ 'test' => 1 ], [ 'label' => '', 'value' => 1 ] ],
];
}
}