Liangent has uploaded a new change for review. https://gerrit.wikimedia.org/r/72256
Change subject: New class LanguageFallbackChainSerializer ...................................................................... New class LanguageFallbackChainSerializer Change-Id: I65d69c8b12fa4e754b02e95697a754622f06bf24 --- M lib/WikibaseLib.classes.php A lib/includes/LanguageFallbackChainSerializer.php A lib/tests/phpunit/LanguageFallbackChainSerializerTest.php 3 files changed, 203 insertions(+), 0 deletions(-) git pull ssh://gerrit.wikimedia.org:29418/mediawiki/extensions/Wikibase refs/changes/56/72256/1 diff --git a/lib/WikibaseLib.classes.php b/lib/WikibaseLib.classes.php index 64893a8..56f4e40 100644 --- a/lib/WikibaseLib.classes.php +++ b/lib/WikibaseLib.classes.php @@ -42,6 +42,7 @@ 'Wikibase\DiffView' => 'includes/DiffView.php', 'Wikibase\LanguageFallbackChain' => 'includes/LanguageFallbackChain.php', 'Wikibase\LanguageFallbackChainFactory' => 'includes/LanguageFallbackChainFactory.php', + 'Wikibase\LanguageFallbackChainSerializer' => 'includes/LanguageFallbackChainSerializer.php', 'Wikibase\LanguageWithConversion' => 'includes/LanguageWithConversion.php', 'Wikibase\Lib\GuidGenerator' => 'includes/GuidGenerator.php', 'Wikibase\Lib\V4GuidGenerator' => 'includes/GuidGenerator.php', diff --git a/lib/includes/LanguageFallbackChainSerializer.php b/lib/includes/LanguageFallbackChainSerializer.php new file mode 100644 index 0000000..36318b6 --- /dev/null +++ b/lib/includes/LanguageFallbackChainSerializer.php @@ -0,0 +1,107 @@ +<?php + +namespace Wikibase; +use Language, FormatJson, MWException; + +/** + * Object serializing LanguageFallbackChain objects in Wikibase. + * + * The serialized form is not for persistant storage. They only allows + * clients to "echo" back the original fallback chain as a string. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * http://www.gnu.org/copyleft/gpl.html + * + * @since 0.4 + * + * @file + * @ingroup WikibaseLib + * + * @licence GNU GPL v2+ + */ +class LanguageFallbackChainSerializer { + + /** + * Serialize a language fallback chain into a string. JSON is used now, but + * any external component is not expected to understand the serialized form. + * + * @param LanguageFallbackChain $languageFallbackChain + * + * @return string serialized form + */ + public function serialize( LanguageFallbackChain $languageFallbackChain ) { + wfProfileIn( __METHOD__ ); + $data = array(); + + // We sacrifice readability for length here, as the serialized form may be passed around in URLs. + foreach ( $languageFallbackChain->getFallbackChain() as $item ) { + $elem = array( $item->getLanguage()->getCode() ); + + $sourceLanguage = $item->getSourceLanguage(); + if ( $sourceLanguage ) { + $elem[] = $sourceLanguage->getCode(); + } + + $data[] = implode( ':', $elem ); + } + + wfProfileOut( __METHOD__ ); + return implode( '|', $data ); + } + + /** + * Unserialize a language fallback chain from a previous serializeLanguageFallbackChain output. + * + * @param string $serialized + * + * @return LanguageFallbackChain|null on bad input + */ + public function unserialize( $serialized ) { + wfProfileIn( __METHOD__ ); + $data = explode( '|', $serialized ); + $chain = array(); + + foreach ( $data as $itemString ) { + $item = explode( ':', $itemString ); + $langCode = $item[0]; + + if ( !isset( $item[1] ) ) { + $sourceLangCode = false; + } else { + $sourceLangCode = $item[1]; + } + + try { + $language = Language::factory( $langCode ); + if ( $sourceLangCode ) { + $sourceLanguage = Language::factory( $sourceLangCode ); + } else { + $sourceLanguage = null; + } + $chainItem = LanguageWithConversion::factory( $language, $sourceLanguage ); + } catch ( MWException $e ) { + wfProfileOut( __METHOD__ ); + return null; + } + + $chain[] = $chainItem; + } + + $languageFallbackChain = new LanguageFallbackChain( $chain ); + wfProfileOut( __METHOD__ ); + return $languageFallbackChain; + } + +} diff --git a/lib/tests/phpunit/LanguageFallbackChainSerializerTest.php b/lib/tests/phpunit/LanguageFallbackChainSerializerTest.php new file mode 100644 index 0000000..1b33798 --- /dev/null +++ b/lib/tests/phpunit/LanguageFallbackChainSerializerTest.php @@ -0,0 +1,95 @@ +<?php + +namespace Wikibase\Test; +use Wikibase\LanguageFallbackChain; +use Wikibase\LanguageFallbackChainFactory; +use Wikibase\LanguageFallbackChainSerializer; + +/** + * Tests for the Wikibase\LanguageFallbackChainSerializer class. + * + * @file + * @since 0.4 + * + * @ingroup WikibaseLib + * @ingroup Test + * + * @group Wikibase + * @group WikibaseUtils + * + * @licence GNU GPL v2+ + */ +class LanguageFallbackChainSerializerTest extends \MediaWikiTestCase { + + private function assertChainEquals( $expected, $languageFallbackChain ) { + $expectedChain = $expected->getFallbackChain(); + $chain = $languageFallbackChain->getFallbackChain(); + + $this->assertEquals( count( $expectedChain ), count( $chain ) ); + + foreach ( $expectedChain as $i => $expectedItem ) { + $this->assertEquals( $expectedItem->getLanguage()->getCode(), $chain[$i]->getLanguage()->getCode() ); + + if ( $expectedItem->getSourceLanguage() === null ) { + $this->assertNull( $chain[$i]->getSourceLanguage() ); + } else { + $this->assertEquals( + $expectedItem->getSourceLanguage()->getCode(), + $chain[$i]->getSourceLanguage()->getCode() + ); + } + } + } + + /** + * @group WikibaseLib + * @dataProvider provideValidChain + */ + public function testValidChain( $languageFallbackChain ) { + $serializer = new LanguageFallbackChainSerializer(); + $serialized = $serializer->serialize( $languageFallbackChain ); + $unserialized = $serializer->unserialize( $serialized ); + $this->assertChainEquals( $languageFallbackChain, $unserialized ); + } + + public function provideValidChain() { + $factory = new LanguageFallbackChainFactory(); + + // By design, the serialized form is not for persistant storage. + // We only test it to make sure it can unserialize data back to its original object. + return array( + array( $factory->newFromLanguage( \Language::factory( 'en' ) ) ), + array( $factory->newFromLanguage( \Language::factory( 'de' ) ) ), + array( $factory->newFromLanguage( \Language::factory( 'sr-ec' ) ) ), + array( $factory->newFromLanguage( \Language::factory( 'zh-cn' ), + LanguageFallbackChainFactory::FALLBACK_SELF | LanguageFallbackChainFactory::FALLBACK_VARIANTS + ) ), + array( $factory->newFromLanguage( \Language::factory( 'ii' ) ) ), + array( new LanguageFallbackChain( $factory->buildFromBabel( array( + 'N' => array( 'de-formal', 'en' ), + ) ) ) ), + array( new LanguageFallbackChain( $factory->buildFromBabel( array( + 'N' => array( 'zh-hk', 'en-gb' ), + '3' => array( 'zh', 'en' ), + ) ) ) ), + ); + } + + /** + * @group WikibaseLib + * @dataProvider provideInvalidChain + */ + public function testInvalidChain( $serialized ) { + $serializer = new LanguageFallbackChainSerializer(); + $unserialized = $serializer->unserialize( $serialized ); + $this->assertNull( $unserialized ); + } + + public function provideInvalidChain() { + return array( + array( '/' ), + array( 'zh-cn:sr-ec' ), + ); + } + +} -- To view, visit https://gerrit.wikimedia.org/r/72256 To unsubscribe, visit https://gerrit.wikimedia.org/r/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I65d69c8b12fa4e754b02e95697a754622f06bf24 Gerrit-PatchSet: 1 Gerrit-Project: mediawiki/extensions/Wikibase Gerrit-Branch: master Gerrit-Owner: Liangent <liang...@gmail.com> _______________________________________________ MediaWiki-commits mailing list MediaWiki-commits@lists.wikimedia.org https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits