Merge pull request #7103 from Wikia/DAT-2760

DAT-2760 Backwards compatibility in <image> tag for portable infoboxes
This commit is contained in:
Sebastian Marzjan 2015-05-05 12:25:37 +02:00
commit 958e073d8a
10 changed files with 188 additions and 25 deletions

View file

@ -18,7 +18,9 @@ $wgExtensionCredits[ 'parserhook' ][] = [
$wgAutoloadClasses[ 'PortableInfoboxRenderService' ] = $dir . 'services/PortableInfoboxRenderService.class.php'; $wgAutoloadClasses[ 'PortableInfoboxRenderService' ] = $dir . 'services/PortableInfoboxRenderService.class.php';
// parser // parser
$wgAutoloadClasses[ 'Wikia\\PortableInfobox\\Parser\\ExternalParser'] = $dir . 'services/Parser/ExternalParser.php';
$wgAutoloadClasses[ 'Wikia\\PortableInfobox\\Parser\\XmlParser'] = $dir . 'services/Parser/XmlParser.php'; $wgAutoloadClasses[ 'Wikia\\PortableInfobox\\Parser\\XmlParser'] = $dir . 'services/Parser/XmlParser.php';
$wgAutoloadClasses[ 'Wikia\\PortableInfobox\\Parser\\DummyParser'] = $dir . 'services/Parser/DummyParser.php';
$wgAutoloadClasses[ 'Wikia\\PortableInfobox\\Parser\\MediaWikiParserService'] = $dir . 'services/Parser/MediaWikiParserService.php'; $wgAutoloadClasses[ 'Wikia\\PortableInfobox\\Parser\\MediaWikiParserService'] = $dir . 'services/Parser/MediaWikiParserService.php';
$wgInfoboxParserNodes = [ $wgInfoboxParserNodes = [
'Node', 'Node',
@ -36,6 +38,9 @@ foreach ( $wgInfoboxParserNodes as $parserNode ) {
$wgAutoloadClasses[ 'Wikia\\PortableInfobox\\Parser\\Nodes\\'.$parserNode ] = $dir . 'services/Parser/Nodes/'.$parserNode.'.php'; $wgAutoloadClasses[ 'Wikia\\PortableInfobox\\Parser\\Nodes\\'.$parserNode ] = $dir . 'services/Parser/Nodes/'.$parserNode.'.php';
} }
// helpers
$wgAutoloadClasses[ 'Wikia\PortableInfobox\Helpers\ImageFilenameSanitizer' ] = $dir . 'services/Helpers/ImageFilenameSanitizer.php';
// controller classes // controller classes
$wgAutoloadClasses[ 'PortableInfoboxParserTagController' ] = $dir . 'controllers/PortableInfoboxParserTagController.class.php'; $wgAutoloadClasses[ 'PortableInfoboxParserTagController' ] = $dir . 'controllers/PortableInfoboxParserTagController.class.php';
$wgAutoloadClasses[ 'PortableInfoboxHooks' ] = $dir . 'PortableInfoboxHooks.class.php'; $wgAutoloadClasses[ 'PortableInfoboxHooks' ] = $dir . 'PortableInfoboxHooks.class.php';

View file

@ -0,0 +1,60 @@
<?php
namespace Wikia\PortableInfobox\Helpers;
class ImageFilenameSanitizer {
private static $instance = null;
private $filePrefixRegex = [ ];
private function __construct() {
}
/**
* @return null|ImageFilenameSanitizer
*/
public static function getInstance() {
if ( is_null( self::$instance ) ) {
self::$instance = new self;
}
return self::$instance;
}
/**
* @param $contLang \Language
* Used as local cache for getting string to remove
*/
private function getFilePrefixRegex( $contLang ) {
$langCode = $contLang->getCode();
if ( empty( $this->filePrefixRegex[$langCode] ) ) {
$fileNamespaces = [ \MWNamespace::getCanonicalName( NS_FILE ), $contLang->getNamespaces()[NS_FILE] ];
$aliases = $contLang->getNamespaceAliases();
foreach ( $aliases as $alias => $namespaceId ) {
if ( $namespaceId == NS_FILE )
$fileNamespaces [] = $alias;
}
$this->filePrefixRegex[$langCode] = '^(' . implode( '|', $fileNamespaces ) . '):';
}
return $this->filePrefixRegex[$langCode];
}
/**
* @param $filename string
* @param $contLang \Language
* @return mixed
*/
public function sanitizeImageFileName( $filename, $contLang ) {
// replace the MW square brackets and surrounding whitespace
$trimmedFilename = trim( $filename, "\t\n\r[]" );
$filePrefixRegex = $this->getFilePrefixRegex( $contLang );
$unprefixedFilename = mbereg_replace( $filePrefixRegex, "", $trimmedFilename );
// strip
$filenameParts = explode( '|', $unprefixedFilename );
if ( !empty( $filenameParts[0] ) ) {
$filename = $filenameParts[0];
}
return $filename;
}
}

View file

@ -0,0 +1,13 @@
<?php
namespace Wikia\PortableInfobox\Parser;
class DummyParser implements ExternalParser {
public function parse( $text ) {
return "parse($text)";
}
public function parseRecursive( $text ) {
return "parseRecursive($text)";
}
}

View file

@ -0,0 +1,8 @@
<?php
namespace Wikia\PortableInfobox\Parser;
interface ExternalParser {
public function parse( $text );
public function parseRecursive( $text );
}

View file

@ -6,17 +6,22 @@ class NodeImage extends Node {
public function getData() { public function getData() {
$node = []; $node = [];
$imageName = $this->getInfoboxData( $this->getXmlAttribute($this->xmlNode, self::DATA_SRC_ATTR_NAME ) );
$imageName = $this->getValueWithDefault( $this->xmlNode );
$node['value'] = $this->resolveImageUrl( $imageName ); $node['value'] = $this->resolveImageUrl( $imageName );
$node['alt'] = $this->getValueWithDefault( $this->xmlNode->{self::ALT_TAG_NAME} ); $node['alt'] = $this->getValueWithDefault( $this->xmlNode->{self::ALT_TAG_NAME} );
return $node; return $node;
} }
protected function resolveImageUrl( $filename ) { public function resolveImageUrl( $filename ) {
$title = \Title::newFromText( $filename, NS_FILE ); global $wgContLang;
$title = \Title::newFromText( \Wikia\PortableInfobox\Helpers\ImageFilenameSanitizer::getInstance()
->sanitizeImageFileName($filename, $wgContLang), NS_FILE );
if ( $title && $title->exists() ) { if ( $title && $title->exists() ) {
return \WikiaFileHelper::getFileFromTitle($title)->getUrlGenerator()->url(); return \WikiaFileHelper::getFileFromTitle( $title )->getUrlGenerator()->url();
} else {
return "";
} }
return "";
} }
} }

View file

@ -0,0 +1,85 @@
<?php
class ImageFilenameSanitizerTest extends WikiaBaseTest {
private $imageFilenameSanitizer;
protected function setUp() {
$this->setupFile = dirname( __FILE__ ) . '/../PortableInfobox.setup.php';
parent::setUp();
$this->imageFilenameSanitizer = \Wikia\PortableInfobox\Helpers\ImageFilenameSanitizer::getInstance();
}
/**
* @param $inputFileName
* @param $expectedOutput
* @param $description
* @dataProvider testSanitizeFilenameDataProvider
*/
public function testSanitizeFilename( $inputFileName, $contentLanguageCode, $expectedOutput, $description ) {
$language = new \Language();
$language->setCode( $contentLanguageCode );
$actualOutput = $this->imageFilenameSanitizer->sanitizeImageFileName( $inputFileName, $language );
$this->assertEquals( $expectedOutput, $actualOutput, $description );
}
public function testSanitizeFilenameDataProvider() {
return [
[
'filename.jpg',
'en',
'filename.jpg',
'Plain filename'
],
[
'File:filename.jpg',
'en',
'filename.jpg',
'Filename with namespace'
],
[
'Plik:filename.jpg',
'pl',
'filename.jpg',
'Filename with localized namespace'
],
[
'Grafika:filename.jpg',
'pl',
'filename.jpg',
'Filename with localized namespace alias'
],
[
'File:filename.jpg|300px',
'en',
'filename.jpg',
'Filename with namespace and width'
],
[
'[[File:filename.jpg|300px|lorem ipsum]]',
'en',
'filename.jpg',
'Link to filename with namespace, width and caption'
],
[
'[[File:filename.jpg|lorem ipsum]]',
'en',
'filename.jpg',
'Link to filename with namespace and caption'
],
[
'{{File:filename.jpg|lorem ipsum}}',
'en',
'{{File:filename.jpg',
'Non-file string; sanitized, though useless'
],
[
'',
'en',
'',
'Empty file name'
]
];
}
}

View file

@ -1,12 +1,10 @@
<?php <?php
class PortableInfoboxParserNodesTest extends WikiaBaseTest { class PortableInfoboxParserNodesTest extends WikiaBaseTest {
protected function setUp() { protected function setUp() {
$this->setupFile = dirname( __FILE__ ) . '/../PortableInfobox.setup.php';
parent::setUp(); parent::setUp();
require_once( dirname( __FILE__ ) . '/../PortableInfobox.setup.php' );
foreach ( $wgAutoloadClasses as $class => $file) {
require_once($file);
}
} }
public function testNodeTitle() { public function testNodeTitle() {

View file

@ -3,8 +3,8 @@
class PortableInfoboxParserTagControllerTest extends WikiaBaseTest { class PortableInfoboxParserTagControllerTest extends WikiaBaseTest {
protected function setUp() { protected function setUp() {
$this->setupFile = dirname( __FILE__ ) . '/../PortableInfobox.setup.php';
parent::setUp(); parent::setUp();
require_once( dirname( __FILE__ ) . '/../PortableInfobox.setup.php' );
} }
public function testEmptyInfobox() { public function testEmptyInfobox() {

View file

@ -3,9 +3,9 @@
class PortableInfoboxRenderServiceTest extends PHPUnit_Framework_TestCase { class PortableInfoboxRenderServiceTest extends PHPUnit_Framework_TestCase {
private $infoboxRenderService; private $infoboxRenderService;
public function setUp() { protected function setUp() {
$this->setupFile = dirname( __FILE__ ) . '/../PortableInfobox.setup.php';
parent::setUp(); parent::setUp();
require_once( dirname( __FILE__ ) . '/../PortableInfobox.setup.php' );
$this->infoboxRenderService = new PortableInfoboxRenderService(); $this->infoboxRenderService = new PortableInfoboxRenderService();
} }

View file

@ -1,21 +1,10 @@
<?php <?php
require_once( dirname( __FILE__ ) . '/../services/Parser/XmlParser.php' );
class TestParser implements \Wikia\PortableInfobox\Parser\ExternalParser {
public function parse( $text ) {
return "parse($text)";
}
public function parseRecursive( $text ) {
return "parseRecursive($text)";
}
}
class XmlParserTest extends WikiaBaseTest { class XmlParserTest extends WikiaBaseTest {
protected function setUp() { protected function setUp() {
$this->setupFile = dirname( __FILE__ ) . '/../PortableInfobox.setup.php';
parent::setUp(); parent::setUp();
require_once( dirname( __FILE__ ) . '/../PortableInfobox.setup.php' );
} }
public function testIsEmpty() { public function testIsEmpty() {
@ -52,7 +41,7 @@ class XmlParserTest extends WikiaBaseTest {
'elem2' => 'ELEM2', 'elem2' => 'ELEM2',
'lado2' => 'LALALA' 'lado2' => 'LALALA'
]); ]);
$externalParser = new TestParser(); $externalParser = new \Wikia\PortableInfobox\Parser\DummyParser();
$parser->setExternalParser( $externalParser ); $parser->setExternalParser( $externalParser );
$markup = ' $markup = '
<infobox> <infobox>