diff --git a/PortableInfobox.setup.php b/PortableInfobox.setup.php index 47da56e..4592c12 100644 --- a/PortableInfobox.setup.php +++ b/PortableInfobox.setup.php @@ -18,7 +18,9 @@ $wgExtensionCredits[ 'parserhook' ][] = [ $wgAutoloadClasses[ 'PortableInfoboxRenderService' ] = $dir . 'services/PortableInfoboxRenderService.class.php'; // 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\\DummyParser'] = $dir . 'services/Parser/DummyParser.php'; $wgAutoloadClasses[ 'Wikia\\PortableInfobox\\Parser\\MediaWikiParserService'] = $dir . 'services/Parser/MediaWikiParserService.php'; $wgInfoboxParserNodes = [ 'Node', @@ -36,6 +38,9 @@ foreach ( $wgInfoboxParserNodes as $parserNode ) { $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 $wgAutoloadClasses[ 'PortableInfoboxParserTagController' ] = $dir . 'controllers/PortableInfoboxParserTagController.class.php'; $wgAutoloadClasses[ 'PortableInfoboxHooks' ] = $dir . 'PortableInfoboxHooks.class.php'; diff --git a/services/Helpers/ImageFilenameSanitizer.php b/services/Helpers/ImageFilenameSanitizer.php new file mode 100644 index 0000000..d2d1465 --- /dev/null +++ b/services/Helpers/ImageFilenameSanitizer.php @@ -0,0 +1,60 @@ +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; + } +} diff --git a/services/Parser/DummyParser.php b/services/Parser/DummyParser.php new file mode 100644 index 0000000..4ff1c8c --- /dev/null +++ b/services/Parser/DummyParser.php @@ -0,0 +1,13 @@ +getInfoboxData( $this->getXmlAttribute($this->xmlNode, self::DATA_SRC_ATTR_NAME ) ); + + $imageName = $this->getValueWithDefault( $this->xmlNode ); $node['value'] = $this->resolveImageUrl( $imageName ); $node['alt'] = $this->getValueWithDefault( $this->xmlNode->{self::ALT_TAG_NAME} ); + return $node; } - protected function resolveImageUrl( $filename ) { - $title = \Title::newFromText( $filename, NS_FILE ); + public function resolveImageUrl( $filename ) { + global $wgContLang; + $title = \Title::newFromText( \Wikia\PortableInfobox\Helpers\ImageFilenameSanitizer::getInstance() + ->sanitizeImageFileName($filename, $wgContLang), NS_FILE ); if ( $title && $title->exists() ) { - return \WikiaFileHelper::getFileFromTitle($title)->getUrlGenerator()->url(); + return \WikiaFileHelper::getFileFromTitle( $title )->getUrlGenerator()->url(); + } else { + return ""; } - return ""; } } diff --git a/tests/ImageFilenameSanitizerTest.php b/tests/ImageFilenameSanitizerTest.php new file mode 100644 index 0000000..3e6155b --- /dev/null +++ b/tests/ImageFilenameSanitizerTest.php @@ -0,0 +1,85 @@ +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' + ] + ]; + } +} diff --git a/tests/ParserNodesTest.php b/tests/ParserNodesTest.php index b3ab5e0..7059c8d 100644 --- a/tests/ParserNodesTest.php +++ b/tests/ParserNodesTest.php @@ -1,12 +1,10 @@ setupFile = dirname( __FILE__ ) . '/../PortableInfobox.setup.php'; parent::setUp(); - require_once( dirname( __FILE__ ) . '/../PortableInfobox.setup.php' ); - foreach ( $wgAutoloadClasses as $class => $file) { - require_once($file); - } } public function testNodeTitle() { diff --git a/tests/PortableInfoboxParserTagControllerTest.php b/tests/PortableInfoboxParserTagControllerTest.php index 93666c6..4b160dc 100644 --- a/tests/PortableInfoboxParserTagControllerTest.php +++ b/tests/PortableInfoboxParserTagControllerTest.php @@ -3,8 +3,8 @@ class PortableInfoboxParserTagControllerTest extends WikiaBaseTest { protected function setUp() { + $this->setupFile = dirname( __FILE__ ) . '/../PortableInfobox.setup.php'; parent::setUp(); - require_once( dirname( __FILE__ ) . '/../PortableInfobox.setup.php' ); } public function testEmptyInfobox() { diff --git a/tests/PortableInfoboxRenderServiceTest.php b/tests/PortableInfoboxRenderServiceTest.php index db4966a..43a12bb 100644 --- a/tests/PortableInfoboxRenderServiceTest.php +++ b/tests/PortableInfoboxRenderServiceTest.php @@ -3,9 +3,9 @@ class PortableInfoboxRenderServiceTest extends PHPUnit_Framework_TestCase { private $infoboxRenderService; - public function setUp() { + protected function setUp() { + $this->setupFile = dirname( __FILE__ ) . '/../PortableInfobox.setup.php'; parent::setUp(); - require_once( dirname( __FILE__ ) . '/../PortableInfobox.setup.php' ); $this->infoboxRenderService = new PortableInfoboxRenderService(); } diff --git a/tests/XmlParserTest.php b/tests/XmlParserTest.php index bab7f27..a1333f3 100644 --- a/tests/XmlParserTest.php +++ b/tests/XmlParserTest.php @@ -1,21 +1,10 @@ setupFile = dirname( __FILE__ ) . '/../PortableInfobox.setup.php'; parent::setUp(); - require_once( dirname( __FILE__ ) . '/../PortableInfobox.setup.php' ); } public function testIsEmpty() { @@ -52,7 +41,7 @@ class XmlParserTest extends WikiaBaseTest { 'elem2' => 'ELEM2', 'lado2' => 'LALALA' ]); - $externalParser = new TestParser(); + $externalParser = new \Wikia\PortableInfobox\Parser\DummyParser(); $parser->setExternalParser( $externalParser ); $markup = '