Henning Snater has uploaded a new change for review.
https://gerrit.wikimedia.org/r/187423
Change subject: Added Special page to set label, description and aliases at once
......................................................................
Added Special page to set label, description and aliases at once
Change-Id: I9c23eca9f7303c3be04e3ac2c07f45779f1a0746
---
M repo/Wikibase.i18n.alias.php
M repo/Wikibase.php
M repo/i18n/en.json
M repo/i18n/qqq.json
M repo/includes/View/EntityTermsView.php
M repo/includes/specials/SpecialModifyEntity.php
A repo/includes/specials/SpecialSetLabelDescriptionAliases.php
A repo/tests/phpunit/includes/specials/SpecialSetLabelDescritionAliasesTest.php
8 files changed, 520 insertions(+), 2 deletions(-)
git pull ssh://gerrit.wikimedia.org:29418/mediawiki/extensions/Wikibase
refs/changes/23/187423/1
diff --git a/repo/Wikibase.i18n.alias.php b/repo/Wikibase.i18n.alias.php
index ba42ce4..f73679f 100644
--- a/repo/Wikibase.i18n.alias.php
+++ b/repo/Wikibase.i18n.alias.php
@@ -25,6 +25,7 @@
'SetLabel' => array( 'SetLabel' ),
'SetDescription' => array( 'SetDescription' ),
'SetAliases' => array( 'SetAliases' ),
+ 'SetLabelDescriptionAliases' => array( 'SetLabelDescriptionAliases' ),
'SetSiteLink' => array( 'SetSiteLink' ),
'MergeItems' => array( 'MergeItems', 'MergeItem' ),
'EntitiesWithoutLabel' => array( 'EntitiesWithoutLabel' ),
diff --git a/repo/Wikibase.php b/repo/Wikibase.php
index 7010a28..3b3052f 100644
--- a/repo/Wikibase.php
+++ b/repo/Wikibase.php
@@ -150,6 +150,7 @@
$wgSpecialPages['SetLabel']
= 'Wikibase\Repo\Specials\SpecialSetLabel';
$wgSpecialPages['SetDescription']
= 'Wikibase\Repo\Specials\SpecialSetDescription';
$wgSpecialPages['SetAliases']
= 'Wikibase\Repo\Specials\SpecialSetAliases';
+ $wgSpecialPages['SetLabelDescriptionAliases'] =
'Wikibase\Repo\Specials\SpecialSetLabelDescriptionAliases';
$wgSpecialPages['SetSiteLink']
= 'Wikibase\Repo\Specials\SpecialSetSiteLink';
$wgSpecialPages['EntitiesWithoutLabel'] =
array( 'Wikibase\Repo\Specials\SpecialEntitiesWithoutPageFactory',
'newSpecialEntitiesWithoutLabel' );
$wgSpecialPages['EntitiesWithoutDescription'] = array(
'Wikibase\Repo\Specials\SpecialEntitiesWithoutPageFactory',
'newSpecialEntitiesWithoutDescription' );
diff --git a/repo/i18n/en.json b/repo/i18n/en.json
index a5fe18f..04ccc62 100644
--- a/repo/i18n/en.json
+++ b/repo/i18n/en.json
@@ -184,6 +184,13 @@
"wikibase-setaliases-label": "Aliases:",
"wikibase-setaliases-submit": "Set aliases",
"wikibase-setaliases-warning-remove": "Do you really want to remove all
aliases of [[$1]]?",
+ "special-setlabeldescriptionaliases": "Set label, description and
aliases",
+ "wikibase-setlabeldescriptionaliases-introfull": "You are setting
label, description and aliases in $2 for [[$1]].",
+ "wikibase-setlabeldescriptionaliases-intro": "This form allows you to
set label, description and aliases of an entity. You need to provide the id of
the entity (e.g. Q23), a language code (e.g. \"en\") as well as label,
description and aliases to set to. Several aliases are separated by a pipe
(<code>|</code>) character.",
+ "wikibase-setlabeldescriptionaliases-label-label": "Label:",
+ "wikibase-setlabeldescriptionaliases-description-label": "Description:",
+ "wikibase-setlabeldescriptionaliases-aliases-label": "Aliases:",
+ "wikibase-setlabeldescriptionaliases-submit": "Set label, description
and aliases",
"special-setsitelink": "Set a site link",
"wikibase-setsitelink-introfull": "You are setting the site link of $2
for [[$1]].",
"wikibase-setsitelink-intro": "This form allows you to set the site
link of an item. You need to provide the id of the item (e.g. Q23), a site id
(e.g. \"enwiki\") and the site link to set to.",
diff --git a/repo/i18n/qqq.json b/repo/i18n/qqq.json
index 930f9f5..6434671 100644
--- a/repo/i18n/qqq.json
+++ b/repo/i18n/qqq.json
@@ -210,6 +210,13 @@
"wikibase-setaliases-label": "Label for the input field to type the
aliases to set the entity to.\n{{Identical|Alias}}",
"wikibase-setaliases-submit": "Label for the button that activates the
action.",
"wikibase-setaliases-warning-remove": "A warning message to ask the
user if he wants to remove all aliases.\n\nParameters:\n* $1 - the id that
links to the entity",
+ "special-setlabel": "{{doc-special|SetLabelAliasesDescription}}\nThe
special page allows the user to set an entity's label, description and aliases
in a particular language.",
+ "wikibase-setlabel-introfull": "Intro text when label, description and
aliases are to be set. Parameters:\n* $1 - the ID that links to the entity\n*
$2 - the translated language name (possibly autonym) label, description and
aliases are to be set in.",
+ "wikibase-setlabel-intro": "A short text at the top of the page that
allows users to set an entity's label, description and aliases, explaining the
form.",
+ "wikibase-setlabel-label": "Label for the input field to type the label
to set the entity to.\n{{Identical|Label}}",
+ "wikibase-setlabel-description": "Label for the input field to type the
description to set the entity to.\n{{Identical|Description}}",
+ "wikibase-setlabel-aliases": "Label for the input field to type the
aliases to set the entity to.\n{{Identical|Alias}}",
+ "wikibase-setlabel-submit": "Label for the button that activates the
action.",
"special-setsitelink": "{{doc-special|SetSiteLink}}\nThe special page
allows the user to set a site link for an item.",
"wikibase-setsitelink-introfull": "Intro text when a site link is to be
set. Parameters:\n* $1 - the ID that links to the item\n* $2 - the site id the
site link is to be set to",
"wikibase-setsitelink-intro": "A short text at the top of the page that
allows users to set the site link of an item, explaining the form.",
diff --git a/repo/includes/View/EntityTermsView.php
b/repo/includes/View/EntityTermsView.php
index 53a5224..0e0be9f 100644
--- a/repo/includes/View/EntityTermsView.php
+++ b/repo/includes/View/EntityTermsView.php
@@ -85,7 +85,7 @@
$textInjector->newMarker(
'entityViewPlaceholder-entitytermsview-entitytermsforlanguagelistview-class'
),
- $this->getHtmlForEditSection( 'SetLabel', $entityId,
$editable )
+ $this->getHtmlForEditSection(
'SetLabelDescriptionAliases', $entityId, $editable )
);
}
diff --git a/repo/includes/specials/SpecialModifyEntity.php
b/repo/includes/specials/SpecialModifyEntity.php
index abe9293..54e76be 100644
--- a/repo/includes/specials/SpecialModifyEntity.php
+++ b/repo/includes/specials/SpecialModifyEntity.php
@@ -151,7 +151,7 @@
*
* @param Entity $entity
*/
- private function setForm( Entity $entity = null ) {
+ protected function setForm( Entity $entity = null ) {
$this->addCopyrightText();
$this->getOutput()->addModuleStyles( array( 'wikibase.special'
) );
diff --git a/repo/includes/specials/SpecialSetLabelDescriptionAliases.php
b/repo/includes/specials/SpecialSetLabelDescriptionAliases.php
new file mode 100644
index 0000000..1bc5be9
--- /dev/null
+++ b/repo/includes/specials/SpecialSetLabelDescriptionAliases.php
@@ -0,0 +1,367 @@
+<?php
+
+namespace Wikibase\Repo\Specials;
+
+use Html;
+use InvalidArgumentException;
+use Language;
+use PermissionsError;
+use OutOfBoundsException;
+use Wikibase\ChangeOp\ChangeOpException;
+use Wikibase\ChangeOp\FingerprintChangeOpFactory;
+use Wikibase\DataModel\Entity\Entity;
+use Wikibase\DataModel\Entity\Item;
+use Wikibase\DataModel\Entity\Property;
+use Wikibase\DataModel\Term\Fingerprint;
+use Wikibase\DataModel\Term\FingerprintProvider;
+use Wikibase\Repo\WikibaseRepo;
+use Wikibase\Summary;
+use Wikibase\Utils;
+
+/**
+ * Special page for setting label, description and aliases of a Wikibase
Entity that features a
+ * Fingerprint.
+ *
+ * @since 0.5
+ * @licence GNU GPL v2+
+ * @author H. Snater < [email protected] >
+ * @author Bene* < [email protected] >
+ */
+class SpecialSetLabelDescriptionAliases extends SpecialModifyEntity {
+
+ /**
+ * @var FingerprintChangeOpFactory
+ */
+ protected $fingerprintChangeOpFactory;
+
+ /**
+ * The language label, description and aliases are set in.
+ * @var string
+ */
+ private $languageCode;
+
+ /**
+ * @var Fingerprint
+ */
+ private $labelDescriptionAliases;
+
+ /**
+ * @since 0.5
+ */
+ public function __construct() {
+ parent::__construct( 'SetLabelDescriptionAliases', 'edit' );
+
+ $changeOpFactoryProvider =
WikibaseRepo::getDefaultInstance()->getChangeOpFactoryProvider();
+ $this->fingerprintChangeOpFactory
+ =
$changeOpFactoryProvider->getFingerprintChangeOpFactory();
+ }
+
+ /**
+ * @see SpecialModifyEntity::validateInput
+ * @since 0.5
+ *
+ * @return bool
+ */
+ protected function validateInput() {
+ $request = $this->getRequest();
+
+ if ( !parent::validateInput() || !$this->isValidLanguageCode(
$this->languageCode ) ) {
+ return false;
+ }
+
+ try{
+ $this->checkTermChangePermissions(
$this->entityRevision->getEntity() );
+ } catch( PermissionsError $e ) {
+ $this->showErrorHTML( $this->msg( 'permissionserrors' )
. ': ' . $e->permission );
+ return false;
+ }
+
+ if( $this->entityRevision ) {
+ $entity = $this->entityRevision->getEntity();
+ return $entity instanceof FingerprintProvider;
+ } else {
+ return false;
+ }
+ }
+
+ /**
+ * @param Entity $entity
+ *
+ * @throws PermissionsError
+ * @throws InvalidArgumentException
+ */
+ private function checkTermChangePermissions( Entity $entity ) {
+ if( $entity instanceof Item ) {
+ $type = 'item';
+ } else if ( $entity instanceof Property ) {
+ $type = 'property';
+ } else {
+ throw new InvalidArgumentException( 'Unexpected Entity
type when checking special page term change permissions' );
+ }
+ $restriction = $type . '-term';
+ if ( !$this->getUser()->isAllowed( $restriction ) ) {
+ throw new PermissionsError( $restriction );
+ }
+ }
+
+ /**
+ * @see SpecialModifyEntity::getFormElements()
+ * @since 0.5
+ *
+ * @param Entity $entity
+ * @return string
+ */
+ protected function getFormElements( Entity $entity = null ) {
+ if ( $this->languageCode === null ) {
+ $this->languageCode = $this->getLanguage()->getCode();
+ }
+ if ( $this->labelDescriptionAliases === null ) {
+ $this->labelDescriptionAliases = $entity instanceof
FingerprintProvider
+ ? $entity->getFingerprint()
+ : new Fingerprint();
+ }
+
+ $labelText = $this->getRequest()->getVal( 'label' );
+ if( !$labelText ) {
+ try {
+ $labelText = $this->labelDescriptionAliases
+ ->getLabel( $this->languageCode )
+ ->getText();
+ } catch( OutOfBoundsException $e ) {
+ $labelText = '';
+ }
+ }
+
+ $labelInput = $this->getTextInput( 'label', $labelText );
+
+ $descriptionText = $this->getRequest()->getVal( 'description' );
+ if( !$descriptionText ) {
+ try {
+ $descriptionText =
$this->labelDescriptionAliases
+ ->getDescription( $this->languageCode )
+ ->getText();
+ } catch( OutOfBoundsException $e ) {
+ $descriptionText = '';
+ }
+ }
+
+ $descriptionInput = $this->getTextInput( 'description',
$descriptionText );
+
+ $aliasesText = $this->getRequest()->getVal( 'aliases' );
+ if( !$aliasesText ) {
+ try {
+ $aliasGroup =
$this->labelDescriptionAliases->getAliasGroup( $this->languageCode );
+ $aliasesText = implode( '|',
$aliasGroup->getAliases() );
+ } catch( OutOfBoundsException $e ) {
+ $aliasesText = '';
+ }
+ }
+
+ $aliasesInput = $this->getTextInput( 'aliases', $aliasesText );
+
+ $languageName = Language::fetchLanguageName(
+ $this->languageCode, $this->getLanguage()->getCode()
+ );
+
+ if ( $entity !== null && $this->languageCode !== null &&
$languageName !== '' ) {
+ return Html::rawElement(
+ 'p',
+ array(),
+ $this->msg(
+
'wikibase-setlabeldescriptionaliases-introfull',
+ $this->getEntityTitle( $entity->getId()
)->getPrefixedText(),
+ $languageName
+ )->parse()
+ )
+ . Html::input( 'language', $this->languageCode,
'hidden' )
+ . Html::input( 'id',
$entity->getId()->getSerialization(), 'hidden' )
+ . $labelInput . $descriptionInput . $aliasesInput;
+ } else {
+ return Html::rawElement(
+ 'p',
+ array(),
+ $this->msg(
'wikibase-setlabeldescriptionaliases-intro' )->parse()
+ )
+ . parent::getFormElements( $entity )
+ . Html::element(
+ 'label',
+ array(
+ 'for' =>
'wikibase-setlabeldescriptionaliases-language',
+ 'class' => 'wb-label'
+ ),
+ $this->msg( 'wikibase-modifyterm-language'
)->text()
+ )
+ . Html::input(
+ 'language',
+ $this->languageCode,
+ 'text',
+ array(
+ 'class' => 'wb-input',
+ 'id' =>
'wikibase-setlabeldescriptionaliases-language'
+ )
+ )
+ . $this->getLabel( 'label' ) . $labelInput
+ . $this->getLabel( 'description' ) . $descriptionInput
+ . $this->getLabel( 'aliases' ) . $aliasesInput;
+ }
+ }
+
+ /**
+ * Returns HTML text input element for a specific term (label,
description, aliases).
+ *
+ * @param string $name
+ * @param string $value Text to fill the input element with
+ * @return string
+ */
+ private function getTextInput( $name, $value ) {
+ return Html::input(
+ $name,
+ $value,
+ 'text',
+ array(
+ 'class' => 'wb-input',
+ 'id' => 'wikibase-setlabeldescriptionaliases-'
. $name,
+ 'size' => 50
+ )
+ )
+ . Html::element( 'br' );
+ }
+
+ /**
+ * Returns a HTML label element for a specific term (label,
description, aliases).
+ *
+ * @param string $name
+ * @return string
+ */
+ private function getLabel( $name ) {
+ return Html::element( 'br' )
+ . Html::element(
+ $name,
+ array(
+ 'for' => 'wikibase-setlabeldescriptionaliases-'
. $name,
+ 'class' => 'wb-label'
+ ),
+ // Messages:
+ // wikibase-setlabeldescriptionaliases-label-label
+ //
wikibase-setlabeldescriptionaliases-description-label
+ // wikibase-setlabeldescriptionaliases-aliases-label
+ $this->msg( 'wikibase-setlabeldescriptionaliases-' .
$name . '-label' )->text()
+ );
+ }
+
+ /**
+ * @see SpecialModifyEntity::prepareArguments()
+ * @since 0.5
+ *
+ * @param string $subPage
+ */
+ protected function prepareArguments( $subPage ) {
+ parent::prepareArguments( $subPage );
+
+ $request = $this->getRequest();
+ $parts = ( $subPage === '' ) ? array() : explode( '/',
$subPage, 2 );
+
+ $this->languageCode = $request->getVal( 'language', isset(
$parts[1] ) ? $parts[1] : '' );
+
+ if ( $this->languageCode === '' ) {
+ $this->languageCode = null;
+ }
+
+ if ( $this->languageCode !== null &&
!$this->isValidLanguageCode( $this->languageCode ) ) {
+ $errorMessage = $this->msg(
+ 'wikibase-wikibaserepopage-invalid-langcode',
+ $this->languageCode
+ )->parse();
+
+ $this->showErrorHTML( $errorMessage );
+ }
+
+ $this->labelDescriptionAliases = null;
+ if( $this->entityRevision !== null ) {
+ $entity = $this->entityRevision->getEntity();
+ if( $entity instanceof FingerprintProvider ) {
+ $this->labelDescriptionAliases =
$entity->getFingerprint();
+ }
+ }
+
+ if( $this->labelDescriptionAliases === null ) {
+ $this->labelDescriptionAliases = new Fingerprint();
+ }
+
+ if( $request->getVal( 'label' ) && $this->languageCode ) {
+ $this->labelDescriptionAliases->setLabel(
+ $this->languageCode,
+ $request->getVal( 'label' )
+ );
+ }
+
+ if( $request->getVal( 'description' ) && $this->languageCode ) {
+ $this->labelDescriptionAliases->setDescription(
+ $this->languageCode,
+ $request->getVal( 'description' )
+ );
+ }
+
+ if( $request->getVal( 'aliases' ) && $this->languageCode ) {
+ $this->labelDescriptionAliases->setAliasGroup(
+ $this->languageCode,
+ explode( '|', $request->getVal( 'aliases' ) )
+ );
+ }
+ }
+
+ /**
+ * Checks if the language code is valid.
+ *
+ * @param $languageCode string the language code
+ *
+ * @return bool
+ */
+ private function isValidLanguageCode( $languageCode ) {
+ return $languageCode !== null
+ && Language::isValidBuiltInCode( $languageCode )
+ && in_array( $languageCode, Utils::getLanguageCodes() );
+ }
+
+ /**
+ * @see SpecialModifyEntity::modifyEntity()
+ *
+ * @param Entity $entity
+ * @return Summary[]|bool
+ */
+ protected function modifyEntity( Entity $entity ) {
+ if( $this->labelDescriptionAliases === null ) {
+ return false;
+ }
+
+ $labelChangeOp =
$this->fingerprintChangeOpFactory->newSetLabelOp(
+ $this->languageCode,
+ $this->labelDescriptionAliases->getLabel(
$this->languageCode )->getText()
+ );
+ $descriptionChangeOp =
$this->fingerprintChangeOpFactory->newSetDescriptionOp(
+ $this->languageCode,
+ $this->labelDescriptionAliases->getDescription(
$this->languageCode )->getText()
+ );
+ $aliasesChangeOp =
$this->fingerprintChangeOpFactory->newSetAliasesOp(
+ $this->languageCode,
+ $this->labelDescriptionAliases->getAliasGroup(
$this->languageCode )->getAliases()
+ );
+
+ $success = true;
+
+ foreach( array( $labelChangeOp, $descriptionChangeOp,
$aliasesChangeOp ) as $changeOp ) {
+ try {
+ $this->applyChangeOp( $changeOp, $entity );
+ } catch ( ChangeOpException $e ) {
+ $this->showErrorHTML( $e->getMessage() );
+ $success = false;
+ }
+ }
+
+ if( !$success ) {
+ return false;
+ }
+
+ return $this->getSummary( 'wbeditentity' );
+ }
+}
diff --git
a/repo/tests/phpunit/includes/specials/SpecialSetLabelDescritionAliasesTest.php
b/repo/tests/phpunit/includes/specials/SpecialSetLabelDescritionAliasesTest.php
new file mode 100644
index 0000000..7dbdd5d
--- /dev/null
+++
b/repo/tests/phpunit/includes/specials/SpecialSetLabelDescritionAliasesTest.php
@@ -0,0 +1,135 @@
+<?php
+
+namespace Wikibase\Test;
+
+use Wikibase\DataModel\Entity\Item;
+use Wikibase\EntityContent;
+use Wikibase\Repo\Specials\SpecialSetLabelDescriptionAliases;
+use Wikibase\Repo\WikibaseRepo;
+
+/**
+ * @since 0.5
+ *
+ * @licence GNU GPL v2+
+ * @author Bene* < [email protected] >
+ * @author H. Snater < [email protected] >
+ */
+class SpecialSetLabelDescriptionAliasesTest extends SpecialPageTestBase {
+
+ /**
+ * @see SpecialPageTestBase::newSpecialPage()
+ *
+ * @return SpecialSetLabelDescriptionAliases
+ */
+ protected function newSpecialPage() {
+ return new SpecialSetLabelDescriptionAliases();
+ }
+
+ /**
+ * @return string
+ */
+ private function createNewItem() {
+ $item = Item::newEmpty();
+ // add data and check if it is shown in the form
+ $item->setLabel( 'de', 'foo' );
+ $item->setDescription( 'de', 'foo' );
+ $item->setAliases( 'de', array( 'foo' ) );
+
+ // save the item
+ $store = WikibaseRepo::getDefaultInstance()->getEntityStore();
+ $store->saveEntity( $item, "testing", $GLOBALS['wgUser'],
EDIT_NEW | EntityContent::EDIT_IGNORE_CONSTRAINTS );
+
+ // return the id
+ return $item->getId()->getSerialization();
+ }
+
+ public function testExecute() {
+ $id = $this->createNewItem();
+
+ $this->newSpecialPage();
+
+ $matchers['id'] = array(
+ 'tag' => 'input',
+ 'attributes' => array(
+ 'id' => 'wb-modifyentity-id',
+ 'class' => 'wb-input',
+ 'name' => 'id',
+ ),
+ );
+ $matchers['language'] = array(
+ 'tag' => 'input',
+ 'attributes' => array(
+ 'id' =>
'wikibase-setlabeldescriptionaliases-language',
+ 'class' => 'wb-input',
+ 'name' => 'language',
+ 'value' => 'en',
+ ),
+ );
+ $matchers['label'] = array(
+ 'tag' => 'input',
+ 'attributes' => array(
+ 'id' =>
'wikibase-setlabeldescriptionaliases-label',
+ 'class' => 'wb-input',
+ 'name' => 'label',
+ ),
+ );
+ $matchers['description'] = array(
+ 'tag' => 'input',
+ 'attributes' => array(
+ 'id' =>
'wikibase-setlabeldescriptionaliases-description',
+ 'class' => 'wb-input',
+ 'name' => 'description',
+ ),
+ );
+ $matchers['aliases'] = array(
+ 'tag' => 'input',
+ 'attributes' => array(
+ 'id' =>
'wikibase-setlabeldescriptionaliases-aliases',
+ 'class' => 'wb-input',
+ 'name' => 'aliases',
+ ),
+ );
+ $matchers['submit'] = array(
+ 'tag' => 'input',
+ 'attributes' => array(
+ 'id' => 'wb-setlabeldescriptionaliases-submit',
+ 'class' => 'wb-button',
+ 'type' => 'submit',
+ 'name' =>
'wikibase-setlabeldescriptionaliases-submit',
+ ),
+ );
+
+ // execute with no subpage value
+ list( $output, ) = $this->executeSpecialPage( '', null, 'en' );
+ foreach( $matchers as $key => $matcher ) {
+ $this->assertTag( $matcher, $output, "Failed to match
html output with tag '{$key}'" );
+ }
+
+ // execute with one subpage value
+ list( $output, ) = $this->executeSpecialPage( $id, null, 'en' );
+ $matchers['id']['attributes'] = array(
+ 'type' => 'hidden',
+ 'name' => 'id',
+ 'value' => $id,
+ );
+ $matchers['language']['attributes'] = array(
+ 'type' => 'hidden',
+ 'name' => 'language',
+ 'value' => 'en',
+ );
+
+ foreach( $matchers as $key => $matcher ) {
+ $this->assertTag( $matcher, $output, "Failed to match
html output with tag '{$key}' passing one subpage value" );
+ }
+
+ // execute with two subpage values
+ list( $output, ) = $this->executeSpecialPage( $id . '/de',
null, 'en' );
+ $matchers['language']['attributes']['value'] = 'de';
+ $matchers['value']['attributes']['value'] = 'foo';
+
+ foreach( $matchers as $key => $matcher ) {
+ $this->assertTag( $matcher, $output, "Failed to match
html output with tag '{$key}' passing two subpage values" );
+ }
+ }
+
+}
--
To view, visit https://gerrit.wikimedia.org/r/187423
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: I9c23eca9f7303c3be04e3ac2c07f45779f1a0746
Gerrit-PatchSet: 1
Gerrit-Project: mediawiki/extensions/Wikibase
Gerrit-Branch: master
Gerrit-Owner: Henning Snater <[email protected]>
_______________________________________________
MediaWiki-commits mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits