jenkins-bot has submitted this change and it was merged. Change subject: Introduce ParserOutputDataUpdater class ......................................................................
Introduce ParserOutputDataUpdater class This is for updating ParserOutput properties and extension data (e.g "wikibase_item" for the connected item for a page) that Wikibase sets in the client. The code is split off from LangLinkHandler. Bug: T98981 Change-Id: I7bee7412bd3ae6a8469950770bc617e91793d656 --- M client/includes/LangLinkHandler.php A client/includes/ParserOutputDataUpdater.php M client/includes/WikibaseClient.php M client/tests/phpunit/includes/Hooks/ParserAfterParseHookHandlerTest.php M client/tests/phpunit/includes/LangLinkHandlerTest.php A client/tests/phpunit/includes/ParserOutputDataUpdaterTest.php M client/tests/phpunit/includes/WikibaseClientTest.php 7 files changed, 371 insertions(+), 45 deletions(-) Approvals: Daniel Kinzler: Looks good to me, approved jenkins-bot: Verified diff --git a/client/includes/LangLinkHandler.php b/client/includes/LangLinkHandler.php index a9dc393..67c1e92 100644 --- a/client/includes/LangLinkHandler.php +++ b/client/includes/LangLinkHandler.php @@ -8,6 +8,7 @@ use Title; use Wikibase\Client\Hooks\LanguageLinkBadgeDisplay; use Wikibase\Client\Hooks\OtherProjectsSidebarGeneratorFactory; +use Wikibase\Client\ParserOutputDataUpdater; use Wikibase\Client\Usage\ParserOutputUsageAccumulator; use Wikibase\DataModel\Entity\Item; use Wikibase\DataModel\Entity\ItemId; @@ -27,11 +28,6 @@ * @author Katie Filbert < aude.w...@gmail.com > */ class LangLinkHandler { - - /** - * @var OtherProjectsSidebarGeneratorFactory - */ - private $otherProjectsSidebarGeneratorFactory; /** * @var LanguageLinkBadgeDisplay @@ -54,6 +50,11 @@ private $entityLookup; /** + * @var ParserOutputDataUpdater + */ + private $parserOutputDataUpdater; + + /** * @var SiteStore */ private $siteStore; @@ -69,30 +70,30 @@ private $siteGroup; /** - * @param OtherProjectsSidebarGeneratorFactory $otherProjectsSidebarGeneratorFactory * @param LanguageLinkBadgeDisplay $badgeDisplay * @param NamespaceChecker $namespaceChecker determines which namespaces wikibase is enabled on * @param SiteLinkLookup $siteLinkLookup A site link lookup service * @param EntityLookup $entityLookup An entity lookup service + * @param ParserOutputDataUpdater $parserOutputDataUpdater * @param SiteStore $sites * @param string $siteId The global site ID for the local wiki * @param string $siteGroup The ID of the site group to use for showing language links. */ public function __construct( - OtherProjectsSidebarGeneratorFactory $otherProjectsSidebarGeneratorFactory, LanguageLinkBadgeDisplay $badgeDisplay, NamespaceChecker $namespaceChecker, SiteLinkLookup $siteLinkLookup, EntityLookup $entityLookup, + ParserOutputDataUpdater $parserOutputDataUpdater, SiteStore $siteStore, $siteId, $siteGroup ) { - $this->otherProjectsSidebarGeneratorFactory = $otherProjectsSidebarGeneratorFactory; $this->badgeDisplay = $badgeDisplay; $this->namespaceChecker = $namespaceChecker; $this->siteLinkLookup = $siteLinkLookup; $this->entityLookup = $entityLookup; + $this->parserOutputDataUpdater = $parserOutputDataUpdater; $this->siteStore = $siteStore; $this->siteId = $siteId; $this->siteGroup = $siteGroup; @@ -110,7 +111,10 @@ public function getEntityLinks( Title $title ) { $links = array(); - $itemId = $this->getItemIdForTitle( $title ); + $itemId = $this->siteLinkLookup->getItemIdForLink( + $this->siteId, + $title->getFullText() + ); if ( $itemId !== null ) { //NOTE: SiteLinks we could get from $this->siteLinkLookup do not contain badges, @@ -428,48 +432,21 @@ * * @param Title $title * @param ParserOutput $out + * + * @deprecated instead use ParserOutputDataUpdater::updateItemIdProperty */ public function updateItemIdProperty( Title $title, ParserOutput $out ) { - $itemId = $this->getItemIdForTitle( $title ); - - if ( $itemId ) { - $out->setProperty( 'wikibase_item', $itemId->getSerialization() ); - - $usageAccumulator = new ParserOutputUsageAccumulator( $out ); - $usageAccumulator->addSiteLinksUsage( $itemId ); - } else { - $out->unsetProperty( 'wikibase_item' ); - } + $this->parserOutputDataUpdater->updateItemIdProperty( $title, $out ); } /** * @param Title $title * @param ParserOutput $out + * + * @deprecated instead use ParserOutputDataUpdater::updateOtherProjectsLinksData */ public function updateOtherProjectsLinksData( Title $title, ParserOutput $out ) { - $itemId = $this->getItemIdForTitle( $title ); - - if ( $itemId ) { - $otherProjectsSidebarGenerator = $this->otherProjectsSidebarGeneratorFactory-> - getOtherProjectsSidebarGenerator(); - - $otherProjects = $otherProjectsSidebarGenerator->buildProjectLinkSidebar( $title ); - $out->setExtensionData( 'wikibase-otherprojects-sidebar', $otherProjects ); - } else { - $out->setExtensionData( 'wikibase-otherprojects-sidebar', array() ); - } - } - - /** - * @param Title $title - * - * @return ItemId|null - */ - private function getItemIdForTitle( Title $title ) { - return $this->siteLinkLookup->getItemIdForLink( - $this->siteId, - $title->getFullText() - ); + $this->parserOutputDataUpdater->updateOtherProjectsLinksData( $title, $out ); } } diff --git a/client/includes/ParserOutputDataUpdater.php b/client/includes/ParserOutputDataUpdater.php new file mode 100644 index 0000000..90fb5a6 --- /dev/null +++ b/client/includes/ParserOutputDataUpdater.php @@ -0,0 +1,109 @@ +<?php + +namespace Wikibase\Client; + +use InvalidArgumentException; +use ParserOutput; +use Title; +use Wikibase\Client\Hooks\OtherProjectsSidebarGeneratorFactory; +use Wikibase\Client\Usage\ParserOutputUsageAccumulator; +use Wikibase\DataModel\Entity\ItemId; +use Wikibase\DataModel\SiteLink; +use Wikibase\Lib\Store\SiteLinkLookup; + +/** + * Update Wikibase ParserOutput properties and extension data. + + * @since 0.5 + * + * @licence GNU GPL v2+ + * @author Daniel Kinzler + * @author Katie Filbert < aude.w...@gmail.com > + */ +class ParserOutputDataUpdater { + + /** + * @var OtherProjectsSidebarGeneratorFactory + */ + private $otherProjectsSidebarGeneratorFactory; + + /** + * @var SiteLinkLookup + */ + private $siteLinkLookup; + + /** + * @var string + */ + private $siteId; + + /** + * @param OtherProjectsSidebarGeneratorFactory $otherProjectsSidebarGeneratorFactory + * Use the factory here to defer initialization of things like Site objects. + * @param SiteLinkLookup $siteLinkLookup + * @param string $siteId The global site ID for the local wiki + */ + public function __construct( + OtherProjectsSidebarGeneratorFactory $otherProjectsSidebarGeneratorFactory, + SiteLinkLookup $siteLinkLookup, + $siteId + ) { + if ( !is_string( $siteId ) ) { + throw new InvalidArgumentException( '$siteId must be a string.' ); + } + + $this->otherProjectsSidebarGeneratorFactory = $otherProjectsSidebarGeneratorFactory; + $this->siteLinkLookup = $siteLinkLookup; + $this->siteId = $siteId; + } + + /** + * Add wikibase_item parser output property + * + * @param Title $title + * @param ParserOutput $out + */ + public function updateItemIdProperty( Title $title, ParserOutput $out ) { + $itemId = $this->getItemIdForTitle( $title ); + + if ( $itemId ) { + $out->setProperty( 'wikibase_item', $itemId->getSerialization() ); + + $usageAccumulator = new ParserOutputUsageAccumulator( $out ); + $usageAccumulator->addSiteLinksUsage( $itemId ); + } else { + $out->unsetProperty( 'wikibase_item' ); + } + } + + /** + * @param Title $title + * @param ParserOutput $out + */ + public function updateOtherProjectsLinksData( Title $title, ParserOutput $out ) { + $itemId = $this->getItemIdForTitle( $title ); + + if ( $itemId ) { + $otherProjectsSidebarGenerator = $this->otherProjectsSidebarGeneratorFactory-> + getOtherProjectsSidebarGenerator(); + + $otherProjects = $otherProjectsSidebarGenerator->buildProjectLinkSidebar( $title ); + $out->setExtensionData( 'wikibase-otherprojects-sidebar', $otherProjects ); + } else { + $out->setExtensionData( 'wikibase-otherprojects-sidebar', array() ); + } + } + + /** + * @param Title $title + * + * @return ItemId|null + */ + private function getItemIdForTitle( Title $title ) { + return $this->siteLinkLookup->getItemIdForLink( + $this->siteId, + $title->getFullText() + ); + } + +} diff --git a/client/includes/WikibaseClient.php b/client/includes/WikibaseClient.php index f2cf9a9..d0814b9 100644 --- a/client/includes/WikibaseClient.php +++ b/client/includes/WikibaseClient.php @@ -21,6 +21,7 @@ use Wikibase\Client\Hooks\LanguageLinkBadgeDisplay; use Wikibase\Client\Hooks\OtherProjectsSidebarGeneratorFactory; use Wikibase\Client\Hooks\ParserFunctionRegistrant; +use Wikibase\Client\ParserOutputDataUpdater; use Wikibase\Client\Store\TitleFactory; use Wikibase\ClientStore; use Wikibase\DataAccess\PropertyIdResolver; @@ -140,6 +141,11 @@ * @var LangLinkHandler|null */ private $langLinkHandler = null; + + /** + * @var ParserOutputDataUpdater|null + */ + private $parserOutputDataUpdater = null; /** * @var NamespaceChecker|null @@ -538,11 +544,11 @@ public function getLangLinkHandler() { if ( $this->langLinkHandler === null ) { $this->langLinkHandler = new LangLinkHandler( - $this->getOtherProjectsSidebarGeneratorFactory(), $this->getLanguageLinkBadgeDisplay(), $this->getNamespaceChecker(), $this->getStore()->getSiteLinkLookup(), $this->getStore()->getEntityLookup(), + $this->getParserOutputDataUpdater(), $this->getSiteStore(), $this->settings->getSetting( 'siteGlobalID' ), $this->getLangLinkSiteGroup() @@ -553,6 +559,21 @@ } /** + * @return ParserOutputDataUpdater + */ + public function getParserOutputDataUpdater() { + if ( $this->parserOutputDataUpdater === null ) { + $this->parserOutputDataUpdater = new ParserOutputDataUpdater( + $this->getOtherProjectsSidebarGeneratorFactory(), + $this->getStore()->getSiteLinkLookup(), + $this->settings->getSetting( 'siteGlobalID' ) + ); + } + + return $this->parserOutputDataUpdater; + } + + /** * @return LanguageLinkBadgeDisplay */ public function getLanguageLinkBadgeDisplay() { diff --git a/client/tests/phpunit/includes/Hooks/ParserAfterParseHookHandlerTest.php b/client/tests/phpunit/includes/Hooks/ParserAfterParseHookHandlerTest.php index 14ad1d6..77320a5 100644 --- a/client/tests/phpunit/includes/Hooks/ParserAfterParseHookHandlerTest.php +++ b/client/tests/phpunit/includes/Hooks/ParserAfterParseHookHandlerTest.php @@ -15,6 +15,7 @@ use Wikibase\Client\Hooks\LanguageLinkBadgeDisplay; use Wikibase\Client\Hooks\OtherProjectsSidebarGeneratorFactory; use Wikibase\Client\Hooks\ParserAfterParseHookHandler; +use Wikibase\Client\ParserOutputDataUpdater; use Wikibase\Client\Usage\EntityUsage; use Wikibase\Client\WikibaseClient; use Wikibase\DataModel\Entity\Item; @@ -170,12 +171,18 @@ Language::factory( 'en' ) ); - $langLinkHandler = new LangLinkHandler( + $parserOutputDataUpdater = new ParserOutputDataUpdater( $this->getOtherProjectsSidebarGeneratorFactory( $settings, $mockRepo ), + $mockRepo, + $settings->getSetting( 'siteGlobalID' ) + ); + + $langLinkHandler = new LangLinkHandler( $badgeDisplay, $namespaceChecker, $mockRepo, $mockRepo, + $parserOutputDataUpdater, $this->getSiteStore(), $settings->getSetting( 'siteGlobalID' ), $settings->getSetting( 'languageLinkSiteGroup' ) diff --git a/client/tests/phpunit/includes/LangLinkHandlerTest.php b/client/tests/phpunit/includes/LangLinkHandlerTest.php index ee5ec72..453efb0 100644 --- a/client/tests/phpunit/includes/LangLinkHandlerTest.php +++ b/client/tests/phpunit/includes/LangLinkHandlerTest.php @@ -8,6 +8,7 @@ use Wikibase\Client\Hooks\LanguageLinkBadgeDisplay; use Wikibase\Client\Hooks\OtherProjectsSidebarGenerator; use Wikibase\Client\Hooks\OtherProjectsSidebarGeneratorFactory; +use Wikibase\Client\ParserOutputDataUpdater; use Wikibase\Client\Usage\EntityUsage; use Wikibase\Client\Usage\ParserOutputUsageAccumulator; use Wikibase\DataModel\Entity\Item; @@ -85,12 +86,18 @@ $siteStore = MockSiteStore::newFromTestSites(); - return new LangLinkHandler( + $parserOutputDataUpdater = new ParserOutputDataUpdater( $this->getOtherProjectsSidebarGeneratorFactory( $otherProjects ), + $this->mockRepo, + 'srwiki' + ); + + return new LangLinkHandler( $this->getLanguageLinkBadgeDisplay(), new NamespaceChecker( array( NS_TALK ), array() ), $this->mockRepo, $this->mockRepo, + $parserOutputDataUpdater, $siteStore, 'srwiki', 'wikipedia' diff --git a/client/tests/phpunit/includes/ParserOutputDataUpdaterTest.php b/client/tests/phpunit/includes/ParserOutputDataUpdaterTest.php new file mode 100644 index 0000000..f59a5c0 --- /dev/null +++ b/client/tests/phpunit/includes/ParserOutputDataUpdaterTest.php @@ -0,0 +1,195 @@ +<?php + +namespace Wikibase\Client\Tests; + +use ParserOutput; +use Title; +use Wikibase\Client\Hooks\OtherProjectsSidebarGenerator; +use Wikibase\Client\Hooks\OtherProjectsSidebarGeneratorFactory; +use Wikibase\Client\ParserOutputDataUpdater; +use Wikibase\Client\Usage\EntityUsage; +use Wikibase\Client\Usage\ParserOutputUsageAccumulator; +use Wikibase\DataModel\Entity\Item; +use Wikibase\DataModel\Entity\ItemId; +use Wikibase\DataModel\SiteLink; +use Wikibase\Test\MockRepository; + +/** + * @covers Wikibase\Client\ParserOutputDataUpdater + * + * @group WikibaseClient + * @group Wikibase + * @group Database + * + * @licence GNU GPL v2+ + * @author Katie Filbert < aude.w...@gmail.com > + * @author Daniel Kinzler + */ +class ParserOutputDataUpdaterTest extends \MediaWikiTestCase { + + /** + * @var MockRepository|null + */ + private $mockRepo = null; + + private function getItems() { + $items = array(); + + $item = new Item( new ItemId( 'Q1' ) ); + $item->setLabel( 'en', 'Foo' ); + $links = $item->getSiteLinkList(); + $links->addNewSiteLink( 'dewiki', 'Foo de' ); + $links->addNewSiteLink( 'enwiki', 'Foo en', array( new ItemId( 'Q17' ) ) ); + $links->addNewSiteLink( 'srwiki', 'Foo sr' ); + $links->addNewSiteLink( 'dewiktionary', 'Foo de word' ); + $links->addNewSiteLink( 'enwiktionary', 'Foo en word' ); + $items[] = $item; + + $item = new Item( new ItemId( 'Q2' ) ); + $item->setLabel( 'en', 'Talk:Foo' ); + $links = $item->getSiteLinkList(); + $links->addNewSiteLink( 'dewiki', 'Talk:Foo de' ); + $links->addNewSiteLink( 'enwiki', 'Talk:Foo en' ); + $links->addNewSiteLink( 'srwiki', 'Talk:Foo sr' ); + $items[] = $item; + + return $items; + } + + /** + * @param string[] $otherProjects + * + * @return ParserOutputDataUpdater + */ + private function getParserOutputDataUpdater( array $otherProjects = array() ) { + $this->mockRepo = new MockRepository(); + + foreach ( $this->getItems() as $item ) { + $this->mockRepo->putEntity( $item ); + } + + return new ParserOutputDataUpdater( + $this->getOtherProjectsSidebarGeneratorFactory( $otherProjects ), + $this->mockRepo, + 'srwiki' + ); + } + + /** + * @param string[] $otherProjects + * + * @return OtherProjectsSidebarGeneratorFactory + */ + private function getOtherProjectsSidebarGeneratorFactory( array $otherProjects ) { + $otherProjectsSidebarGenerator = $this->getOtherProjectsSidebarGenerator( $otherProjects ); + + $otherProjectsSidebarGeneratorFactory = $this->getMockBuilder( + 'Wikibase\Client\Hooks\OtherProjectsSidebarGeneratorFactory' + ) + ->disableOriginalConstructor() + ->getMock(); + + $otherProjectsSidebarGeneratorFactory->expects( $this->any() ) + ->method( 'getOtherProjectsSidebarGenerator' ) + ->will( $this->returnValue( $otherProjectsSidebarGenerator ) ); + + return $otherProjectsSidebarGeneratorFactory; + } + + /** + * @param string[] $otherProjects + * + * @return OtherProjectsSidebarGenerator + */ + private function getOtherProjectsSidebarGenerator( array $otherProjects ) { + $otherProjectsSidebarGenerator = $this->getMockBuilder( 'Wikibase\Client\Hooks\OtherProjectsSidebarGenerator' ) + ->disableOriginalConstructor() + ->getMock(); + + $otherProjectsSidebarGenerator->expects( $this->any() ) + ->method( 'buildProjectLinkSidebar' ) + ->will( $this->returnValue( $otherProjects ) ); + + return $otherProjectsSidebarGenerator; + } + + public function testUpdateItemIdProperty() { + $parserOutput = new ParserOutput(); + + $titleText = 'Foo sr'; + $title = Title::newFromText( $titleText ); + + $parserOutputDataUpdater = $this->getParserOutputDataUpdater(); + + $parserOutputDataUpdater->updateItemIdProperty( $title, $parserOutput ); + $property = $parserOutput->getProperty( 'wikibase_item' ); + + $itemId = $this->mockRepo->getItemIdForLink( 'srwiki', $titleText ); + $this->assertEquals( $itemId->getSerialization(), $property ); + + $this->assertUsageTracking( $itemId, EntityUsage::SITELINK_USAGE, $parserOutput ); + } + + private function assertUsageTracking( ItemId $id, $aspect, ParserOutput $parserOutput ) { + $usageAcc = new ParserOutputUsageAccumulator( $parserOutput ); + $usage = $usageAcc->getUsages(); + $expected = new EntityUsage( $id, $aspect ); + + $this->assertContains( $expected, $usage, '', false, false ); + } + + public function testUpdateItemIdPropertyForUnconnectedPage() { + $parserOutput = new ParserOutput(); + + $titleText = 'Foo xx'; + $title = Title::newFromText( $titleText ); + + $parserOutputDataUpdater = $this->getParserOutputDataUpdater(); + + $parserOutputDataUpdater->updateItemIdProperty( $title, $parserOutput ); + $property = $parserOutput->getProperty( 'wikibase_item' ); + + $this->assertEquals( false, $property ); + } + + /** + * @dataProvider updateOtherProjectsLinksDataProvider + */ + public function testUpdateOtherProjectsLinksData( $expected, $otherProjects, $titleText ) { + $parserOutput = new ParserOutput(); + $title = Title::newFromText( $titleText ); + + $parserOutputDataUpdater = $this->getParserOutputDataUpdater( $otherProjects ); + + $parserOutputDataUpdater->updateOtherProjectsLinksData( $title, $parserOutput ); + $extensionData = $parserOutput->getExtensionData( 'wikibase-otherprojects-sidebar' ); + + $this->assertEquals( $expected, $extensionData ); + } + + public function updateOtherProjectsLinksDataProvider() { + return array( + 'other project exists, page has site link' => array( + array( 'project' => 'catswiki' ), + array( 'project' => 'catswiki' ), + 'Foo sr' + ), + 'other project exists, page has no site link' => array( + array(), + array( 'project' => 'catswiki' ), + 'Foo xx' + ), + 'no other projects, page has site link' => array( + array(), + array(), + 'Foo sr' + ), + 'no site link for this page' => array( + array(), + array(), + 'Foo xx' + ) + ); + } + +} diff --git a/client/tests/phpunit/includes/WikibaseClientTest.php b/client/tests/phpunit/includes/WikibaseClientTest.php index 3093a4f..a54f5a8 100644 --- a/client/tests/phpunit/includes/WikibaseClientTest.php +++ b/client/tests/phpunit/includes/WikibaseClientTest.php @@ -75,6 +75,16 @@ $this->assertInstanceOf( 'Site', $returnValue ); } + public function testGetLangLinkHandlerReturnType() { + $returnValue = $this->getWikibaseClient()->getLangLinkHandler(); + $this->assertInstanceOf( 'Wikibase\LangLinkHandler', $returnValue ); + } + + public function testGetParserOutputDataUpdaterType() { + $returnValue = $this->getWikibaseClient()->getParserOutputDataUpdater(); + $this->assertInstanceOf( 'Wikibase\Client\ParserOutputDataUpdater', $returnValue ); + } + /** * @dataProvider getLangLinkSiteGroupProvider */ -- To view, visit https://gerrit.wikimedia.org/r/210711 To unsubscribe, visit https://gerrit.wikimedia.org/r/settings Gerrit-MessageType: merged Gerrit-Change-Id: I7bee7412bd3ae6a8469950770bc617e91793d656 Gerrit-PatchSet: 10 Gerrit-Project: mediawiki/extensions/Wikibase Gerrit-Branch: master Gerrit-Owner: Aude <aude.w...@gmail.com> Gerrit-Reviewer: Aude <aude.w...@gmail.com> Gerrit-Reviewer: Daniel Kinzler <daniel.kinz...@wikimedia.de> Gerrit-Reviewer: Thiemo Mättig (WMDE) <thiemo.maet...@wikimedia.de> Gerrit-Reviewer: jenkins-bot <> _______________________________________________ MediaWiki-commits mailing list MediaWiki-commits@lists.wikimedia.org https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits