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

Reply via email to