Hoo man has uploaded a new change for review.
https://gerrit.wikimedia.org/r/264597
Change subject: Override commons sidebar link with commons category
......................................................................
Override commons sidebar link with commons category
This does not implement any form of cache invalidation,
but that is ok for now.
The sidebar itself is cached within the ParserCache, so
this is only being executed on parse.
Bug: T94989
Change-Id: I96163f37bc86e78096e13a8db62adcd6d6c77fec
---
M WikimediaBadges.php
A includes/OtherProjectsSidebarHookHandler.php
A tests/phpunit/includes/OtherProjectsSidebarHookHandlerTest.php
3 files changed, 304 insertions(+), 2 deletions(-)
git pull
ssh://gerrit.wikimedia.org:29418/mediawiki/extensions/WikimediaBadges
refs/changes/97/264597/1
diff --git a/WikimediaBadges.php b/WikimediaBadges.php
index 3cea3e3..b1caa12 100644
--- a/WikimediaBadges.php
+++ b/WikimediaBadges.php
@@ -32,20 +32,23 @@
$GLOBALS['wgMessagesDirs']['WikimediaBadges'] = __DIR__ . '/i18n';
$GLOBALS['wgExtensionFunctions'][] = function() {
- global $wgExtensionCredits, $wgMessagesDirs, $wgHooks,
$wgResourceModules;
+ global $wgExtensionCredits, $wgMessagesDirs, $wgHooks,
$wgResourceModules, $wgWikimediaBadgesUseCommonsCategory;
$wgExtensionCredits['wikibase'][] = array(
'path' => __DIR__,
'name' => 'WikimediaBadges',
'version' => WIKIMEDIA_BADGES_VERSION,
- 'author' => '[https://www.mediawiki.org/wiki/User:Bene* Bene*]',
+ 'author' => array( '[https://www.mediawiki.org/wiki/User:Bene*
Bene*]', 'Marius Hoch' ),
'url' => 'https://github.com/wmde/WikimediaBadges',
'descriptionmsg' => 'wikimedia-badges-desc',
'license-name' => 'GPL-2.0+'
);
+ $wgWikimediaBadgesUseCommonsCategory = true;
+
// Hooks
$wgHooks['BeforePageDisplay'][] =
'WikimediaBadges\BeforePageDisplayHookHandler::onBeforePageDisplay';
+ $wgHooks['WikibaseClientOtherProjectsSidebar'][] =
'WikimediaBadges\OtherProjectsSidebarHookHandler::addToSidebar';
// Register phpunit tests
$wgHooks['UnitTestsList'][] = function( array &$files ) {
diff --git a/includes/OtherProjectsSidebarHookHandler.php
b/includes/OtherProjectsSidebarHookHandler.php
new file mode 100644
index 0000000..96b0662
--- /dev/null
+++ b/includes/OtherProjectsSidebarHookHandler.php
@@ -0,0 +1,157 @@
+<?php
+
+namespace WikimediaBadges;
+
+use Config;
+use RequestContext;
+use Wikibase\DataModel\Entity\Item;
+use Wikibase\DataModel\Entity\ItemId;
+use Wikibase\DataModel\Entity\PropertyId;
+use Wikibase\DataModel\Services\Lookup\EntityLookup;
+use Wikibase\DataModel\Services\Lookup\EntityLookupException;
+use Wikibase\DataModel\Snak\PropertyValueSnak;
+use Wikibase\Client\WikibaseClient;
+
+/**
+ * Handler for the WikibaseClientOtherProjectsSidebar hook that changes the
link
+ * to Wikimedia Commons with the one to the commons category.
+ *
+ * @since 0.1
+ *
+ * @license GNU GPL v2+
+ * @author Marius Hoch < [email protected] >
+ */
+class OtherProjectsSidebarHookHandler {
+
+ /**
+ * @var EntityLookup
+ */
+ private $entityLookup;
+
+ /**
+ * @var Config
+ */
+ private $config;
+
+ public function __construct( EntityLookup $entityLookup, Config $config
) {
+ $this->entityLookup = $entityLookup;
+ $this->config = $config;
+ }
+
+ /**
+ * @since 0.1
+ *
+ * @param ItemId $itemId
+ * @param array &$sidebar
+ *
+ * @return bool
+ */
+ public static function addToSidebar( ItemId $itemId, array &$sidebar ) {
+ $self = self::newFromGlobalState();
+
+ return $self->doAddToSidebar( $itemId, $sidebar );
+ }
+
+ /**
+ * @since 0.1
+ *
+ * @param ItemId $itemId
+ * @param array &$sidebar
+ *
+ * @return bool
+ */
+ public function doAddToSidebar( ItemId $itemId, array &$sidebar ) {
+ $enabled = $this->config->get(
'WikimediaBadgesUseCommonsCategory' );
+ if ( !$enabled ) {
+ return true;
+ }
+
+ $categoryName = $this->getCommonsCategoryName( $itemId );
+ if ( !$categoryName ) {
+ return true;
+ }
+ $href = 'https://commons.wikimedia.org/wiki/Category:' .
+ wfUrlencode( str_replace( ' ', '_',
$categoryName ) );
+
+ $this->modifyOrAddEntry( $sidebar, $href );
+
+ return true;
+ }
+
+ /**
+ * @param array &$sidebar
+ * @param string $href Link to the commons category
+ */
+ private function modifyOrAddEntry( array &$sidebar, $href ) {
+ foreach ( $sidebar as &$entry ) {
+ if ( $entry['msg'] === 'wikibase-otherprojects-commons'
) {
+ $entry['href'] = $href;
+
+ return;
+ }
+ }
+
+ $sidebar[] = array(
+ 'msg' => 'wikibase-otherprojects-commons',
+ 'class' => 'wb-otherproject-link
wb-otherproject-commons',
+ 'href' => $href,
+ 'hreflang' => 'en'
+ );
+ }
+
+ /**
+ * @param ItemId $itemId
+ *
+ * @return string|null
+ */
+ private function getCommonsCategoryName( ItemId $itemId ) {
+ $item = $this->getItem( $itemId );
+
+ if ( !$item ) {
+ return null;
+ }
+
+ $statements = $item->getStatements()->getByPropertyId( new
PropertyId( 'P373' ) );
+ $statements = $item->getStatements()->getByPropertyId( new
PropertyId( 'P9' ) );
+
+ $mainSnaks = $statements->getBestStatements()->getMainSnaks();
+
+ foreach ( $mainSnaks as $snak ) {
+ if ( $snak->getType() === 'value' ) {
+ /* @var $snak PropertyValueSnak */
+ return $snak->getDataValue()->getValue();
+ }
+ }
+
+ return null;
+ }
+
+ /**
+ * @param ItemId $itemId
+ *
+ * @return Item|null
+ */
+ private function getItem( ItemId $itemId ) {
+ try {
+ $item = $this->entityLookup->getEntity( $itemId );
+ } catch( EntityLookupException $ex ) {
+ wfLogWarning(
+ "Failed to load Item $itemId: " .
$ex->getMessage()
+ );
+
+ return null;
+ }
+
+ return $item;
+ }
+
+ private static function newFromGlobalState() {
+ $wikibaseClient = WikibaseClient::getDefaultInstance();
+
+ return new self(
+ $wikibaseClient->getStore()->getEntityLookup(),
+ RequestContext::getMain()->getConfig()
+ );
+ }
+
+}
diff --git a/tests/phpunit/includes/OtherProjectsSidebarHookHandlerTest.php
b/tests/phpunit/includes/OtherProjectsSidebarHookHandlerTest.php
new file mode 100644
index 0000000..8d55222
--- /dev/null
+++ b/tests/phpunit/includes/OtherProjectsSidebarHookHandlerTest.php
@@ -0,0 +1,142 @@
+<?php
+
+namespace WikimediaBadges\Tests;
+
+use DataValues\StringValue;
+use PHPUnit_Framework_TestCase;
+use Wikibase\DataModel\Entity\Item;
+use Wikibase\DataModel\Entity\ItemId;
+use Wikibase\DataModel\Entity\PropertyId;
+use Wikibase\DataModel\Snak\PropertySomeValueSnak;
+use Wikibase\DataModel\Snak\PropertyValueSnak;
+use Wikibase\DataModel\Services\Lookup\InMemoryEntityLookup;
+use Wikibase\DataModel\Services\Lookup\EntityLookupException;
+use WikimediaBadges\OtherProjectsSidebarHookHandler;
+
+/**
+ * @covers WikimediaBadges\OtherProjectsSidebarHookHandler
+ *
+ * @group WikimediaBadges
+ *
+ * @license GNU GPL v2+
+ * @author Marius Hoch < [email protected] >
+ */
+class OtherProjectsSidebarHookHandlerTest extends PHPUnit_Framework_TestCase {
+
+ /**
+ * @dataProvider doAddToSidebarProvider
+ */
+ public function testDoAddToSidebar( array $expected, array $sidebar,
ItemId $itemId, $suppressErrors = false ) {
+ $handler = new OtherProjectsSidebarHookHandler(
+ $this->getEntityLookup(),
+ $this->getConfig( true )
+ );
+
+ if ( $suppressErrors === 'suppress' ) {
+ \MediaWiki\suppressWarnings();
+ }
+ $this->assertTrue( $handler->doAddToSidebar( $itemId, $sidebar
) );
+ if ( $suppressErrors === 'suppress' ) {
+ \MediaWiki\restoreWarnings();
+ }
+
+ $this->assertSame( $expected, $sidebar );
+ }
+
+ public function doAddToSidebarProvider() {
+ $wikiquoteLink = array(
+ 'msg' => 'wikibase-otherprojects-wikiquote',
+ 'class' => 'wb-otherproject-link
wb-otherproject-wikiquote',
+ 'href' => 'https://en.wikiquote.org/wiki/Ams',
+ 'hreflang' => 'en'
+ );
+ $oldCommonsLink = array(
+ 'msg' => 'wikibase-otherprojects-commons',
+ 'class' => 'wb-otherproject-link
wb-otherproject-commons',
+ 'href' =>
'https://commons.wikimedia.org/wiki/Amsterdam',
+ 'hreflang' => 'en'
+ );
+ $newCommonsLink = $oldCommonsLink;
+ $newCommonsLink['href'] =
'https://commons.wikimedia.org/wiki/Category:Amsterdam';
+
+ return array(
+ 'Item without commons category statement' => array(
+ array(),
+ array(),
+ new ItemId( 'Q2013' )
+ ),
+ 'Sidebar without commons link gets amended' => array(
+ array( $wikiquoteLink, $newCommonsLink ),
+ array( $wikiquoteLink ),
+ new ItemId( 'Q123' )
+ ),
+ 'Empty sidebar gets amended' => array(
+ array( $newCommonsLink ),
+ array(),
+ new ItemId( 'Q123' )
+ ),
+ 'Existing commons link gets amended' => array(
+ array( $wikiquoteLink, $newCommonsLink ),
+ array( $wikiquoteLink, $oldCommonsLink ),
+ new ItemId( 'Q123' )
+ ),
+ 'No such item' => array(
+ array( $wikiquoteLink, $oldCommonsLink ),
+ array( $wikiquoteLink, $oldCommonsLink ),
+ new ItemId( 'Q404' )
+ ),
+ 'Item loading failed' => array(
+ array( $wikiquoteLink, $oldCommonsLink ),
+ array( $wikiquoteLink, $oldCommonsLink ),
+ new ItemId( 'Q503' ),
+ 'suppress'
+ ),
+ );
+ }
+
+ public function testDoAddToSidebar_disabled() {
+ $entityLookup = $this->getMock(
'Wikibase\DataModel\Services\Lookup\EntityLookup' );
+ $entityLookup->expects( $this->never() )
+ ->method( 'getEntity' );
+
+ $handler = new OtherProjectsSidebarHookHandler(
+ $entityLookup,
+ $this->getConfig( false )
+ );
+
+ $sidebar = array( 101010 => array( 'blah' ) );
+ $origSidebar = $sidebar;
+ $this->assertTrue( $handler->doAddToSidebar( new ItemId( 'Q42'
), $sidebar ) );
+ $this->assertSame( $origSidebar, $sidebar );
+ }
+
+ private function getEntityLookup() {
+ $entityLookup = new InMemoryEntityLookup();
+ $propertyId = new PropertyId( 'P373' );
+
+ $mainSnak = new PropertyValueSnak( $propertyId, new
StringValue( 'Amsterdam' ) );
+
+ $item = new Item( new ItemId( 'Q123' ) );
+ $item->getStatements()->addNewStatement( $mainSnak );
+ $item->getStatements()->addNewStatement( new
PropertySomeValueSnak( $propertyId ) );
+
+ $exception = new EntityLookupException( new ItemId( 'Q503' ) );
+
+ $entityLookup->addEntity( $item );
+ $entityLookup->addEntity( new Item( new ItemId( 'Q2013' ) ) );
+ $entityLookup->addException( $exception );
+
+ return $entityLookup;
+ }
+
+ private function getConfig( $enabled ) {
+ $config = $this->getMock( 'Config' );
+ $config->expects( $this->once() )
+ ->method( 'get' )
+ ->with( 'WikimediaBadgesUseCommonsCategory' )
+ ->will( $this->returnValue( $enabled ) );
+
+ return $config;
+ }
+
+}
--
To view, visit https://gerrit.wikimedia.org/r/264597
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: I96163f37bc86e78096e13a8db62adcd6d6c77fec
Gerrit-PatchSet: 1
Gerrit-Project: mediawiki/extensions/WikimediaBadges
Gerrit-Branch: master
Gerrit-Owner: Hoo man <[email protected]>
_______________________________________________
MediaWiki-commits mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits