WikidataBuilder has uploaded a new change for review.
https://gerrit.wikimedia.org/r/266478
Change subject: New Wikidata Build - 2016-01-26T10:00:01+0000
......................................................................
New Wikidata Build - 2016-01-26T10:00:01+0000
Change-Id: I2f1b16ff103dba876493aa72f16a2d33f3f80879
---
M composer.lock
M extensions/Wikibase/README.md
M extensions/Wikibase/client/i18n/tt-cyrl.json
M extensions/Wikibase/client/includes/Hooks/OtherProjectsSidebarGenerator.php
M extensions/Wikibase/client/includes/LangLinkHandler.php
M
extensions/Wikibase/client/tests/phpunit/includes/Hooks/OtherProjectsSidebarGeneratorTest.php
M extensions/Wikibase/docs/hooks.txt
A extensions/Wikibase/docs/public-apis.wiki
M extensions/Wikibase/lib/i18n/de.json
M extensions/Wikibase/lib/i18n/en.json
M extensions/Wikibase/lib/i18n/zh-hant.json
M extensions/Wikibase/lib/tests/phpunit/EntityRevisionLookupTest.php
M extensions/Wikibase/lib/tests/phpunit/changes/EntityChangeTest.php
M extensions/Wikibase/repo/Wikibase.hooks.php
M extensions/Wikibase/repo/i18n/el.json
M extensions/Wikibase/repo/i18n/gd.json
M extensions/Wikibase/repo/i18n/zh-hans.json
M extensions/Wikibase/repo/includes/EditEntity.php
M extensions/Wikibase/repo/includes/EditEntityFactory.php
M extensions/Wikibase/repo/includes/Hooks/EditFilterHookRunner.php
M
extensions/Wikibase/repo/tests/phpunit/includes/ParserOutput/PageImagesDataUpdaterTest.php
M
extensions/Wikibase/repo/tests/phpunit/includes/store/sql/EntityPerPageBuilderTest.php
M extensions/Wikibase/view/src/EntityTermsView.php
M extensions/Wikibase/view/src/EntityViewPlaceholderExpander.php
M extensions/Wikibase/view/tests/phpunit/EntityTermsViewTest.php
M extensions/WikimediaBadges/WikimediaBadges.php
M extensions/WikimediaBadges/composer.json
R extensions/WikimediaBadges/includes/BeforePageDisplayHookHandler.php
A extensions/WikimediaBadges/includes/OtherProjectsSidebarHookHandler.php
A
extensions/WikimediaBadges/tests/phpunit/includes/BeforePageDisplayHookHandlerTest.php
A
extensions/WikimediaBadges/tests/phpunit/includes/OtherProjectsSidebarHookHandlerTest.php
M vendor/composer/autoload_classmap.php
M vendor/composer/autoload_psr4.php
M vendor/composer/installed.json
34 files changed, 863 insertions(+), 111 deletions(-)
git pull ssh://gerrit.wikimedia.org:29418/mediawiki/extensions/Wikidata
refs/changes/78/266478/1
diff --git a/composer.lock b/composer.lock
index 44ae127..824c25e 100644
--- a/composer.lock
+++ b/composer.lock
@@ -1449,12 +1449,12 @@
"source": {
"type": "git",
"url":
"https://github.com/wikimedia/mediawiki-extensions-Wikibase.git",
- "reference": "b4111f6820ab6e1f6072d2b1bf4b3fddd3f775bd"
+ "reference": "53f56d3496a13a8ccb8c85ee4fb96001bac9b2c9"
},
"dist": {
"type": "zip",
- "url":
"https://api.github.com/repos/wikimedia/mediawiki-extensions-Wikibase/zipball/b4111f6820ab6e1f6072d2b1bf4b3fddd3f775bd",
- "reference": "b4111f6820ab6e1f6072d2b1bf4b3fddd3f775bd",
+ "url":
"https://api.github.com/repos/wikimedia/mediawiki-extensions-Wikibase/zipball/53f56d3496a13a8ccb8c85ee4fb96001bac9b2c9",
+ "reference": "53f56d3496a13a8ccb8c85ee4fb96001bac9b2c9",
"shasum": ""
},
"require": {
@@ -1525,7 +1525,7 @@
"wikibaserepo",
"wikidata"
],
- "time": "2016-01-21 03:04:33"
+ "time": "2016-01-26 09:44:07"
},
{
"name": "wikibase/wikimedia-badges",
@@ -1533,7 +1533,7 @@
"source": {
"type": "git",
"url":
"https://gerrit.wikimedia.org/r/mediawiki/extensions/WikimediaBadges",
- "reference": "22cfee80965d12162f97405d38ed8ec32f56e59c"
+ "reference": "885441b2e0f3cab5f8b5731cf22581309dee2735"
},
"require": {
"php": ">=5.3.0"
@@ -1543,9 +1543,9 @@
"files": [
"WikimediaBadges.php"
],
- "classmap": [
- "WikimediaBadges.hooks.php"
- ]
+ "psr-4": {
+ "WikimediaBadges\\": "includes/"
+ }
},
"license": [
"GNU GPL v2+"
@@ -1567,7 +1567,7 @@
"support": {
"irc": "irc://irc.freenode.net/wikidata"
},
- "time": "2016-01-18 13:08:32"
+ "time": "2016-01-21 13:15:32"
}
],
"packages-dev": [],
diff --git a/extensions/Wikibase/README.md b/extensions/Wikibase/README.md
index 6a9cf38..51147d3 100644
--- a/extensions/Wikibase/README.md
+++ b/extensions/Wikibase/README.md
@@ -26,8 +26,6 @@
The lib bundles common code that is used by both the client and the repo.
-Note that in each of the directories you will also find `README.md` notes for
each of the extensions.
-
## Install
This package contains three interrelated MediaWiki extensions:
diff --git a/extensions/Wikibase/client/i18n/tt-cyrl.json
b/extensions/Wikibase/client/i18n/tt-cyrl.json
index 1aa7fcd..7f54ec5 100644
--- a/extensions/Wikibase/client/i18n/tt-cyrl.json
+++ b/extensions/Wikibase/client/i18n/tt-cyrl.json
@@ -29,6 +29,10 @@
"wikibase-rc-wikibase-edit-title": "{{WBREPONAME}} үзгәртүе",
"wikibase-watchlist-show-changes-pref": "{{WBREPONAME}} булган
үзгәртүләрне күзәтү исемлегендә карау",
"wikibase-unconnectedpages-submit": "Битләрне күрсәтү",
+ "pageswithbadges": "Билгеле битләр",
+ "wikibase-pageswithbadges-badge": "Билге:",
+ "wikibase-pageswithbadges-submit": "Битләрне күрсәтү",
+ "wikibase-pageinfo-entity-id": "{{grammar:genitive|{{WBREPONAME}}}} ID
элементы",
"wikibase-pageinfo-entity-id-none": "Юк",
"wikibase-otherprojects": "Башка проектларда",
"wikibase-otherprojects-beta-message": "Башка проектлар өлгесе",
diff --git
a/extensions/Wikibase/client/includes/Hooks/OtherProjectsSidebarGenerator.php
b/extensions/Wikibase/client/includes/Hooks/OtherProjectsSidebarGenerator.php
index 85b8a62..285bbb5 100644
---
a/extensions/Wikibase/client/includes/Hooks/OtherProjectsSidebarGenerator.php
+++
b/extensions/Wikibase/client/includes/Hooks/OtherProjectsSidebarGenerator.php
@@ -2,10 +2,12 @@
namespace Wikibase\Client\Hooks;
+use Hooks;
use Site;
use SiteStore;
use Title;
use Wikibase\DataModel\SiteLink;
+use Wikibase\DataModel\Entity\ItemId;
use Wikibase\Lib\Store\SiteLinkLookup;
/**
@@ -64,16 +66,74 @@
* group and global ids.
*/
public function buildProjectLinkSidebar( Title $title ) {
- return $this->buildSidebarFromSiteLinks( $this->getSiteLinks(
$title ) );
+ $itemId = $this->getItemId( $title );
+ if ( !$itemId ) {
+ return array();
+ }
+
+ $sidebar = $this->buildPreliminarySidebarFromSiteLinks(
$this->getSiteLinks( $itemId ) );
+ $sidebar = $this->runHook( $itemId, $sidebar );
+
+ return $this->sortAndFlattenSidebar( $sidebar );
+ }
+
+ /**
+ * @param ItemId $itemId
+ * @param array $sidebar
+ *
+ * @return array
+ */
+ private function runHook( ItemId $itemId, array $sidebar ) {
+ $newSidebar = $sidebar;
+
+ Hooks::run( 'WikibaseClientOtherProjectsSidebar', array(
$itemId, &$newSidebar ) );
+
+ if ( $newSidebar === $sidebar ) {
+ return $sidebar;
+ }
+
+ if ( !is_array( $newSidebar ) || !$this->isValidSidebar(
$newSidebar ) ) {
+ wfLogWarning( 'Other projects sidebar data invalid
after hook run.' );
+ return $sidebar;
+ }
+
+ return $newSidebar;
+ }
+
+ /**
+ * @param array $sidebar
+ * @return bool
+ */
+ private function isValidSidebar( array $sidebar ) {
+ // Make sure all required array keys are set and are string.
+ foreach ( $sidebar as $siteGroup => $perSiteGroup ) {
+ if ( !is_string( $siteGroup ) || !is_array(
$perSiteGroup ) ) {
+ return false;
+ }
+
+ foreach ( $perSiteGroup as $siteId => $perSite ) {
+ if ( !is_string( $siteId )
+ || !isset( $perSite['msg'] )
+ || !isset( $perSite['class'] )
+ || !isset( $perSite['href'] )
+ || !is_string( $perSite['msg'] )
+ || !is_string( $perSite['class'] )
+ || !is_string( $perSite['href'] )
+ ) {
+ return false;
+ }
+ }
+ }
+
+ return true;
}
/**
* @param SiteLink[] $siteLinks
*
- * @return array[] Array of arrays of attributes describing sidebar
links, sorted by the site's
- * group and global ids.
+ * @return array[] Arrays of link attributes indexed by site group and
by global site id.
*/
- private function buildSidebarFromSiteLinks( array $siteLinks ) {
+ private function buildPreliminarySidebarFromSiteLinks( array $siteLinks
) {
$linksByGroup = array();
foreach ( $siteLinks as $siteLink ) {
@@ -91,7 +151,7 @@
}
}
- return $this->sortAndFlattenSidebar( $linksByGroup );
+ return $linksByGroup;
}
/**
@@ -117,22 +177,25 @@
}
/**
- * @param Title $title
+ * @param ItemId $itemId
*
* @return SiteLink[]
*/
- private function getSiteLinks( Title $title ) {
- $siteLink = new SiteLink( $this->localSiteId,
$title->getFullText() );
- $itemId = $this->siteLinkLookup->getItemIdForSiteLink(
$siteLink );
-
- if ( $itemId === null ) {
- return array();
- }
-
+ private function getSiteLinks( ItemId $itemId ) {
return $this->siteLinkLookup->getSiteLinksForItem( $itemId );
}
/**
+ * @param Title $title
+ *
+ * @return Item|null
+ */
+ private function getItemId( Title $title ) {
+ $siteLink = new SiteLink( $this->localSiteId,
$title->getFullText() );
+ return $this->siteLinkLookup->getItemIdForSiteLink( $siteLink );
+ }
+
+ /**
* @param SiteLink $siteLink
* @param Site $site
*
diff --git a/extensions/Wikibase/client/includes/LangLinkHandler.php
b/extensions/Wikibase/client/includes/LangLinkHandler.php
index ca4112d..335b0f1 100644
--- a/extensions/Wikibase/client/includes/LangLinkHandler.php
+++ b/extensions/Wikibase/client/includes/LangLinkHandler.php
@@ -115,7 +115,7 @@
$links = iterator_to_array(
$item->getSiteLinkList() );
$links = $this->indexLinksBySiteId( $links );
} else {
- wfWarn( __METHOD__ . ": Could not load item " .
$itemId->getSerialization()
+ wfLogWarning( __METHOD__ . ": Could not load
item " . $itemId->getSerialization()
. " for " . $title->getFullText() );
}
}
diff --git
a/extensions/Wikibase/client/tests/phpunit/includes/Hooks/OtherProjectsSidebarGeneratorTest.php
b/extensions/Wikibase/client/tests/phpunit/includes/Hooks/OtherProjectsSidebarGeneratorTest.php
index b121789..f92a9fb 100644
---
a/extensions/Wikibase/client/tests/phpunit/includes/Hooks/OtherProjectsSidebarGeneratorTest.php
+++
b/extensions/Wikibase/client/tests/phpunit/includes/Hooks/OtherProjectsSidebarGeneratorTest.php
@@ -85,6 +85,187 @@
}
/**
+ * @dataProvider projectLinkSidebarHookProvider
+ */
+ public function testBuildProjectLinkSidebar_hook(
+ /* callable */ $handler,
+ array $siteIdsToOutput,
+ array $result,
+ $suppressErrors = false
+ ) {
+ $this->setMwGlobals( 'wgHooks', array(
'WikibaseClientOtherProjectsSidebar' => array( $handler ) ) );
+
+ $otherProjectSidebarGenerator = new
OtherProjectsSidebarGenerator(
+ 'enwiki',
+ $this->getSiteLinkLookup(),
+ $this->getSiteStore(),
+ $siteIdsToOutput
+ );
+
+ if ( $suppressErrors ) {
+ \MediaWiki\suppressWarnings();
+ }
+ $this->assertEquals(
+ $result,
+ $otherProjectSidebarGenerator->buildProjectLinkSidebar(
Title::makeTitle( NS_MAIN, 'Nyan Cat' ) )
+ );
+
+ if ( $suppressErrors ) {
+ \MediaWiki\restoreWarnings();
+ }
+ }
+
+ public function projectLinkSidebarHookProvider() {
+ $wiktionaryLink = array(
+ 'msg' => 'wikibase-otherprojects-wiktionary',
+ 'class' => 'wb-otherproject-link
wb-otherproject-wiktionary',
+ 'href' => 'https://en.wiktionary.org/wiki/Nyan_Cat',
+ 'hreflang' => 'en'
+ );
+ $wikiquoteLink = array(
+ 'msg' => 'wikibase-otherprojects-wikiquote',
+ 'class' => 'wb-otherproject-link
wb-otherproject-wikiquote',
+ 'href' => 'https://en.wikiquote.org/wiki/Nyan_Cat',
+ 'hreflang' => 'en'
+ );
+ $wikipediaLink = array(
+ 'msg' => 'wikibase-otherprojects-wikipedia',
+ 'class' => 'wb-otherproject-link
wb-otherproject-wikipedia',
+ 'href' => 'https://en.wikipedia.org/wiki/Nyan_Cat',
+ 'hreflang' => 'en'
+ );
+ $changedWikipedaLink = array(
+ 'msg' => 'wikibase-otherprojects-wikipedia',
+ 'class' => 'wb-otherproject-link
wb-otherproject-wikipedia',
+ 'href' => 'https://en.wikipedia.org/wiki/Cat',
+ 'hreflang' => 'en'
+ );
+ $self = $this; // PHP 5.3 :(
+
+ return array(
+ 'Noop hook, gets the right data' => array(
+ function( ItemId $itemId, array &$sidebar ) use
( $wikipediaLink, $wikiquoteLink, $wiktionaryLink, $self ) {
+ $self->assertSame(
+ array(
+ 'wikiquote' => array(
'enwikiquote' => $wikiquoteLink ),
+ 'wikipedia' => array(
'enwiki' => $wikipediaLink ),
+ 'wiktionary' => array(
'enwiktionary' => $wiktionaryLink )
+ ),
+ $sidebar
+ );
+ $self->assertSame( 'Q123',
$itemId->getSerialization() );
+ },
+ array( 'enwiktionary', 'enwiki', 'enwikiquote'
),
+ array( $wikipediaLink, $wikiquoteLink,
$wiktionaryLink )
+ ),
+ 'Hook changes enwiki link' => array(
+ function( ItemId $itemId, array &$sidebar ) use
( $changedWikipedaLink ) {
+ $sidebar['wikipedia']['enwiki']['href']
= $changedWikipedaLink['href'];
+ },
+ array( 'enwiktionary', 'enwiki', 'enwikiquote'
),
+ array( $changedWikipedaLink, $wikiquoteLink,
$wiktionaryLink )
+ ),
+ 'Hook inserts enwiki link' => array(
+ function( ItemId $itemId, array &$sidebar ) use
( $changedWikipedaLink, $self ) {
+ $self->assertFalse(
+ isset( $sidebar['wikipedia'] ),
+ 'No Wikipedia link present yet'
+ );
+
+ $sidebar['wikipedia']['enwiki'] =
$changedWikipedaLink;
+ },
+ array( 'enwiktionary', 'enwikiquote' ),
+ array( $changedWikipedaLink, $wikiquoteLink,
$wiktionaryLink )
+ ),
+ 'Invalid hook #1, original data is being used' => array(
+ function( ItemId $itemId, array &$sidebar ) {
+ $sidebar = null;
+ },
+ array( 'enwiktionary', 'enwiki', 'enwikiquote'
),
+ array( $wikipediaLink, $wikiquoteLink,
$wiktionaryLink ),
+ true
+ ),
+ 'Invalid hook #2, original data is being used' => array(
+ function( ItemId $itemId, array &$sidebar ) {
+ $sidebar[0]['msg'] = array();
+ },
+ array( 'enwiktionary', 'enwiki', 'enwikiquote'
),
+ array( $wikipediaLink, $wikiquoteLink,
$wiktionaryLink ),
+ true
+ ),
+ 'Invalid hook #3, original data is being used' => array(
+ function( ItemId $itemId, array &$sidebar ) use
( $changedWikipedaLink ) {
+ $sidebar['wikipedia']['enwiki']['href']
= 1.2;
+ },
+ array( 'enwiktionary', 'enwiki', 'enwikiquote'
),
+ array( $wikipediaLink, $wikiquoteLink,
$wiktionaryLink ),
+ true
+ ),
+ 'Invalid hook #4, original data is being used' => array(
+ function( ItemId $itemId, array &$sidebar ) use
( $changedWikipedaLink ) {
+ $sidebar['wikipedia'][] =
$changedWikipedaLink;
+ },
+ array( 'enwiktionary', 'enwiki', 'enwikiquote'
),
+ array( $wikipediaLink, $wikiquoteLink,
$wiktionaryLink ),
+ true
+ ),
+ );
+ }
+
+ public function
testBuildProjectLinkSidebar_hookNotCalledIfPageNotConnected() {
+ $self = $this; // We all love PHP 5.3
+
+ $handler = function() use ( $self ) {
+ $self->assertTrue( false, "Should not get called." );
+ };
+
+ $this->setMwGlobals( 'wgHooks', array(
'WikibaseClientOtherProjectsSidebar' => array( $handler ) ) );
+
+ $lookup = $this->getMock( 'Wikibase\Lib\Store\SiteLinkLookup' );
+ $lookup->expects( $this->any() )
+ ->method( 'getItemIdForSiteLink' )
+ ->will( $this->returnValue( null ) );
+
+ $otherProjectSidebarGenerator = new
OtherProjectsSidebarGenerator(
+ 'enwiki',
+ $lookup,
+ $this->getSiteStore(),
+ array( 'enwiki' )
+ );
+
+ $this->assertSame(
+ array(),
+ $otherProjectSidebarGenerator->buildProjectLinkSidebar(
Title::makeTitle( NS_MAIN, 'Nyan Cat' ) )
+ );
+ }
+
+ public function
testBuildProjectLinkSidebar_hookCalledWithEmptySidebar() {
+ $self = $this; // We all love PHP 5.3
+ $called = false;
+
+ $handler = function( ItemId $itemId, $sidebar ) use ( $self,
&$called ) {
+ $self->assertSame( 'Q123', $itemId->getSerialization()
);
+ $self->assertSame( array(), $sidebar );
+ $called = true;
+ };
+
+ $this->setMwGlobals( 'wgHooks', array(
'WikibaseClientOtherProjectsSidebar' => array( $handler ) ) );
+
+ $otherProjectSidebarGenerator = new
OtherProjectsSidebarGenerator(
+ 'enwiki',
+ $this->getSiteLinkLookup(),
+ $this->getSiteStore(),
+ array( 'unknown-site' )
+ );
+
+ $this->assertSame(
+ array(),
+ $otherProjectSidebarGenerator->buildProjectLinkSidebar(
Title::makeTitle( NS_MAIN, 'Nyan Cat' ) )
+ );
+ $this->assertTrue( $called, 'Hook needs to be called' );
+ }
+
+ /**
* @return SiteStore
*/
private function getSiteStore() {
diff --git a/extensions/Wikibase/docs/hooks.txt
b/extensions/Wikibase/docs/hooks.txt
index 92e76fe..9b51cde 100644
--- a/extensions/Wikibase/docs/hooks.txt
+++ b/extensions/Wikibase/docs/hooks.txt
@@ -38,10 +38,18 @@
&$dataTypeDefinitions: the array of data type definitions, as defined by
WikibaseClient.datatypes.php.
Hook handlers may add additional definitions. See the datatypes.wiki file
for details.
-'WikibaseHandleChanges': Callend by ChangeHandler::handleChange() to allow
pre-processing
+'WikibaseHandleChanges': Called by ChangeHandler::handleChange() to allow
pre-processing
of changes.
$changes: A list of Change objects
-'WikibaseHandleChange': Callend by ChangeHandler::handleChange() to allow
alternative
+'WikibaseHandleChange': Called by ChangeHandler::handleChange() to allow
alternative
processing of changes.
$change: A Change object
+
+'WikibaseClientOtherProjectsSidebar' Called by OtherProjectsSidebarGenerator
to allow altering
+the other projects sidebar. Only called in case the page we're on is linked
with an item.
+$itemId: Id of the item the page is linked with.
+&$newSidedbar: Array containing the sidebar definition. The array consits of
arrays indexed by
+site groups containing arrays indexed by site id. These arrays represent the
link to the given
+site. They contain the keys "msg", "href" and "class" which contain the
respective attributes
+for the link that is going to be created.
diff --git a/extensions/Wikibase/docs/public-apis.wiki
b/extensions/Wikibase/docs/public-apis.wiki
new file mode 100644
index 0000000..222fcbe
--- /dev/null
+++ b/extensions/Wikibase/docs/public-apis.wiki
@@ -0,0 +1,15 @@
+The current status is that this extensions PHP interfaces may not be used by
+other extensions. None of the PHP APIs have any stability guarantees. An
+exception are extensions that fully cover these usages with unit tests which
+are run by the CI pre-merge and are integrated in the Wikidata build.
+
+TODO:
+
+Explain how this extension can be used by other Mediawiki exstension,
+which type of public APIs there are (HTTP API, Mediawiki hooks, composer
+components, PHP classes, etc) and what stability guarantees are available and
+how these are annotated on the individual parts (e.g. class level docs).
+
+See also:
+* https://phabricator.wikimedia.org/T103070 Find extensions using code directly
+ from Wikibase and provide mechanism with a stable interface
diff --git a/extensions/Wikibase/lib/i18n/de.json
b/extensions/Wikibase/lib/i18n/de.json
index 16857c1..d466563 100644
--- a/extensions/Wikibase/lib/i18n/de.json
+++ b/extensions/Wikibase/lib/i18n/de.json
@@ -83,13 +83,13 @@
"version-wikibase": "Wikibase-Erweiterungen",
"wikibase-time-precision-Gannum": "$1 Milliarden Jahre n. Chr.",
"wikibase-time-precision-Mannum": "$1 Millionen Jahre n. Chr.",
- "wikibase-time-precision-annum": "$1 Jahre n. Chr.",
+ "wikibase-time-precision-annum": "{{PLURAL:$1|Ein Jahr|$1 Jahre}} n.
Chr.",
"wikibase-time-precision-millennium": "$1. Jahrtausend",
"wikibase-time-precision-century": "$1. Jahrhundert",
"wikibase-time-precision-10annum": "$1 Jahrzehnte",
"wikibase-time-precision-BCE-Gannum": "$1 Milliarden Jahre v. Chr.",
"wikibase-time-precision-BCE-Mannum": "$1 Millionen Jahre v. Chr.",
- "wikibase-time-precision-BCE-annum": "$1 Jahre v. Chr.",
+ "wikibase-time-precision-BCE-annum": "{{PLURAL:$1|Ein Jahr|$1 Jahre}}
v. Chr.",
"wikibase-time-precision-BCE-millennium": "$1. Jahrtausend v. u. Z.",
"wikibase-time-precision-BCE-century": "$1. Jahrhundert v. u. Z.",
"wikibase-time-precision-BCE-10annum": "$1 Jahrzehnte v. u. Z.",
diff --git a/extensions/Wikibase/lib/i18n/en.json
b/extensions/Wikibase/lib/i18n/en.json
index 1eeff22..391b71b 100644
--- a/extensions/Wikibase/lib/i18n/en.json
+++ b/extensions/Wikibase/lib/i18n/en.json
@@ -75,13 +75,13 @@
"version-wikibase": "Wikibase",
"wikibase-time-precision-Gannum": "$1 billion years CE",
"wikibase-time-precision-Mannum": "$1 million years CE",
- "wikibase-time-precision-annum": "$1 years CE",
+ "wikibase-time-precision-annum": "{{PLURAL:$1|$1 year|$1 years}} CE",
"wikibase-time-precision-millennium": "$1. millennium",
"wikibase-time-precision-century": "$1. century",
"wikibase-time-precision-10annum": "$1s",
"wikibase-time-precision-BCE-Gannum": "$1 billion years BCE",
"wikibase-time-precision-BCE-Mannum": "$1 million years BCE",
- "wikibase-time-precision-BCE-annum": "$1 years BCE",
+ "wikibase-time-precision-BCE-annum": "{{PLURAL:$1|$1 year|$1 years}}
BCE",
"wikibase-time-precision-BCE-millennium": "$1. millennium BCE",
"wikibase-time-precision-BCE-century": "$1. century BCE",
"wikibase-time-precision-BCE-10annum": "$1s BCE",
diff --git a/extensions/Wikibase/lib/i18n/zh-hant.json
b/extensions/Wikibase/lib/i18n/zh-hant.json
index 7e85002..3bdb05f 100644
--- a/extensions/Wikibase/lib/i18n/zh-hant.json
+++ b/extensions/Wikibase/lib/i18n/zh-hant.json
@@ -55,7 +55,7 @@
"wikibase-sitelinks-link-columnheading": "已連結的頁面",
"wikibase-snakview-snaktypeselector-somevalue": "未知數值",
"wikibase-snakview-snaktypeselector-novalue": "無數值",
- "wikibase-tooltip-error-details": "詳細資訊",
+ "wikibase-tooltip-error-details": "詳細資料",
"wikibase-undeserializable-value": "此數值無效,無法顯示。",
"wikibase-validator-invalid": "無效的數值",
"wikibase-validator-missing-field": "缺少必填欄位 \"$1\"",
diff --git a/extensions/Wikibase/lib/tests/phpunit/EntityRevisionLookupTest.php
b/extensions/Wikibase/lib/tests/phpunit/EntityRevisionLookupTest.php
index 72f4e9b..11a23c0 100644
--- a/extensions/Wikibase/lib/tests/phpunit/EntityRevisionLookupTest.php
+++ b/extensions/Wikibase/lib/tests/phpunit/EntityRevisionLookupTest.php
@@ -2,7 +2,6 @@
namespace Wikibase\Test;
-use ContentHandler;
use Wikibase\DataModel\Entity\EntityId;
use Wikibase\DataModel\Entity\EntityRedirect;
use Wikibase\DataModel\Entity\Item;
diff --git a/extensions/Wikibase/lib/tests/phpunit/changes/EntityChangeTest.php
b/extensions/Wikibase/lib/tests/phpunit/changes/EntityChangeTest.php
index ff7b27e..142adc7 100644
--- a/extensions/Wikibase/lib/tests/phpunit/changes/EntityChangeTest.php
+++ b/extensions/Wikibase/lib/tests/phpunit/changes/EntityChangeTest.php
@@ -159,13 +159,13 @@
* @since 0.4
*/
public function testToString( EntityChange $entityChange ) {
- $s = "$entityChange"; // magically calls __toString()
+ $string = $entityChange->__toString();
- $id = $entityChange->getEntityId()->getSerialization();
+ $id = strtolower(
$entityChange->getEntityId()->getSerialization() );
$type = $entityChange->getType();
- $this->assertTrue( stripos( $s, $id ) !== false, "missing
entity ID $id" );
- $this->assertTrue( stripos( $s, $type ) !== false, "missing
type $type" );
+ $this->assertContains( "'object_id' => '$id'", $string,
"missing entity ID $id" );
+ $this->assertContains( "'type' => '$type'", $string, "missing
type $type" );
}
public function testGetComment() {
diff --git a/extensions/Wikibase/repo/Wikibase.hooks.php
b/extensions/Wikibase/repo/Wikibase.hooks.php
index eeb930d..0b4693c 100644
--- a/extensions/Wikibase/repo/Wikibase.hooks.php
+++ b/extensions/Wikibase/repo/Wikibase.hooks.php
@@ -350,18 +350,13 @@
'type' => 'api'
);
- if ( class_exists( 'Babel' ) ) {
-
$preferences['wikibase-entitytermsview-showEntitytermslistview'] = array(
- 'type' => 'toggle',
- 'label-message' =>
'wikibase-setting-entitytermsview-showEntitytermslistview',
- 'help-message' =>
'wikibase-setting-entitytermsview-showEntitytermslistview-help',
- 'section' => 'rendering/advancedrendering',
- );
- } elseif ( $user->getBoolOption(
'wikibase-entitytermsview-showEntitytermslistview' ) ) {
- // Clear setting after uninstalling Babel extension.
- unset(
$user->mOptions['wikibase-entitytermsview-showEntitytermslistview'] );
- $user->saveSettings();
- }
+
$preferences['wikibase-entitytermsview-showEntitytermslistview'] = array(
+ 'type' => 'toggle',
+ 'label-message' =>
'wikibase-setting-entitytermsview-showEntitytermslistview',
+ 'help-message' =>
'wikibase-setting-entitytermsview-showEntitytermslistview-help',
+ 'section' => 'rendering/advancedrendering',
+ 'default' => '1',
+ );
return true;
}
diff --git a/extensions/Wikibase/repo/i18n/el.json
b/extensions/Wikibase/repo/i18n/el.json
index 9d42ccb..8af3f34 100644
--- a/extensions/Wikibase/repo/i18n/el.json
+++ b/extensions/Wikibase/repo/i18n/el.json
@@ -8,7 +8,8 @@
"Indoril",
"Evropi",
"Macofe",
- "Glavkos"
+ "Glavkos",
+ "Badseed"
]
},
"wikibase-desc": "Αποθετήριο δομημένων δεδομένων",
@@ -153,11 +154,11 @@
"wikibase-setdescription-introfull": "Ορίζετε την περιγραφή στα $2 για
το [[$1]].",
"wikibase-setdescription-label": "Περιγραφή:",
"wikibase-setdescription-submit": "Προσθέστε μια περιγραφή",
- "wikibase-setaliases-introfull": "Ορίζετε τα αλλώνυμα στα $2 για το
[[$1]]. Πολλαπλά αλλώνυμα είναι διαχωρισμένα με τον χαρακτήρα πίπας
(<code>|</code>).",
+ "wikibase-setaliases-introfull": "Ορίζετε τα αλλώνυμα στα $2 για το
[[$1]]. Πολλαπλά αλλώνυμα διαχωρίζονται με τον χαρακτήρα καθέτου
(<code>|</code>).",
"wikibase-setaliases-label": "Αλλώνυμα:",
"wikibase-setaliases-submit": "Ορίστε αλλώνυμα",
"special-setlabeldescriptionaliases": "Ορίστε ετικέτα, περιγραφή και
αλλώνυμα",
- "wikibase-setlabeldescriptionaliases-introfull": "Ορίζετε ετικέτα,
περιγραφή και αλλώνυμα στα $2 για το [[$1]]. Πολλαπλά αλλώνυμα είναι
διαχωρισμένα με τον χαρακτήρα πίπας (<code>|</code>).",
+ "wikibase-setlabeldescriptionaliases-introfull": "Ορίζετε ετικέτα,
περιγραφή και αλλώνυμα στα $2 για το [[$1]]. Πολλαπλά αλλώνυμα διαχωρίζονται με
τον χαρακτήρα καθέτου (<code>|</code>).",
"wikibase-setlabeldescriptionaliases-label-label": "Ετικέτα:",
"wikibase-setlabeldescriptionaliases-description-label": "Περιγραφή:",
"wikibase-setlabeldescriptionaliases-aliases-label": "Αλλώνυμα:",
diff --git a/extensions/Wikibase/repo/i18n/gd.json
b/extensions/Wikibase/repo/i18n/gd.json
index 525f5a0..440d3d7 100644
--- a/extensions/Wikibase/repo/i18n/gd.json
+++ b/extensions/Wikibase/repo/i18n/gd.json
@@ -8,5 +8,10 @@
},
"wikibase-edit": "deasaich",
"wikibase-add": "cuir ris",
- "wikibase-sitelinks-special": "Làraichean eile"
+ "wikibase-label-empty": "Cha deach leubail a shònrachadh",
+ "wikibase-description-empty": "Cha deach tuairisgeul a shònrachadh",
+ "wikibase-sitelinks-special": "Làraichean eile",
+ "wikibase-aliases-empty": "Cha deach alias a shònrachadh",
+ "wikibase-statementview-rank-normal": "Inbhe àbhaisteach",
+ "wikibase-statementview-referencesheading-pendingcountersubject":
"{{PLURAL:$1|tùs|thùs|tùsan|tùs}}"
}
diff --git a/extensions/Wikibase/repo/i18n/zh-hans.json
b/extensions/Wikibase/repo/i18n/zh-hans.json
index d42fd01..6ee8392 100644
--- a/extensions/Wikibase/repo/i18n/zh-hans.json
+++ b/extensions/Wikibase/repo/i18n/zh-hans.json
@@ -525,6 +525,7 @@
"apihelp-wbsetlabel-example-1":
"为ID为“Q42”的页面设置字符串“Wikimedia”作为英语标签,并报告它为漂亮打印的json",
"apihelp-wbsetlabel-example-2": "为带有英语维基 => \"Earth\"的项设置英语标签为“Earth”。",
"apihelp-wbsetqualifier-description": "创建一个限定符或设置现有限定符的值。",
+ "apihelp-wbsetqualifier-param-value":
"限定符的新值。\n只应为PropertyValueSnak限定符提供",
"apihelp-wbsetqualifier-param-snakhash": "要修改的snak哈希。\n应只为存在的标识符提供",
"apihelp-wbsetqualifier-param-summary":
"编辑摘要。\n将按照自动生成的评论。自动评论与摘要的长度限制是260个字符。需要小心任何超出上述限定的东西将被裁剪掉。",
"apihelp-wbsetqualifier-param-bot":
"将此编辑标记为机器人编辑。此URL标记将只在用户属于“bot”用户组时受尊重。",
diff --git a/extensions/Wikibase/repo/includes/EditEntity.php
b/extensions/Wikibase/repo/includes/EditEntity.php
index a061c92..bbd8394 100644
--- a/extensions/Wikibase/repo/includes/EditEntity.php
+++ b/extensions/Wikibase/repo/includes/EditEntity.php
@@ -2,8 +2,8 @@
namespace Wikibase;
-use DerivativeContext;
use Html;
+use IContextSource;
use InvalidArgumentException;
use MWException;
use ReadOnlyError;
@@ -93,7 +93,7 @@
private $title = null;
/**
- * @var RequestContext|DerivativeContext
+ * @var IContextSource
*/
private $context;
@@ -170,7 +170,7 @@
* This will detect "late" edit conflicts, i.e. someone
squeezing in an edit
* just before the actual database transaction for saving beings.
* The empty string and 0 are both treated as `false`, disabling
conflict checks.
- * @param RequestContext|DerivativeContext|null $context the context to
use while processing
+ * @param IContextSource|null $context the context to use while
processing
* the edit; defaults to RequestContext::getMain().
*
* @throws InvalidArgumentException
@@ -184,7 +184,7 @@
User $user,
EditFilterHookRunner $editFilterHookRunner,
$baseRevId = false,
- $context = null
+ IContextSource $context = null
) {
$this->newEntity = $newEntity;
@@ -201,14 +201,6 @@
$this->errorType = 0;
$this->status = Status::newGood();
-
- if ( $context !== null
- && !( $context instanceof RequestContext )
- && !( $context instanceof DerivativeContext )
- ) {
- throw new InvalidArgumentException( '$context must be
an instance of RequestContext'
- . ' or DerivativeContext' );
- }
if ( $context === null ) {
$context = RequestContext::getMain();
diff --git a/extensions/Wikibase/repo/includes/EditEntityFactory.php
b/extensions/Wikibase/repo/includes/EditEntityFactory.php
index cd58259..cc4bc59 100644
--- a/extensions/Wikibase/repo/includes/EditEntityFactory.php
+++ b/extensions/Wikibase/repo/includes/EditEntityFactory.php
@@ -2,8 +2,7 @@
namespace Wikibase;
-use DerivativeContext;
-use RequestContext;
+use IContextSource;
use User;
use Wikibase\DataModel\Entity\Entity;
use Wikibase\Lib\Store\EntityRevisionLookup;
@@ -46,7 +45,7 @@
private $editFilterHookRunner;
/**
- * @var RequestContext|DerivativeContext|null
+ * @var IContextSource|null
*/
private $context;
@@ -56,7 +55,7 @@
* @param EntityStore $entityStore
* @param EntityPermissionChecker $permissionChecker
* @param EditFilterHookRunner $editFilterHookRunner
- * @param RequestContext|DerivativeContext|null $context
+ * @param IContextSource|null $context
*/
public function __construct(
EntityTitleLookup $titleLookup,
@@ -64,7 +63,7 @@
EntityStore $entityStore,
EntityPermissionChecker $permissionChecker,
EditFilterHookRunner $editFilterHookRunner,
- $context = null
+ IContextSource $context = null
) {
$this->titleLookup = $titleLookup;
$this->entityRevisionLookup = $entityLookup;
diff --git a/extensions/Wikibase/repo/includes/Hooks/EditFilterHookRunner.php
b/extensions/Wikibase/repo/includes/Hooks/EditFilterHookRunner.php
index 1de1a6d..8e199e5 100644
--- a/extensions/Wikibase/repo/includes/Hooks/EditFilterHookRunner.php
+++ b/extensions/Wikibase/repo/includes/Hooks/EditFilterHookRunner.php
@@ -38,7 +38,7 @@
private $entityContentFactory;
/**
- * @var IContextSource
+ * @var MutableContext
*/
private $context;
@@ -52,6 +52,12 @@
EntityContentFactory $entityContentFactory,
IContextSource $context
) {
+ if ( !( $context instanceof MutableContext ) ) {
+ wfLogWarning( '$context is not an instanceof
MutableContext.' );
+
+ $context = new DerivativeContext( $context );
+ }
+
$this->titleLookup = $titleLookup;
$this->entityContentFactory = $entityContentFactory;
$this->context = $context;
@@ -131,12 +137,6 @@
// namespace IDs for Property entities.
$namespace = $this->titleLookup->getNamespaceForType(
$entityType );
$title = Title::makeTitle( $namespace, 'New' . ucfirst(
$entityType ) );
- }
-
- if ( !( $context instanceof MutableContext ) ) {
- wfLogWarning( '$context is not an instanceof
MutableContext.' );
-
- $context = new DerivativeContext( $context );
}
$context->setTitle( $title );
diff --git
a/extensions/Wikibase/repo/tests/phpunit/includes/ParserOutput/PageImagesDataUpdaterTest.php
b/extensions/Wikibase/repo/tests/phpunit/includes/ParserOutput/PageImagesDataUpdaterTest.php
index 3849361..fcadef5 100644
---
a/extensions/Wikibase/repo/tests/phpunit/includes/ParserOutput/PageImagesDataUpdaterTest.php
+++
b/extensions/Wikibase/repo/tests/phpunit/includes/ParserOutput/PageImagesDataUpdaterTest.php
@@ -131,6 +131,8 @@
'Property not found' => array( $statements, array(
'P9999' ), null ),
'Not a property id' => array( $statements, array( 'Q1'
), null ),
'Invalid id' => array( $statements, array( 'invalid' ),
null ),
+
+ // Configuration
'Ignore misconfiguration' => array( $statements, array(
'P1', 'P2', 'P1' ), '1.jpg' ),
'Ignore keys' => array( $statements, array( 2 => 'P1',
1 => 'P2' ), '1.jpg' ),
@@ -144,8 +146,10 @@
'Increasing order' => array( $statements, array( 'P1',
'P2', 'P3' ), '1.jpg' ),
'Decreasing order' => array( $statements, array( 'P3',
'P2', 'P1' ), '3a.jpg' ),
+ // Ranks
'Skip deprecated' => array( $statements, array( 'P4' ),
'Four_2.jpg' ),
'Prefer preferred' => array( $statements, array( 'P5'
), '5c.jpg' ),
+ 'Rank does not overrule priority' => array(
$statements, array( 'P1', 'P5' ), '1.jpg' ),
);
}
diff --git
a/extensions/Wikibase/repo/tests/phpunit/includes/store/sql/EntityPerPageBuilderTest.php
b/extensions/Wikibase/repo/tests/phpunit/includes/store/sql/EntityPerPageBuilderTest.php
index 15ca610..5eba0fa 100644
---
a/extensions/Wikibase/repo/tests/phpunit/includes/store/sql/EntityPerPageBuilderTest.php
+++
b/extensions/Wikibase/repo/tests/phpunit/includes/store/sql/EntityPerPageBuilderTest.php
@@ -2,7 +2,6 @@
namespace Wikibase\Test;
-use ContentHandler;
use RuntimeException;
use User;
use Wikibase\DataModel\Entity\EntityRedirect;
diff --git a/extensions/Wikibase/view/src/EntityTermsView.php
b/extensions/Wikibase/view/src/EntityTermsView.php
index 65aa246..05b3648 100644
--- a/extensions/Wikibase/view/src/EntityTermsView.php
+++ b/extensions/Wikibase/view/src/EntityTermsView.php
@@ -188,10 +188,10 @@
}
return $this->templateFactory->render(
'wikibase-entitytermsforlanguagelistview',
- $this->msg(
'wikibase-entitytermsforlanguagelistview-language' ),
- $this->msg(
'wikibase-entitytermsforlanguagelistview-label' ),
- $this->msg(
'wikibase-entitytermsforlanguagelistview-description' ),
- $this->msg(
'wikibase-entitytermsforlanguagelistview-aliases' ),
+ $this->msg(
'wikibase-entitytermsforlanguagelistview-language' )->escaped(),
+ $this->msg(
'wikibase-entitytermsforlanguagelistview-label' )->escaped(),
+ $this->msg(
'wikibase-entitytermsforlanguagelistview-description' )->escaped(),
+ $this->msg(
'wikibase-entitytermsforlanguagelistview-aliases' )->escaped(),
$entityTermsForLanguageViewsHtml
);
}
diff --git a/extensions/Wikibase/view/src/EntityViewPlaceholderExpander.php
b/extensions/Wikibase/view/src/EntityViewPlaceholderExpander.php
index 1c49f1c..dc679ef 100644
--- a/extensions/Wikibase/view/src/EntityViewPlaceholderExpander.php
+++ b/extensions/Wikibase/view/src/EntityViewPlaceholderExpander.php
@@ -211,16 +211,7 @@
isset( $args[1] ) ? (int)$args[1] : 0
);
case
'entityViewPlaceholder-entitytermsview-entitytermsforlanguagelistview-class':
- return
- !$this->user->isAnon()
- && $this->user->getBoolOption(
-
'wikibase-entitytermsview-showEntitytermslistview'
- )
- || $this->user->isAnon()
- && isset(
$_COOKIE['wikibase-entitytermsview-showEntitytermslistview'] )
- &&
$_COOKIE['wikibase-entitytermsview-showEntitytermslistview'] === 'true'
- ? '' : 'wikibase-initially-collapsed';
-
+ return $this->isInitiallyCollapsed() ?
'wikibase-initially-collapsed' : '';
default:
wfWarn( "Unknown placeholder: $name" );
return '(((' . htmlspecialchars( $name ) .
')))';
@@ -228,6 +219,18 @@
}
/**
+ * @return bool If the terms list should be initially collapsed for the
current user.
+ */
+ private function isInitiallyCollapsed() {
+ if ( $this->user->isAnon() ) {
+ return isset(
$_COOKIE['wikibase-entitytermsview-showEntitytermslistview'] )
+ &&
$_COOKIE['wikibase-entitytermsview-showEntitytermslistview'] === 'false';
+ } else {
+ return !$this->user->getBoolOption(
'wikibase-entitytermsview-showEntitytermslistview' );
+ }
+ }
+
+ /**
* Generates HTML of the term box, to be injected into the entity page.
*
* @param EntityId $entityId
diff --git a/extensions/Wikibase/view/tests/phpunit/EntityTermsViewTest.php
b/extensions/Wikibase/view/tests/phpunit/EntityTermsViewTest.php
index 60537d8..6dbd9da 100644
--- a/extensions/Wikibase/view/tests/phpunit/EntityTermsViewTest.php
+++ b/extensions/Wikibase/view/tests/phpunit/EntityTermsViewTest.php
@@ -4,6 +4,7 @@
use Language;
use MediaWikiLangTestCase;
+use MessageCache;
use Wikibase\DataModel\Entity\ItemId;
use Wikibase\DataModel\Term\Fingerprint;
use Wikibase\View\EntityTermsView;
@@ -240,9 +241,21 @@
$this->assertNotContains( '&', $html, 'no double escaping'
);
}
+ public function testGetEntityTermsForLanguageListView_isEscaped() {
+ MessageCache::singleton()->enable();
+ $this->setMwGlobals( 'wgLang', Language::factory( 'en' ) );
+ $this->insertPage(
'MediaWiki:wikibase-entitytermsforlanguagelistview-language', "''RAW''" );
+
+ $view = $this->getEntityTermsView();
+ $html = $view->getEntityTermsForLanguageListView( new
Fingerprint(), array() );
+
+ $this->assertContains( '''RAW''', $html );
+ $this->assertNotContains( "'RAW'", $html );
+ }
+
public function testGetEntityTermsForLanguageListView_isMarkedAsEmpty()
{
$view = $this->getEntityTermsView( 0, 1 );
- $html = $view->getEntityTermsForLanguageListView( new
Fingerprint(), array( 'en' ), null );
+ $html = $view->getEntityTermsForLanguageListView( new
Fingerprint(), array( 'en' ) );
$this->assertContains( 'wb-empty', $html );
$this->assertContains( '(wikibase-label-empty)', $html );
diff --git a/extensions/WikimediaBadges/WikimediaBadges.php
b/extensions/WikimediaBadges/WikimediaBadges.php
index 77402aa..1767743 100644
--- a/extensions/WikimediaBadges/WikimediaBadges.php
+++ b/extensions/WikimediaBadges/WikimediaBadges.php
@@ -31,6 +31,16 @@
$GLOBALS['wgMessagesDirs']['WikimediaBadges'] = __DIR__ . '/i18n';
+/**
+ * The Property id of the commons category property.
+ * This is used to construct the link target for the other projects
+ * sidebar link to Wikimedia Commons.
+ *
+ * Set this to null in order to disable the other projects
+ * sidebar replacement.
+ */
+$GLOBALS['wgWikimediaBadgesCommonsCategoryProperty'] = 'P373';
+
$GLOBALS['wgExtensionFunctions'][] = function() {
global $wgExtensionCredits, $wgHooks, $wgResourceModules;
@@ -38,14 +48,20 @@
'path' => __FILE__,
'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+'
);
// Hooks
- $wgHooks['BeforePageDisplay'][] =
'WikimediaBadges\Hooks::onBeforePageDisplay';
+ $wgHooks['BeforePageDisplay'][] =
'WikimediaBadges\BeforePageDisplayHookHandler::onBeforePageDisplay';
+ $wgHooks['WikibaseClientOtherProjectsSidebar'][] =
'WikimediaBadges\OtherProjectsSidebarHookHandler::addToSidebar';
+
+ // Register phpunit tests
+ $wgHooks['UnitTestsList'][] = function( array &$files ) {
+ $files[] = __DIR__ . '/tests/phpunit';
+ };
// Resource Loader modules
$wgResourceModules = array_merge( $wgResourceModules, include __DIR__ .
'/resources/Resources.php' );
diff --git a/extensions/WikimediaBadges/composer.json
b/extensions/WikimediaBadges/composer.json
index bec0688..45eb3b3 100644
--- a/extensions/WikimediaBadges/composer.json
+++ b/extensions/WikimediaBadges/composer.json
@@ -27,8 +27,8 @@
"files": [
"WikimediaBadges.php"
],
- "classmap": [
- "WikimediaBadges.hooks.php"
- ]
+ "psr-4": {
+ "WikimediaBadges\\": "includes/"
+ }
}
}
diff --git a/extensions/WikimediaBadges/WikimediaBadges.hooks.php
b/extensions/WikimediaBadges/includes/BeforePageDisplayHookHandler.php
similarity index 83%
rename from extensions/WikimediaBadges/WikimediaBadges.hooks.php
rename to extensions/WikimediaBadges/includes/BeforePageDisplayHookHandler.php
index 33a1845..adda0f1 100644
--- a/extensions/WikimediaBadges/WikimediaBadges.hooks.php
+++ b/extensions/WikimediaBadges/includes/BeforePageDisplayHookHandler.php
@@ -6,14 +6,14 @@
use Skin;
/**
- * File defining the hook handlers for the WikimediaBadges extension.
+ * Handler for the BeforePageDisplay hook.
*
* @since 0.1
*
* @license GNU GPL v2+
* @author Bene* < [email protected] >
*/
-final class Hooks {
+class BeforePageDisplayHookHandler {
/**
* Handler for the BeforePageDisplay hook
diff --git
a/extensions/WikimediaBadges/includes/OtherProjectsSidebarHookHandler.php
b/extensions/WikimediaBadges/includes/OtherProjectsSidebarHookHandler.php
new file mode 100644
index 0000000..3156f4e
--- /dev/null
+++ b/extensions/WikimediaBadges/includes/OtherProjectsSidebarHookHandler.php
@@ -0,0 +1,213 @@
+<?php
+
+namespace WikimediaBadges;
+
+use DataValues\StringValue;
+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;
+use Wikimedia\Assert\Assert;
+use Wikimedia\Assert\ParameterTypeException;
+
+/**
+ * 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 string|null
+ */
+ private $commonsCategoryPropertySetting;
+
+ /**
+ * @return self
+ */
+ private static function newFromGlobalState() {
+ $wikibaseClient = WikibaseClient::getDefaultInstance();
+
+ return new self(
+ $wikibaseClient->getStore()->getEntityLookup(),
+ RequestContext::getMain()->getConfig()->get(
'WikimediaBadgesCommonsCategoryProperty' )
+ );
+ }
+
+ /**
+ * @param EntityLookup $entityLookup
+ * @param string|null $commonsCategoryPropertySetting
+ *
+ * @throws ParameterTypeException
+ */
+ public function __construct( EntityLookup $entityLookup,
$commonsCategoryPropertySetting ) {
+ Assert::parameterType( 'string|null',
$commonsCategoryPropertySetting, '$commonsCategoryPropertySetting' );
+
+ $this->entityLookup = $entityLookup;
+ $this->commonsCategoryPropertySetting =
$commonsCategoryPropertySetting;
+ }
+
+ /**
+ * @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 ) {
+ if ( $this->commonsCategoryPropertySetting !== null
+ ) {
+ $categoryName = $this->getCommonsCategoryName( $itemId
);
+ if ( $categoryName !== null ) {
+ $this->handleCategoryName( $categoryName,
$sidebar );
+ }
+ }
+
+ return true;
+ }
+
+ /**
+ * @param string $categoryName
+ * @param array &$sidebar
+ */
+ private function handleCategoryName( $categoryName, array &$sidebar ) {
+ $href = 'https://commons.wikimedia.org/wiki/Category:' .
+ wfUrlencode( str_replace( ' ', '_', $categoryName ) );
+
+ $this->modifyOrAddEntry( $href, $sidebar );
+ }
+
+ /**
+ * @param string $href Link to the commons category
+ * @param array &$sidebar
+ */
+ private function modifyOrAddEntry( $href, array &$sidebar ) {
+ if ( isset( $sidebar['commons']['commonswiki'] ) ) {
+ $sidebar['commons']['commonswiki']['href'] = $href;
+
+ return;
+ }
+
+ $sidebar['commons'] = array(
+ 'commonswiki' => 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;
+ }
+
+ return $this->getCommonsCategoryNameFromItem( $item );
+ }
+
+ /**
+ * @param Item $item
+ *
+ * @return string|null
+ */
+ private function getCommonsCategoryNameFromItem( Item $item ) {
+ $propertyId = new PropertyId(
$this->commonsCategoryPropertySetting );
+ $statements = $item->getStatements()->getByPropertyId(
$propertyId );
+
+ $mainSnaks = $statements->getBestStatements()->getMainSnaks();
+
+ return $this->getCommonsCategoryNameFromMainSnaks(
+ $mainSnaks,
+ $item->getId(),
+ $propertyId
+ );
+ }
+
+ /**
+ * @param Snak[] $mainSnaks
+ * @param ItemId $itemId
+ * @param PropertyId $propertyId
+ *
+ * @return string|null
+ */
+ private function getCommonsCategoryNameFromMainSnaks(
+ array $mainSnaks,
+ ItemId $itemId,
+ PropertyId $propertyId
+ ) {
+ foreach ( $mainSnaks as $snak ) {
+ if ( !( $snak instanceof PropertyValueSnak ) ) {
+ continue;
+ }
+
+ if ( !( $snak->getDataValue() instanceof StringValue )
) {
+ wfLogWarning(
+ $itemId->getSerialization() . ' has a
PropertyValueSnak with ' .
+ $propertyId->getSerialization()
. ' that has non-StringValue data.'
+ );
+
+ continue;
+ }
+
+ 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;
+ }
+
+}
diff --git
a/extensions/WikimediaBadges/tests/phpunit/includes/BeforePageDisplayHookHandlerTest.php
b/extensions/WikimediaBadges/tests/phpunit/includes/BeforePageDisplayHookHandlerTest.php
new file mode 100644
index 0000000..9a409b7
--- /dev/null
+++
b/extensions/WikimediaBadges/tests/phpunit/includes/BeforePageDisplayHookHandlerTest.php
@@ -0,0 +1,31 @@
+<?php
+
+namespace WikimediaBadges\Tests;
+
+use PHPUnit_Framework_TestCase;
+use SkinTemplate;
+use WikimediaBadges\BeforePageDisplayHookHandler;
+
+/**
+ * @covers WikimediaBadges\BeforePageDisplayHookHandler
+ *
+ * @group WikimediaBadges
+ *
+ * @license GNU GPL v2+
+ * @author Marius Hoch < [email protected] >
+ */
+class BeforePageDisplayHookHandlerTest extends PHPUnit_Framework_TestCase {
+
+ public function testOnBeforePageDisplay() {
+ $skin = new SkinTemplate();
+ $out = $this->getMockBuilder( 'OutputPage' )
+ ->disableOriginalConstructor()
+ ->getMock();
+ $out->expects( $this->once() )
+ ->method( 'addModuleStyles' )
+ ->with( 'ext.wikimediaBadges' );
+
+ $this->assertTrue(
BeforePageDisplayHookHandler::onBeforePageDisplay( $out, $skin ) );
+ }
+
+}
diff --git
a/extensions/WikimediaBadges/tests/phpunit/includes/OtherProjectsSidebarHookHandlerTest.php
b/extensions/WikimediaBadges/tests/phpunit/includes/OtherProjectsSidebarHookHandlerTest.php
new file mode 100644
index 0000000..3ed8a93
--- /dev/null
+++
b/extensions/WikimediaBadges/tests/phpunit/includes/OtherProjectsSidebarHookHandlerTest.php
@@ -0,0 +1,210 @@
+<?php
+
+namespace WikimediaBadges\Tests;
+
+use DataValues\StringValue;
+use DataValues\DecimalValue;
+use MediaWikiTestCase;
+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 MediaWikiTestCase {
+
+ /**
+ * @dataProvider doAddToSidebarProvider
+ */
+ public function testDoAddToSidebar( array $expected, array $sidebar,
ItemId $itemId, $suppressErrors = false ) {
+ $handler = new OtherProjectsSidebarHookHandler(
+ $this->getEntityLookup(),
+ 'P373'
+ );
+
+ 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(
+ 'wikiquote' => array( 'enwikiquote' =>
$wikiquoteLink ),
+ 'commons' => array( 'commonswiki' =>
$newCommonsLink )
+ ),
+ array(
+ 'wikiquote' => array( 'enwikiquote' =>
$wikiquoteLink )
+ ),
+ new ItemId( 'Q123' )
+ ),
+ 'Empty sidebar gets amended' => array(
+ array( 'commons' => array( 'commonswiki' =>
$newCommonsLink ) ),
+ array(),
+ new ItemId( 'Q123' )
+ ),
+ 'Existing commons link gets amended' => array(
+ array(
+ 'wikiquote' => array( 'enwikiquote' =>
$wikiquoteLink ),
+ 'commons' => array( 'commonswiki' =>
$newCommonsLink )
+ ),
+ array(
+ 'wikiquote' => array( 'enwikiquote' =>
$wikiquoteLink ),
+ 'commons' => array( 'commonswiki' =>
$oldCommonsLink )
+ ),
+ new ItemId( 'Q123' )
+ ),
+ 'No such item' => array(
+ array(
+ 'wikiquote' => array( 'enwikiquote' =>
$wikiquoteLink ),
+ 'commons' => array( 'commonswiki' =>
$oldCommonsLink )
+ ),
+ array(
+ 'wikiquote' => array( 'enwikiquote' =>
$wikiquoteLink ),
+ 'commons' => array( 'commonswiki' =>
$oldCommonsLink )
+ ),
+ new ItemId( 'Q404' )
+ ),
+ 'Item loading failed' => array(
+ array(
+ 'wikiquote' => array( 'enwikiquote' =>
$wikiquoteLink ),
+ 'commons' => array( 'commonswiki' =>
$oldCommonsLink )
+ ),
+ array(
+ 'wikiquote' => array( 'enwikiquote' =>
$wikiquoteLink ),
+ 'commons' => array( 'commonswiki' =>
$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,
+ null
+ );
+
+ $sidebar = array( 101010 => array( 'blah' ) );
+ $origSidebar = $sidebar;
+ $this->assertTrue( $handler->doAddToSidebar( new ItemId( 'Q42'
), $sidebar ) );
+ $this->assertSame( $origSidebar, $sidebar );
+ }
+
+ /**
+ * @dataProvider constructor_invalidSettingProvider
+ */
+ public function testConstructor_invalidSetting( $value ) {
+ $this->setExpectedException(
'Wikimedia\Assert\ParameterTypeException' );
+
+ new OtherProjectsSidebarHookHandler(
+ $this->getMock(
'Wikibase\DataModel\Services\Lookup\EntityLookup' ),
+ $value
+ );
+ }
+
+ public function constructor_invalidSettingProvider() {
+ return array(
+ array( array( ':(' ) ),
+ array( function() {} ),
+ array( false )
+ );
+ }
+
+ public function testDoAddToSidebar_invalidDataValue() {
+ $entityLookup = new InMemoryEntityLookup();
+ $propertyId = new PropertyId( 'P12' );
+ $mainSnak = new PropertyValueSnak( $propertyId, new
DecimalValue( 1 ) );
+
+ $item = new Item( new ItemId( 'Q123' ) );
+ $item->getStatements()->addNewStatement( $mainSnak );
+ $entityLookup->addEntity( $item );
+
+ $handler = new OtherProjectsSidebarHookHandler(
+ $entityLookup,
+ 'P12'
+ );
+
+ $sidebar = array( 101010 => array( 'blah' ) );
+ $origSidebar = $sidebar;
+
+ \MediaWiki\suppressWarnings();
+ $this->assertTrue( $handler->doAddToSidebar( new ItemId( 'Q123'
), $sidebar ) );
+ \MediaWiki\restoreWarnings();
+
+ $this->assertSame( $origSidebar, $sidebar );
+ }
+
+ public function testAddToSidebar() {
+ // Integration test: Make sure this doesn't fatal
+ $this->setMwGlobals(
'wgWikimediaBadgesCommonsCategoryProperty', null );
+ $sidebar = array();
+
+ $this->assertTrue(
+ OtherProjectsSidebarHookHandler::addToSidebar( new
ItemId( 'Q38434234' ), $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;
+ }
+
+}
diff --git a/vendor/composer/autoload_classmap.php
b/vendor/composer/autoload_classmap.php
index 9317b5b..ff6e27a 100644
--- a/vendor/composer/autoload_classmap.php
+++ b/vendor/composer/autoload_classmap.php
@@ -1497,7 +1497,8 @@
'Wikidata\\SettingsFileGenerator' => $baseDir .
'/src/SettingsFileGenerator.php',
'Wikidata\\WikidataHooks' => $baseDir . '/src/WikidataHooks.php',
'Wikidata\\WikidataSettingsBuilder' => $baseDir .
'/src/WikidataSettingsBuilder.php',
- 'WikimediaBadges\\Hooks' => $baseDir .
'/extensions/WikimediaBadges/WikimediaBadges.hooks.php',
+ 'WikimediaBadges\\BeforePageDisplayHookHandler' => $baseDir .
'/extensions/WikimediaBadges/includes/BeforePageDisplayHookHandler.php',
+ 'WikimediaBadges\\OtherProjectsSidebarHookHandler' => $baseDir .
'/extensions/WikimediaBadges/includes/OtherProjectsSidebarHookHandler.php',
'Wikimedia\\Purtle\\BNodeLabeler' => $baseDir .
'/extensions/Wikibase/purtle/src/BNodeLabeler.php',
'Wikimedia\\Purtle\\N3Quoter' => $baseDir .
'/extensions/Wikibase/purtle/src/N3Quoter.php',
'Wikimedia\\Purtle\\N3RdfWriterBase' => $baseDir .
'/extensions/Wikibase/purtle/src/N3RdfWriterBase.php',
diff --git a/vendor/composer/autoload_psr4.php
b/vendor/composer/autoload_psr4.php
index 0fb010a..0c00fcb 100644
--- a/vendor/composer/autoload_psr4.php
+++ b/vendor/composer/autoload_psr4.php
@@ -8,6 +8,7 @@
return array(
'Wikimedia\\Purtle\\Tests\\' => array($baseDir .
'/extensions/Wikibase/purtle/tests/phpunit'),
'Wikimedia\\Purtle\\' => array($baseDir .
'/extensions/Wikibase/purtle/src'),
+ 'WikimediaBadges\\' => array($baseDir .
'/extensions/WikimediaBadges/includes'),
'Wikidata\\' => array($baseDir . '/src'),
'Wikibase\\View\\Tests\\' => array($baseDir .
'/extensions/Wikibase/view/tests/phpunit'),
'Wikibase\\View\\' => array($baseDir . '/extensions/Wikibase/view/src'),
diff --git a/vendor/composer/installed.json b/vendor/composer/installed.json
index 574631b..4f71e47 100644
--- a/vendor/composer/installed.json
+++ b/vendor/composer/installed.json
@@ -1237,12 +1237,12 @@
"source": {
"type": "git",
"url":
"https://github.com/wikimedia/mediawiki-extensions-Wikibase.git",
- "reference": "b4111f6820ab6e1f6072d2b1bf4b3fddd3f775bd"
+ "reference": "53f56d3496a13a8ccb8c85ee4fb96001bac9b2c9"
},
"dist": {
"type": "zip",
- "url":
"https://api.github.com/repos/wikimedia/mediawiki-extensions-Wikibase/zipball/b4111f6820ab6e1f6072d2b1bf4b3fddd3f775bd",
- "reference": "b4111f6820ab6e1f6072d2b1bf4b3fddd3f775bd",
+ "url":
"https://api.github.com/repos/wikimedia/mediawiki-extensions-Wikibase/zipball/53f56d3496a13a8ccb8c85ee4fb96001bac9b2c9",
+ "reference": "53f56d3496a13a8ccb8c85ee4fb96001bac9b2c9",
"shasum": ""
},
"require": {
@@ -1274,7 +1274,7 @@
"jakub-onderka/php-parallel-lint": "0.9.2",
"mediawiki/mediawiki-codesniffer": "0.4.0|0.5.0"
},
- "time": "2016-01-21 03:04:33",
+ "time": "2016-01-26 09:44:07",
"type": "mediawiki-extension",
"installation-source": "dist",
"autoload": {
@@ -1323,21 +1323,21 @@
"source": {
"type": "git",
"url":
"https://gerrit.wikimedia.org/r/mediawiki/extensions/WikimediaBadges",
- "reference": "22cfee80965d12162f97405d38ed8ec32f56e59c"
+ "reference": "885441b2e0f3cab5f8b5731cf22581309dee2735"
},
"require": {
"php": ">=5.3.0"
},
- "time": "2016-01-18 13:08:32",
+ "time": "2016-01-21 13:15:32",
"type": "mediawiki-extension",
"installation-source": "source",
"autoload": {
"files": [
"WikimediaBadges.php"
],
- "classmap": [
- "WikimediaBadges.hooks.php"
- ]
+ "psr-4": {
+ "WikimediaBadges\\": "includes/"
+ }
},
"license": [
"GNU GPL v2+"
--
To view, visit https://gerrit.wikimedia.org/r/266478
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: I2f1b16ff103dba876493aa72f16a2d33f3f80879
Gerrit-PatchSet: 1
Gerrit-Project: mediawiki/extensions/Wikidata
Gerrit-Branch: master
Gerrit-Owner: WikidataBuilder <[email protected]>
_______________________________________________
MediaWiki-commits mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits