WikidataBuilder has uploaded a new change for review. (
https://gerrit.wikimedia.org/r/357986 )
Change subject: New Wikidata Build - 2017-06-09T10:00:02+0000
......................................................................
New Wikidata Build - 2017-06-09T10:00:02+0000
Change-Id: Ic1ceb3c8960f1124b1a9b4e523bfd3e34ca50b23
---
M composer.lock
M extensions/Constraints/extension.json
M extensions/Constraints/i18n/de.json
M extensions/Constraints/i18n/en.json
M extensions/Constraints/i18n/qqq.json
M
extensions/Constraints/includes/ConstraintCheck/DelegatingConstraintChecker.php
A
extensions/Constraints/includes/ConstraintCheck/Helper/ConstraintParameterException.php
A
extensions/Constraints/includes/ConstraintCheck/Helper/ConstraintStatementParameterParser.php
M extensions/Constraints/tests/phpunit/ConstraintParameters.php
A
extensions/Constraints/tests/phpunit/Helper/ConstraintStatementParameterParserTest.php
A extensions/PropertySuggester/i18n/lt.json
M extensions/Wikibase/client/i18n/hr.json
M extensions/Wikibase/client/includes/Hooks/OtherProjectsSidebarGenerator.php
M
extensions/Wikibase/client/includes/Hooks/OtherProjectsSidebarGeneratorFactory.php
M extensions/Wikibase/client/includes/Hooks/SidebarLinkBadgeDisplay.php
M extensions/Wikibase/client/includes/WikibaseClient.php
M
extensions/Wikibase/client/tests/phpunit/includes/Hooks/OtherProjectsSidebarGeneratorFactoryTest.php
M
extensions/Wikibase/client/tests/phpunit/includes/Hooks/OtherProjectsSidebarGeneratorTest.php
M
extensions/Wikibase/client/tests/phpunit/includes/Hooks/ParserOutputUpdateHookHandlersTest.php
M extensions/Wikibase/client/tests/phpunit/includes/WikibaseClientTest.php
M extensions/Wikibase/lib/includes/Formatters/MwTimeIsoFormatter.php
M extensions/Wikibase/lib/includes/Store/Sql/TermSqlIndex.php
M extensions/Wikibase/lib/tests/phpunit/Formatters/MwTimeIsoFormatterTest.php
M extensions/Wikibase/lib/tests/phpunit/Store/Sql/TermSqlIndexTest.php
M extensions/Wikibase/repo/i18n/pt.json
M vendor/composer/autoload_classmap.php
M vendor/composer/autoload_static.php
M vendor/composer/installed.json
28 files changed, 837 insertions(+), 80 deletions(-)
git pull ssh://gerrit.wikimedia.org:29418/mediawiki/extensions/Wikidata
refs/changes/86/357986/1
diff --git a/composer.lock b/composer.lock
index fec0e76..57052ad 100644
--- a/composer.lock
+++ b/composer.lock
@@ -792,7 +792,7 @@
"source": {
"type": "git",
"url":
"https://gerrit.wikimedia.org/r/mediawiki/extensions/PropertySuggester",
- "reference": "154f36bdab44696678da0a5fad13d13c856a1977"
+ "reference": "81a4c1f16488baac1475f36b692ba5135e54d4dc"
},
"require": {
"php": ">=5.5.9",
@@ -840,7 +840,7 @@
"wikibase",
"wikidata"
],
- "time": "2017-06-07 11:02:22"
+ "time": "2017-06-08 21:07:10"
},
{
"name": "serialization/serialization",
@@ -957,7 +957,7 @@
"source": {
"type": "git",
"url":
"https://gerrit.wikimedia.org/r/mediawiki/extensions/WikibaseQualityConstraints",
- "reference": "1ca666bcf75650f02623da140594b50430af1ef8"
+ "reference": "ec938fd93421b4c552c41f94282adde8088e03b8"
},
"require": {
"php": ">=5.5.9",
@@ -1018,7 +1018,7 @@
"support": {
"issues":
"https://phabricator.wikimedia.org/project/profile/1202/"
},
- "time": "2017-06-07 12:16:47"
+ "time": "2017-06-08 21:17:20"
},
{
"name": "wikibase/data-model",
@@ -1603,12 +1603,12 @@
"source": {
"type": "git",
"url":
"https://github.com/wikimedia/mediawiki-extensions-Wikibase.git",
- "reference": "1bb3f48e85953e89f54a5a997b8a356e2f384285"
+ "reference": "3ad89acdac353323018a29dc32ae76aaa7866e55"
},
"dist": {
"type": "zip",
- "url":
"https://api.github.com/repos/wikimedia/mediawiki-extensions-Wikibase/zipball/1bb3f48e85953e89f54a5a997b8a356e2f384285",
- "reference": "1bb3f48e85953e89f54a5a997b8a356e2f384285",
+ "url":
"https://api.github.com/repos/wikimedia/mediawiki-extensions-Wikibase/zipball/3ad89acdac353323018a29dc32ae76aaa7866e55",
+ "reference": "3ad89acdac353323018a29dc32ae76aaa7866e55",
"shasum": ""
},
"require": {
@@ -1684,7 +1684,7 @@
"wikibaserepo",
"wikidata"
],
- "time": "2017-06-07 13:35:32"
+ "time": "2017-06-09 08:00:16"
},
{
"name": "wikibase/wikimedia-badges",
diff --git a/extensions/Constraints/extension.json
b/extensions/Constraints/extension.json
index 0c8031c..176a2f7 100644
--- a/extensions/Constraints/extension.json
+++ b/extensions/Constraints/extension.json
@@ -105,6 +105,26 @@
"value": "Q21510862",
"description": "The item ID of the 'symmetric
constraint' item, which, when used in a 'property constraint' statement on a
property, indicates that a referenced entity should refer back to the original
entity.",
"public": true
+ },
+ "WBQualityConstraintsClassId": {
+ "value": "P2308",
+ "description": "The property ID of the 'relation'
property, which specifies the class/type of a 'type' or 'value type'
constraint.",
+ "public": true
+ },
+ "WBQualityConstraintsRelationId": {
+ "value": "P2309",
+ "description": "The property ID of the 'relation'
property, which specifies the relation ('instance of' or 'subclass of') of a
'type' or 'value type' constraint.",
+ "public": true
+ },
+ "WBQualityConstraintsInstanceOfRelationId": {
+ "value": "Q21503252",
+ "description": "The item ID of the 'instance of' item,
which, when used in a 'relation' qualifier of a 'property constraint' statement
on a property, indicates that the 'type' or 'value type' constraint defined in
this statement demands an 'instance' relation.",
+ "public": true
+ },
+ "WBQualityConstraintsSubclassOfRelationId": {
+ "value": "Q21514624",
+ "description": "The item ID of the 'subclass of' item,
which, when used in a 'relation' qualifier of a 'property constraint' statement
on a property, indicates that the 'type' or 'value type' constraint defined in
this statement demands a 'subclass' relation.",
+ "public": true
}
},
"manifest_version": 2
diff --git a/extensions/Constraints/i18n/de.json
b/extensions/Constraints/i18n/de.json
index d0b43d3..1a32409 100644
--- a/extensions/Constraints/i18n/de.json
+++ b/extensions/Constraints/i18n/de.json
@@ -48,6 +48,10 @@
"wbqc-violation-message-parameters-needed-3": "Eigenschaften mit der
Beschränkung „$1“ benötigen die Parameter „$2“, „$3“ und „$4“.",
"wbqc-violation-message-target-entity-must-exist": "Das Zielobjekt muss
vorhanden sein.",
"wbqc-violation-message-value-entity-must-exist": "Das Werteobjekt muss
vorhanden sein.",
+ "wbqc-violation-message-parameter-value": "Der Parameter „$1“ muss
einen realen Wert haben, nicht „kein Wert“ oder „unbekannter Wert“.",
+ "wbqc-violation-message-parameter-entity": "Der Wert für den Parameter
„$1“ muss ein Objekt sein, nicht „$2“.",
+ "wbqc-violation-message-parameter-single": "Der Parameter „$1“ darf nur
einen einzigen Wert haben.",
+ "wbqc-violation-message-parameter-oneof": "Der Parameter „$1“ muss
{{PLURAL:$2|1=$4 sein.|2=entweder $4 oder $5 sein.|eines der folgenden Werte
sein: $3.}}",
"wbqc-violation-message-commons-link-no-existent": "Der Commons-Link
sollte vorhanden sein.",
"wbqc-violation-message-commons-link-not-well-formed": "Der
Commons-Link sollte wohlgeformt sein.",
"wbqc-violation-message-commons-link-check-for-namespace-not-yet-implemented":
"Die Prüfung für den Namensraum „$1“ ist noch nicht implementiert.",
diff --git a/extensions/Constraints/i18n/en.json
b/extensions/Constraints/i18n/en.json
index a4455cc..fed8913 100644
--- a/extensions/Constraints/i18n/en.json
+++ b/extensions/Constraints/i18n/en.json
@@ -54,6 +54,10 @@
"wbqc-violation-message-parameters-needed-3": "Properties with
constraint \"$1\" need parameters \"$2\", \"$3\", and \"$4\".",
"wbqc-violation-message-target-entity-must-exist": "The target entity
must exist.",
"wbqc-violation-message-value-entity-must-exist": "The value entity
must exist.",
+ "wbqc-violation-message-parameter-value": "The parameter \"$1\" must
have a real value, not \"no value\" or \"unknown value\".",
+ "wbqc-violation-message-parameter-entity": "The value for the parameter
\"$1\" must be an entity, not \"$2\".",
+ "wbqc-violation-message-parameter-single": "The parameter \"$1\" must
only have a single value.",
+ "wbqc-violation-message-parameter-oneof": "The parameter \"$1\" must be
{{PLURAL:$2|1=$4.|2=either $4 or $5.|one of the following:$3}}",
"wbqc-violation-message-commons-link-no-existent": "Commons link should
exist.",
"wbqc-violation-message-commons-link-not-well-formed": "Commons link
should be well-formed.",
diff --git a/extensions/Constraints/i18n/qqq.json
b/extensions/Constraints/i18n/qqq.json
index 6db1eb2..84a07f8 100644
--- a/extensions/Constraints/i18n/qqq.json
+++ b/extensions/Constraints/i18n/qqq.json
@@ -50,6 +50,10 @@
"wbqc-violation-message-parameters-needed-3": "Message for when a
constraint needs three specific parameters, but some of them are missing.",
"wbqc-violation-message-target-entity-must-exist": "Message for when an
entity is referenced, but it doesn't exist (any more).",
"wbqc-violation-message-value-entity-must-exist": "Message for when the
property has an entity as its value, but it doesn't exist (any more).",
+ "wbqc-violation-message-parameter-value": "Message for when \"no
value\" or \"unknown value\" has been entered as the value of a constraint
parameter that must be an actual value. $1 contains the parameter.",
+ "wbqc-violation-message-parameter-entity": "Message for when the value
of a constraint parameter must be an entity, but is some other kind of data
value. $1 contains the parameter, $2 the data value type.",
+ "wbqc-violation-message-parameter-single": "Message for when a
constraint parameter has multiple values but only supports one. $1 contains the
parameter.",
+ "wbqc-violation-message-parameter-oneof": "Message for when a
constraint parameter must be one of several values, but is something different.
$1 contains the parameter, $2 the number of allowed values (possibly 1), $3 an
HTML list of all allowed values, and $4, $5 etc. are the individual allowed
values.{{Related|wbqc-violation-message-one-of}}",
"wbqc-violation-message-commons-link-no-existent": "Message for
violation of Commons link constraint. When linked commons page does not exist.",
"wbqc-violation-message-commons-link-not-well-formed": "Message for
violation of Commons link constraint. When link contains invalid characters.",
"wbqc-violation-message-commons-link-check-for-namespace-not-yet-implemented":
"Message for when the check for the Commons link constraint has not yet been
implemented for a specific namespace.",
diff --git
a/extensions/Constraints/includes/ConstraintCheck/DelegatingConstraintChecker.php
b/extensions/Constraints/includes/ConstraintCheck/DelegatingConstraintChecker.php
index 5bcbcf2..c516a32 100644
---
a/extensions/Constraints/includes/ConstraintCheck/DelegatingConstraintChecker.php
+++
b/extensions/Constraints/includes/ConstraintCheck/DelegatingConstraintChecker.php
@@ -10,6 +10,7 @@
use Wikibase\DataModel\Statement\StatementGuid;
use Wikibase\DataModel\Statement\StatementList;
use Wikibase\DataModel\Statement\StatementListProvider;
+use
WikibaseQuality\ConstraintReport\ConstraintCheck\Helper\ConstraintParameterException;
use WikibaseQuality\ConstraintReport\ConstraintCheck\Result\CheckResult;
use WikibaseQuality\ConstraintReport\ConstraintLookup;
use WikibaseQuality\ConstraintReport\Constraint;
@@ -236,7 +237,19 @@
$statsd =
MediaWikiServices::getInstance()->getStatsdDataFactory();
$startTime = microtime( true );
- $result = $checker->checkConstraint( $statement,
$constraint, $entity );
+ try {
+ $result = $checker->checkConstraint(
$statement, $constraint, $entity );
+ } catch ( ConstraintParameterException $e ) {
+ $result = new CheckResult(
+ $entity->getId(),
+ $statement,
+ $constraint->getConstraintTypeQid(),
+ $constraint->getConstraintId(),
+ [],
+ CheckResult::STATUS_VIOLATION,
+ $e->getMessage()
+ );
+ }
$statsd->timing(
'wikibase.quality.constraints.check.timing.' .
$constraint->getConstraintTypeQid(),
( microtime( true ) - $startTime ) * 1000
diff --git
a/extensions/Constraints/includes/ConstraintCheck/Helper/ConstraintParameterException.php
b/extensions/Constraints/includes/ConstraintCheck/Helper/ConstraintParameterException.php
new file mode 100644
index 0000000..16e4bb1
--- /dev/null
+++
b/extensions/Constraints/includes/ConstraintCheck/Helper/ConstraintParameterException.php
@@ -0,0 +1,23 @@
+<?php
+
+namespace WikibaseQuality\ConstraintReport\ConstraintCheck\Helper;
+
+use Exception;
+
+/**
+ * Exception thrown when a constraint’s parameters are invalid.
+ *
+ * @package WikibaseQuality\ConstraintReport\ConstraintCheck\Helper
+ * @author Lucas Werkmeister
+ * @license GNU GPL v2+
+ */
+class ConstraintParameterException extends Exception {
+
+ /**
+ * @param string $message HTML
+ */
+ public function __construct( $message ) {
+ parent::__construct( $message );
+ }
+
+}
diff --git
a/extensions/Constraints/includes/ConstraintCheck/Helper/ConstraintStatementParameterParser.php
b/extensions/Constraints/includes/ConstraintCheck/Helper/ConstraintStatementParameterParser.php
new file mode 100644
index 0000000..86696f7
--- /dev/null
+++
b/extensions/Constraints/includes/ConstraintCheck/Helper/ConstraintStatementParameterParser.php
@@ -0,0 +1,219 @@
+<?php
+
+namespace WikibaseQuality\ConstraintReport\ConstraintCheck\Helper;
+
+use Config;
+use Message;
+use Wikibase\DataModel\DeserializerFactory;
+use Wikibase\DataModel\Deserializers\SnakDeserializer;
+use Wikibase\DataModel\Entity\EntityId;
+use Wikibase\DataModel\Entity\EntityIdValue;
+use Wikibase\DataModel\Snak\PropertyValueSnak;
+use Wikibase\DataModel\Snak\Snak;
+use WikibaseQuality\ConstraintReport\ConstraintParameterRenderer;
+
+/**
+ * Helper for parsing constraint parameters
+ * that were imported from constraint statements.
+ *
+ * All public methods of this class expect snak array serializations,
+ * as stored by {@link
\WikibaseQuality\ConstraintReport\UpdateConstraintsTableJob},
+ * and return parameter objects or throw {@link ConstraintParameterException}s.
+ * The results are used by the checkers,
+ * which may include rendering them into violation messages.
+ * (For backwards compatibility, the methods currently also support
+ * parsing constraint parameters from templates.
+ * This will be removed eventually.)
+ *
+ * Not to be confused with {@link ConstraintParameterParser},
+ * which parses constraint parameters from templates.
+ *
+ * @package WikibaseQuality\ConstraintReport\ConstraintCheck\Helper
+ * @author Lucas Werkmeister
+ * @license GNU GPL v2+
+ */
+class ConstraintStatementParameterParser {
+
+ /**
+ * @var Config
+ */
+ private $config;
+
+ /**
+ * @var SnakDeserializer
+ */
+ private $snakDeserializer;
+
+ /**
+ * @var ConstraintParameterRenderer
+ */
+ private $constraintParameterRenderer;
+
+ /**
+ * @param Config $config
+ * contains entity IDs used in constraint parameters (constraint
statement qualifiers)
+ * @param DeserializerFactory $factory
+ * used to parse constraint statement qualifiers into constraint
parameters
+ * @param ConstraintParameterRenderer $constraintParameterRenderer
+ * used to render incorrect parameters for error messages
+ */
+ public function __construct(
+ Config $config,
+ DeserializerFactory $factory,
+ ConstraintParameterRenderer $constraintParameterRenderer
+ ) {
+ $this->config = $config;
+ $this->snakDeserializer = $factory->newSnakDeserializer();
+ $this->constraintParameterRenderer =
$constraintParameterRenderer;
+ }
+
+ /**
+ * Require that $parameters contains exactly one $parameterId parameter.
+ * @param array $parameters
+ * @param string $parameterId
+ * @throws ConstraintParameterException
+ */
+ private function requireSingleParameter( array $parameters,
$parameterId ) {
+ if ( count( $parameters[$parameterId] ) !== 1 ) {
+ throw new ConstraintParameterException(
+ wfMessage(
'wbqc-violation-message-parameter-single' )
+ ->rawParams(
$this->constraintParameterRenderer->formatPropertyId( $parameterId ) )
+ ->escaped()
+ );
+ }
+ }
+
+ /**
+ * Require that $snak is a {@link PropertyValueSnak}.
+ * @param Snak $snak
+ * @param string $parameterId
+ * @return void
+ * @throws ConstraintParameterException
+ */
+ private function requireValueParameter( Snak $snak, $parameterId ) {
+ if ( !( $snak instanceof PropertyValueSnak ) ) {
+ throw new ConstraintParameterException(
+ wfMessage(
'wbqc-violation-message-parameter-value' )
+ ->rawParams(
$this->constraintParameterRenderer->formatPropertyId( $parameterId ) )
+ ->escaped()
+ );
+ }
+ }
+
+ /**
+ * Parse a single entity ID parameter.
+ * @param array $snakSerialization
+ * @param string $parameterId
+ * @throws ConstraintParameterException
+ * @return EntityId
+ */
+ private function parseEntityIdParameter( array $snakSerialization,
$parameterId ) {
+ $snak = $this->snakDeserializer->deserialize(
$snakSerialization );
+ $this->requireValueParameter( $snak, $parameterId );
+ $value = $snak->getDataValue();
+ if ( $value instanceof EntityIdValue ) {
+ return $value->getEntityId();
+ } else {
+ throw new ConstraintParameterException(
+ wfMessage(
'wbqc-violation-message-parameter-entity' )
+ ->rawParams(
+
$this->constraintParameterRenderer->formatPropertyId( $parameterId ),
+
$this->constraintParameterRenderer->formatDataValue( $value )
+ )
+ ->escaped()
+ );
+ }
+ }
+
+ private function parseClassParameterFromStatement( array
$constraintParameters ) {
+ $classId = $this->config->get( 'WBQualityConstraintsClassId' );
+ $classes = [];
+ foreach ( $constraintParameters[$classId] as $class ) {
+ $classes[] = $this->parseEntityIdParameter( $class,
$classId )->getSerialization();
+ }
+ return $classes;
+ }
+
+ private function parseClassParameterFromTemplate( array
$constraintParameters ) {
+ return explode( ',', $constraintParameters['class'] );
+ }
+
+ /**
+ * @param array $constraintParameters
+ * @param string $constraintTypeName used in error messages
+ * @throws ConstraintParameterException if the parameter is invalid or
missing
+ * @return string[] class entity ID serializations
+ */
+ public function parseClassParameter( array $constraintParameters,
$constraintTypeName ) {
+ $classId = $this->config->get( 'WBQualityConstraintsClassId' );
+ if ( array_key_exists( $classId, $constraintParameters ) ) {
+ return $this->parseClassParameterFromStatement(
$constraintParameters );
+ } elseif ( array_key_exists( 'class', $constraintParameters ) )
{
+ return $this->parseClassParameterFromTemplate(
$constraintParameters );
+ } else {
+ throw new ConstraintParameterException(
+ wfMessage(
'wbqc-violation-message-parameter-needed' )
+ ->params( $constraintTypeName )
+ ->rawParams(
$this->constraintParameterRenderer->formatPropertyId( $classId ) )
+ ->escaped()
+ );
+ }
+ }
+
+ private function parseRelationParameterFromStatement( array
$constraintParameters ) {
+ $relationId = $this->config->get(
'WBQualityConstraintsRelationId' );
+ $this->requireSingleParameter( $constraintParameters,
$relationId );
+ $relationEntityId = $this->parseEntityIdParameter(
$constraintParameters[$relationId][0], $relationId );
+ $instanceId = $this->config->get(
'WBQualityConstraintsInstanceOfRelationId' );
+ $subclassId = $this->config->get(
'WBQualityConstraintsSubclassOfRelationId' );
+ switch ( $relationEntityId ) {
+ case $instanceId:
+ return 'instance';
+ case $subclassId:
+ return 'subclass';
+ default:
+ throw new ConstraintParameterException(
+ wfMessage(
'wbqc-violation-message-parameter-oneof' )
+ ->rawParams(
$this->constraintParameterRenderer->formatPropertyId( $relationId ) )
+ ->numParams( 2 )
+ ->rawParams(
$this->constraintParameterRenderer->formatItemIdList( [ $instanceId,
$subclassId ] ) )
+ ->escaped()
+ );
+ }
+ }
+
+ private function parseRelationParameterFromTemplate( array
$constraintParameters ) {
+ $relation = $constraintParameters['relation'];
+ if ( $relation === 'instance' || $relation === 'subclass' ) {
+ return $relation;
+ } else {
+ throw new ConstraintParameterException(
+ wfMessage(
'wbqc-violation-message-type-relation-instance-or-subclass' )
+ ->escaped()
+ );
+ }
+ }
+
+ /**
+ * @param array $constraintParameters
+ * @param string $constraintTypeName used in error messages
+ * @throws ConstraintParameterException if the parameter is invalid or
missing
+ * @return string 'instance' or 'subclass'
+ */
+ public function parseRelationParameter( array $constraintParameters,
$constraintTypeName ) {
+ $relationId = $this->config->get(
'WBQualityConstraintsRelationId' );
+ if ( array_key_exists( $relationId, $constraintParameters ) ) {
+ return $this->parseRelationParameterFromStatement(
$constraintParameters );
+ } elseif ( array_key_exists( 'relation', $constraintParameters
) ) {
+ return $this->parseRelationParameterFromTemplate(
$constraintParameters );
+ } else {
+ throw new ConstraintParameterException(
+ wfMessage(
'wbqc-violation-message-parameter-needed' )
+ ->params( $constraintTypeName )
+ ->rawParams(
$this->constraintParameterRenderer->formatPropertyId( $relationId ) )
+ ->escaped()
+ );
+ }
+ }
+
+}
diff --git a/extensions/Constraints/tests/phpunit/ConstraintParameters.php
b/extensions/Constraints/tests/phpunit/ConstraintParameters.php
index 031cb10..868994d 100644
--- a/extensions/Constraints/tests/phpunit/ConstraintParameters.php
+++ b/extensions/Constraints/tests/phpunit/ConstraintParameters.php
@@ -4,6 +4,7 @@
use ValueFormatters\ValueFormatter;
use Wikibase\DataModel\Services\EntityId\PlainEntityIdFormatter;
+use
WikibaseQuality\ConstraintReport\ConstraintCheck\Helper\ConstraintStatementParameterParser;
use WikibaseQuality\ConstraintReport\ConstraintParameterRenderer;
use Wikibase\Repo\WikibaseRepo;
@@ -16,10 +17,30 @@
use DefaultConfig;
/**
+ * @var ConstraintStatementParameterParser
+ */
+ private $parser;
+
+ /**
* @var ConstraintParameterRenderer
*/
private $renderer;
+ /**
+ * @return ConstraintStatementParameterParser
+ */
+ public function getConstraintParameterParser() {
+ if ( $this->parser === null ) {
+ $this->parser = new ConstraintStatementParameterParser(
+ $this->getDefaultConfig(),
+
WikibaseRepo::getDefaultInstance()->getBaseDataModelDeserializerFactory(),
+ $this->getConstraintParameterRenderer()
+ );
+ }
+
+ return $this->parser;
+ }
+
public function getConstraintParameterRenderer() {
if ( $this->renderer === null ) {
$valueFormatter = $this->getMock( ValueFormatter::class
);
diff --git
a/extensions/Constraints/tests/phpunit/Helper/ConstraintStatementParameterParserTest.php
b/extensions/Constraints/tests/phpunit/Helper/ConstraintStatementParameterParserTest.php
new file mode 100644
index 0000000..d3f0b22
--- /dev/null
+++
b/extensions/Constraints/tests/phpunit/Helper/ConstraintStatementParameterParserTest.php
@@ -0,0 +1,242 @@
+<?php
+
+namespace WikibaseQuality\ConstraintReport\Test\Helper;
+
+use DataValues\StringValue;
+use Wikibase\DataModel\Entity\EntityIdValue;
+use Wikibase\DataModel\Entity\ItemId;
+use Wikibase\DataModel\Entity\PropertyId;
+use Wikibase\DataModel\Serializers\SnakSerializer;
+use Wikibase\DataModel\Snak\PropertyNoValueSnak;
+use Wikibase\DataModel\Snak\PropertyValueSnak;
+use Wikibase\Repo\WikibaseRepo;
+use
WikibaseQuality\ConstraintReport\ConstraintCheck\Helper\ConstraintParameterException;
+use
WikibaseQuality\ConstraintReport\ConstraintCheck\Helper\ConstraintStatementParameterParser;
+use WikibaseQuality\ConstraintReport\ConstraintCheck\Result\CheckResult;
+use WikibaseQuality\ConstraintReport\Tests\ConstraintParameters;
+use WikibaseQuality\ConstraintReport\Tests\ResultAssertions;
+use Wikibase\DataModel\Statement\Statement;
+
+/**
+ * @covers
\WikibaseQuality\ConstraintReport\ConstraintCheck\Helper\ConstraintStatementParameterParser
+ *
+ * @group WikibaseQualityConstraints
+ *
+ * @author Lucas Werkmeister
+ * @license GNU GPL v2+
+ */
+class ConstraintStatementParameterParserTest extends \MediaWikiLangTestCase {
+
+ use ConstraintParameters, ResultAssertions;
+
+ /**
+ * @var SnakSerializer
+ */
+ private $snakSerializer;
+
+ protected function setUp() {
+ parent::setUp();
+ $this->snakSerializer =
WikibaseRepo::getDefaultInstance()->getSerializerFactory()->newSnakSerializer();
+ }
+
+ /**
+ * @param string $itemId
+ * @return array
+ */
+ private function serializeItemId( $itemId ) {
+ return $this->snakSerializer->serialize(
+ new PropertyValueSnak(
+ new PropertyId( 'P1' ),
+ new EntityIdValue( new ItemId( $itemId ) )
+ )
+ );
+ }
+
+ /**
+ * @param string $method
+ * @param array $arguments
+ * @param string $messageKey
+ * @see
\WikibaseQuality\ConstraintReport\Tests\ResultAssertions::assertViolation
+ */
+ private function assertThrowsConstraintParameterException( $method,
array $arguments, $messageKey ) {
+ try {
+ call_user_func_array( [
$this->getConstraintParameterParser(), $method ], $arguments );
+ $this->assertTrue( false,
+ "$method should have thrown a
ConstraintParameterException with message ⧼${messageKey}⧽." );
+ } catch ( ConstraintParameterException $exception ) {
+ $checkResult = new CheckResult(
+ new ItemId( 'Q1' ),
+ new Statement( new PropertyNoValueSnak( new
PropertyId( 'P1' ) ) ),
+ 'constraint type Q-ID',
+ 'constraint ID',
+ [],
+ CheckResult::STATUS_VIOLATION,
+ $exception->getMessage()
+ );
+ $this->assertViolation( $checkResult, $messageKey );
+ }
+ }
+
+ public function testParseClassParameter() {
+ $config = $this->getDefaultConfig();
+ $classId = $config->get( 'WBQualityConstraintsClassId' );
+ $parsed =
$this->getConstraintParameterParser()->parseClassParameter(
+ [ $classId => [ $this->serializeItemId( 'Q100' ),
$this->serializeItemId( 'Q101' ) ] ],
+ ''
+ );
+ $this->assertEquals( [ 'Q100', 'Q101' ], $parsed );
+ }
+
+ public function testParseClassParameterFromTemplate() {
+ $parsed =
$this->getConstraintParameterParser()->parseClassParameter(
+ [ 'class' => 'Q100,Q101' ],
+ ''
+ );
+ $this->assertEquals( [ 'Q100', 'Q101' ], $parsed );
+ }
+
+ public function testParseClassParameterMissing() {
+ $this->assertThrowsConstraintParameterException(
+ 'parseClassParameter',
+ [ [], 'constraint' ],
+ 'wbqc-violation-message-parameter-needed'
+ );
+ }
+
+ public function testParseClassParameterNoValue() {
+ $config = $this->getDefaultConfig();
+ $classId = $config->get( 'WBQualityConstraintsClassId' );
+ $this->assertThrowsConstraintParameterException(
+ 'parseClassParameter',
+ [
+ [
+ $classId => [
+
$this->snakSerializer->serialize( new PropertyNoValueSnak( new PropertyId(
$classId ) ) )
+ ]
+ ],
+ 'constraint'
+ ],
+ 'wbqc-violation-message-parameter-value'
+ );
+ }
+
+ public function testParseClassParameterStringValue() {
+ $config = $this->getDefaultConfig();
+ $classId = $config->get( 'WBQualityConstraintsClassId' );
+ $this->assertThrowsConstraintParameterException(
+ 'parseClassParameter',
+ [
+ [
+ $classId => [
+
$this->snakSerializer->serialize( new PropertyValueSnak(
+ new PropertyId(
$classId ),
+ new StringValue( 'Q100'
)
+ ) )
+ ]
+ ],
+ 'constraint'
+ ],
+ 'wbqc-violation-message-parameter-entity'
+ );
+ }
+
+ public function testParseRelationParameter() {
+ $config = $this->getDefaultConfig();
+ $relationId = $config->get( 'WBQualityConstraintsRelationId' );
+ $instanceOfId = $config->get(
'WBQualityConstraintsInstanceOfRelationId' );
+ $parsed =
$this->getConstraintParameterParser()->parseRelationParameter(
+ [ $relationId => [ $this->serializeItemId(
$instanceOfId ) ] ],
+ ''
+ );
+ $this->assertEquals( 'instance', $parsed );
+ }
+
+ public function testParseRelationParameterFromTemplate() {
+ $parsed =
$this->getConstraintParameterParser()->parseRelationParameter(
+ [ 'relation' => 'instance' ],
+ ''
+ );
+ $this->assertEquals( 'instance', $parsed );
+ }
+
+ public function testParseRelationParameterMissing() {
+ $this->assertThrowsConstraintParameterException(
+ 'parseRelationParameter',
+ [ [], 'constraint' ],
+ 'wbqc-violation-message-parameter-needed'
+ );
+ }
+
+ public function testParseRelationParameterNoValue() {
+ $config = $this->getDefaultConfig();
+ $relationId = $config->get( 'WBQualityConstraintsRelationId' );
+ $this->assertThrowsConstraintParameterException(
+ 'parseRelationParameter',
+ [
+ [
+ $relationId => [
+
$this->snakSerializer->serialize( new PropertyNoValueSnak( new PropertyId(
$relationId ) ) )
+ ]
+ ],
+ 'constraint'
+ ],
+ 'wbqc-violation-message-parameter-value'
+ );
+ }
+
+ public function testParseRelationParameterStringValue() {
+ $config = $this->getDefaultConfig();
+ $relationId = $config->get( 'WBQualityConstraintsRelationId' );
+ $this->assertThrowsConstraintParameterException(
+ 'parseRelationParameter',
+ [
+ [
+ $relationId => [
+
$this->snakSerializer->serialize( new PropertyValueSnak(
+ new PropertyId(
$relationId ),
+ new StringValue(
'instance' )
+ ) )
+ ]
+ ],
+ 'constraint'
+ ],
+ 'wbqc-violation-message-parameter-entity'
+ );
+ }
+
+ public function testParseRelationParameterMultiValue() {
+ $config = $this->getDefaultConfig();
+ $relationId = $config->get( 'WBQualityConstraintsRelationId' );
+ $instanceOfId = $config->get(
'WBQualityConstraintsInstanceOfRelationId' );
+ $subclassOfId = $config->get(
'WBQualityConstraintsSubclassOfRelationId' );
+ $this->assertThrowsConstraintParameterException(
+ 'parseRelationParameter',
+ [
+ [
+ $relationId => [
+ $this->serializeItemId(
$instanceOfId ),
+ $this->serializeItemId(
$subclassOfId )
+ ]
+ ],
+ 'constraint'
+ ],
+ 'wbqc-violation-message-parameter-single'
+ );
+ }
+
+ public function testParseRelationParameterWrongValue() {
+ $config = $this->getDefaultConfig();
+ $relationId = $config->get( 'WBQualityConstraintsRelationId' );
+ $this->assertThrowsConstraintParameterException(
+ 'parseRelationParameter',
+ [
+ [
+ $relationId => [
$this->serializeItemId( 'Q1' ) ]
+ ],
+ 'constraint'
+ ],
+ 'wbqc-violation-message-parameter-oneof'
+ );
+ }
+
+}
diff --git a/extensions/PropertySuggester/i18n/lt.json
b/extensions/PropertySuggester/i18n/lt.json
new file mode 100644
index 0000000..7cdfb0f
--- /dev/null
+++ b/extensions/PropertySuggester/i18n/lt.json
@@ -0,0 +1,11 @@
+{
+ "@metadata": {
+ "authors": [
+ "Eitvys200"
+ ]
+ },
+ "apihelp-wbsgetsuggestions-example-1": "Gauti pasiūlymų objektui Q4",
+ "apihelp-wbsgetsuggestions-param-language": "Rezultato kalba.",
+ "apihelp-wbsgetsuggestions-param-limit": "Maksimalus rezultatų
skaičius.",
+ "apihelp-wbsgetsuggestions-param-search": "Ieškoti šio teksto."
+}
diff --git a/extensions/Wikibase/client/i18n/hr.json
b/extensions/Wikibase/client/i18n/hr.json
index df91abd..aa4d6c5 100644
--- a/extensions/Wikibase/client/i18n/hr.json
+++ b/extensions/Wikibase/client/i18n/hr.json
@@ -61,6 +61,7 @@
"wikibase-otherprojects": "Na drugim projektima",
"wikibase-otherprojects-beta-message": "Drugi projekti na bočnoj traci",
"wikibase-otherprojects-beta-description": "Dodaje odlomak
\"{{int:wikibase-otherprojects}}\" na bočnoj traci s poveznicama na ostale
Wikimedijine projekte na osnovi podataka s projekta {{WBREPONAME}}.",
+ "echo-category-title-wikibase-action":
"{{PLURAL:$1|Povezivanje|Povezivanja}} s projektom {{WBREPONAME}}",
"notification-header-page-connection": "Stranicu <strong>$3</strong>
{{GENDER:$2|povezao je suradnik $1|povezala je suradnica $1}} sa stavkom
({{WBREPONAME}}).",
"unresolved-property-category": "Stranice s nerazjašnjenim stavkama na
wikipodatcima"
}
diff --git
a/extensions/Wikibase/client/includes/Hooks/OtherProjectsSidebarGenerator.php
b/extensions/Wikibase/client/includes/Hooks/OtherProjectsSidebarGenerator.php
index 929e414..346e903 100644
---
a/extensions/Wikibase/client/includes/Hooks/OtherProjectsSidebarGenerator.php
+++
b/extensions/Wikibase/client/includes/Hooks/OtherProjectsSidebarGenerator.php
@@ -35,6 +35,11 @@
private $siteLookup;
/**
+ * @var SidebarLinkBadgeDisplay
+ */
+ private $sidebarLinkBadgeDisplay;
+
+ /**
* @var string[]
*/
private $siteIdsToOutput;
@@ -43,17 +48,20 @@
* @param string $localSiteId
* @param SiteLinkLookup $siteLinkLookup
* @param SiteLookup $siteLookup
+ * @param SidebarLinkBadgeDisplay $sidebarLinkBadgeDisplay
* @param string[] $siteIdsToOutput
*/
public function __construct(
$localSiteId,
SiteLinkLookup $siteLinkLookup,
SiteLookup $siteLookup,
+ SidebarLinkBadgeDisplay $sidebarLinkBadgeDisplay,
array $siteIdsToOutput
) {
$this->localSiteId = $localSiteId;
$this->siteLinkLookup = $siteLinkLookup;
$this->siteLookup = $siteLookup;
+ $this->sidebarLinkBadgeDisplay = $sidebarLinkBadgeDisplay;
$this->siteIdsToOutput = $siteIdsToOutput;
}
@@ -224,6 +232,11 @@
$attributes['hreflang'] = $siteLanguageCode;
}
+ $this->sidebarLinkBadgeDisplay->applyBadgeToLink(
+ $attributes,
+ $this->sidebarLinkBadgeDisplay->getBadgeInfo(
$siteLink->getBadges() )
+ );
+
return $attributes;
}
diff --git
a/extensions/Wikibase/client/includes/Hooks/OtherProjectsSidebarGeneratorFactory.php
b/extensions/Wikibase/client/includes/Hooks/OtherProjectsSidebarGeneratorFactory.php
index 64db769..44aaccd 100644
---
a/extensions/Wikibase/client/includes/Hooks/OtherProjectsSidebarGeneratorFactory.php
+++
b/extensions/Wikibase/client/includes/Hooks/OtherProjectsSidebarGeneratorFactory.php
@@ -33,6 +33,11 @@
private $siteLookup;
/**
+ * @var SidebarLinkBadgeDisplay
+ */
+ private $sidebarLinkBadgeDisplay;
+
+ /**
* @param SettingsArray $settings
* @param SiteLinkLookup $siteLinkLookup
* @param SiteLookup $siteLookup
@@ -40,11 +45,13 @@
public function __construct(
SettingsArray $settings,
SiteLinkLookup $siteLinkLookup,
- SiteLookup $siteLookup
+ SiteLookup $siteLookup,
+ SidebarLinkBadgeDisplay $sidebarLinkBadgeDisplay
) {
$this->settings = $settings;
$this->siteLinkLookup = $siteLinkLookup;
$this->siteLookup = $siteLookup;
+ $this->sidebarLinkBadgeDisplay = $sidebarLinkBadgeDisplay;
}
/**
@@ -66,6 +73,7 @@
$this->settings->getSetting( 'siteGlobalID' ),
$this->siteLinkLookup,
$this->siteLookup,
+ $this->sidebarLinkBadgeDisplay,
$this->settings->getSetting( 'otherProjectsLinks' )
);
}
diff --git
a/extensions/Wikibase/client/includes/Hooks/SidebarLinkBadgeDisplay.php
b/extensions/Wikibase/client/includes/Hooks/SidebarLinkBadgeDisplay.php
index 06568a4..91927ea 100644
--- a/extensions/Wikibase/client/includes/Hooks/SidebarLinkBadgeDisplay.php
+++ b/extensions/Wikibase/client/includes/Hooks/SidebarLinkBadgeDisplay.php
@@ -56,12 +56,20 @@
* string values. These fields are the one outputted by the
getBadgeInfo() function.
*/
public function applyBadgeToLink( array &$sidebarLink, array $badgeInfo
) {
- if ( isset( $sidebarLink['class'] ) ) {
- $sidebarLink['class'] .= ' ' . $badgeInfo['class'];
- } else {
- $sidebarLink['class'] = $badgeInfo['class'];
+ $badgeClass = $badgeInfo['class'];
+ if ( !$badgeClass ) {
+ return;
}
+ if ( isset( $sidebarLink['class'] ) ) {
+ $sidebarLink['class'] .= ' ' . $badgeClass;
+ } else {
+ $sidebarLink['class'] = $badgeClass;
+ }
+
+ if ( !$badgeInfo['label'] ) {
+ wfLogWarning( "Label for badge class $badgeClass could
not be found." );
+ }
$sidebarLink['itemtitle'] = $badgeInfo['label'];
}
diff --git a/extensions/Wikibase/client/includes/WikibaseClient.php
b/extensions/Wikibase/client/includes/WikibaseClient.php
index 7aa307d..e5b676c 100644
--- a/extensions/Wikibase/client/includes/WikibaseClient.php
+++ b/extensions/Wikibase/client/includes/WikibaseClient.php
@@ -241,6 +241,11 @@
private $propertyOrderProvider = null;
/**
+ * @var SidebarLinkBadgeDisplay|null
+ */
+ private $sidebarLinkBadgeDisplay = null;
+
+ /**
* @warning This is for use with bootstrap code in
WikibaseClient.datatypes.php only!
* Program logic should use WikibaseClient::getSnakFormatterFactory()
instead!
*
@@ -894,19 +899,30 @@
}
/**
- * @return LanguageLinkBadgeDisplay
+ * @return SidebarLinkBadgeDisplay
*/
- public function getLanguageLinkBadgeDisplay() {
- $labelDescriptionLookupFactory =
$this->getLanguageFallbackLabelDescriptionLookupFactory();
- $badgeClassNames = $this->settings->getSetting(
'badgeClassNames' );
- $lang = $this->getUserLanguage();
+ public function getSidebarLinkBadgeDisplay() {
+ if ( $this->sidebarLinkBadgeDisplay === null ) {
+ $labelDescriptionLookupFactory =
$this->getLanguageFallbackLabelDescriptionLookupFactory();
+ $badgeClassNames = $this->settings->getSetting(
'badgeClassNames' );
+ $lang = $this->getUserLanguage();
- return new LanguageLinkBadgeDisplay(
- new SidebarLinkBadgeDisplay(
+ $this->sidebarLinkBadgeDisplay = new
SidebarLinkBadgeDisplay(
$labelDescriptionLookupFactory->newLabelDescriptionLookup( $lang ),
is_array( $badgeClassNames ) ? $badgeClassNames
: [],
$lang
- )
+ );
+ }
+
+ return $this->sidebarLinkBadgeDisplay;
+ }
+
+ /**
+ * @return LanguageLinkBadgeDisplay
+ */
+ public function getLanguageLinkBadgeDisplay() {
+ return new LanguageLinkBadgeDisplay(
+ $this->getSidebarLinkBadgeDisplay()
);
}
@@ -1037,7 +1053,8 @@
return new OtherProjectsSidebarGeneratorFactory(
$this->settings,
$this->getStore()->getSiteLinkLookup(),
- $this->siteLookup
+ $this->siteLookup,
+ $this->getSidebarLinkBadgeDisplay()
);
}
diff --git
a/extensions/Wikibase/client/tests/phpunit/includes/Hooks/OtherProjectsSidebarGeneratorFactoryTest.php
b/extensions/Wikibase/client/tests/phpunit/includes/Hooks/OtherProjectsSidebarGeneratorFactoryTest.php
index 35697e2..f5fd95c 100644
---
a/extensions/Wikibase/client/tests/phpunit/includes/Hooks/OtherProjectsSidebarGeneratorFactoryTest.php
+++
b/extensions/Wikibase/client/tests/phpunit/includes/Hooks/OtherProjectsSidebarGeneratorFactoryTest.php
@@ -3,9 +3,12 @@
namespace Wikibase\Client\Tests\Hooks;
use HashSiteStore;
+use Language;
use TestSites;
use Wikibase\Client\Hooks\OtherProjectsSidebarGenerator;
use Wikibase\Client\Hooks\OtherProjectsSidebarGeneratorFactory;
+use Wikibase\Client\Hooks\SidebarLinkBadgeDisplay;
+use Wikibase\DataModel\Services\Lookup\LabelDescriptionLookup;
use Wikibase\SettingsArray;
use Wikibase\Lib\Tests\MockRepository;
@@ -28,11 +31,17 @@
$siteLinkLookup = new MockRepository();
$siteStore = new HashSiteStore( TestSites::getSites() );
+ $sidebarLinkBadgeDisplay = new SidebarLinkBadgeDisplay(
+ $this->getMock( LabelDescriptionLookup::class ),
+ [],
+ new Language( 'en' )
+ );
$factory = new OtherProjectsSidebarGeneratorFactory(
$settings,
$siteLinkLookup,
- $siteStore
+ $siteStore,
+ $sidebarLinkBadgeDisplay
);
$otherProjectSidebarGenerator =
$factory->getOtherProjectsSidebarGenerator();
diff --git
a/extensions/Wikibase/client/tests/phpunit/includes/Hooks/OtherProjectsSidebarGeneratorTest.php
b/extensions/Wikibase/client/tests/phpunit/includes/Hooks/OtherProjectsSidebarGeneratorTest.php
index 7921ade..3ea2a85 100644
---
a/extensions/Wikibase/client/tests/phpunit/includes/Hooks/OtherProjectsSidebarGeneratorTest.php
+++
b/extensions/Wikibase/client/tests/phpunit/includes/Hooks/OtherProjectsSidebarGeneratorTest.php
@@ -4,13 +4,17 @@
use Closure;
use HashSiteStore;
+use Language;
use MediaWikiSite;
use SiteLookup;
use Title;
use TestSites;
use Wikibase\Client\Hooks\OtherProjectsSidebarGenerator;
+use Wikibase\Client\Hooks\SidebarLinkBadgeDisplay;
use Wikibase\DataModel\Entity\ItemId;
+use Wikibase\DataModel\Services\Lookup\LabelDescriptionLookup;
use Wikibase\DataModel\SiteLink;
+use Wikibase\DataModel\Term\Term;
use Wikibase\Lib\Store\SiteLinkLookup;
/**
@@ -28,11 +32,17 @@
/**
* @dataProvider projectLinkSidebarProvider
*/
- public function testBuildProjectLinkSidebar( array $siteIdsToOutput,
array $result ) {
+ public function testBuildProjectLinkSidebar(
+ array $siteIdsToOutput,
+ array $result,
+ SidebarLinkBadgeDisplay $sidebarLinkBadgeDisplay
+ ) {
+
$otherProjectSidebarGenerator = new
OtherProjectsSidebarGenerator(
'enwiki',
$this->getSiteLinkLookup(),
$this->getSiteLookup(),
+ $sidebarLinkBadgeDisplay,
$siteIdsToOutput
);
@@ -43,44 +53,54 @@
}
public function projectLinkSidebarProvider() {
- $wiktionaryLink = array(
+ $wiktionaryLink = [
'msg' => 'wikibase-otherprojects-wiktionary',
'class' => 'wb-otherproject-link
wb-otherproject-wiktionary',
'href' => 'https://en.wiktionary.org/wiki/Nyan_Cat',
'hreflang' => 'en'
- );
- $wikiquoteLink = array(
+ ];
+ $wikiquoteLink = [
'msg' => 'wikibase-otherprojects-wikiquote',
'class' => 'wb-otherproject-link
wb-otherproject-wikiquote',
'href' => 'https://en.wikiquote.org/wiki/Nyan_Cat',
'hreflang' => 'en'
- );
- $wikipediaLink = array(
+ ];
+ $wikipediaLink = [
'msg' => 'wikibase-otherprojects-wikipedia',
- 'class' => 'wb-otherproject-link
wb-otherproject-wikipedia',
+ 'class' => 'wb-otherproject-link
wb-otherproject-wikipedia badge-Q4242 badge-class',
'href' => 'https://en.wikipedia.org/wiki/Nyan_Cat',
- 'hreflang' => 'en'
- );
+ 'hreflang' => 'en',
+ 'itemtitle' => 'Badge Label',
+ ];
- return array(
- array(
- array(),
- array()
- ),
- array(
- array( 'spam', 'spam2' ),
- array()
- ),
- array(
- array( 'enwiktionary' ),
- array( $wiktionaryLink )
- ),
- array(
+ return [
+ [
+ [],
+ [],
+ $this->getSidebarLinkBadgeDisplay()
+ ],
+ [
+ [ 'spam', 'spam2' ],
+ [],
+ $this->getSidebarLinkBadgeDisplay()
+ ],
+ [
+ [ 'enwiktionary' ],
+ [ $wiktionaryLink ],
+ $this->getSidebarLinkBadgeDisplay()
+ ],
+ [
+ [ 'enwiki' ],
+ [ $wikipediaLink ],
+ $this->getSidebarLinkBadgeDisplay()
+ ],
+ [
// Make sure results are sorted alphabetically
by their group names
- array( 'enwiktionary', 'enwiki', 'enwikiquote'
),
- array( $wikipediaLink, $wikiquoteLink,
$wiktionaryLink )
- )
- );
+ [ 'enwiktionary', 'enwiki', 'enwikiquote' ],
+ [ $wikipediaLink, $wikiquoteLink,
$wiktionaryLink ],
+ $this->getSidebarLinkBadgeDisplay()
+ ],
+ ];
}
/**
@@ -91,6 +111,7 @@
'enwiki',
$this->getSiteLinkLookup(),
$this->getSiteLookup(),
+ $this->getSidebarLinkBadgeDisplay(),
$siteIdsToOutput
);
@@ -117,6 +138,7 @@
'enwiki',
$this->getSiteLinkLookup(),
$this->getSiteLookup(),
+ $this->getSidebarLinkBadgeDisplay(),
$siteIdsToOutput
);
@@ -148,15 +170,17 @@
);
$wikipediaLink = array(
'msg' => 'wikibase-otherprojects-wikipedia',
- 'class' => 'wb-otherproject-link
wb-otherproject-wikipedia',
+ 'class' => 'wb-otherproject-link
wb-otherproject-wikipedia badge-Q4242 badge-class',
'href' => 'https://en.wikipedia.org/wiki/Nyan_Cat',
- 'hreflang' => 'en'
+ 'hreflang' => 'en',
+ 'itemtitle' => 'Badge Label',
);
$changedWikipedaLink = array(
'msg' => 'wikibase-otherprojects-wikipedia',
- 'class' => 'wb-otherproject-link
wb-otherproject-wikipedia',
+ 'class' => 'wb-otherproject-link
wb-otherproject-wikipedia badge-Q4242 badge-class',
'href' => 'https://en.wikipedia.org/wiki/Cat',
- 'hreflang' => 'en'
+ 'hreflang' => 'en',
+ 'itemtitle' => 'Badge Label',
);
return array(
@@ -247,6 +271,7 @@
'enwiki',
$lookup,
$this->getSiteLookup(),
+ $this->getSidebarLinkBadgeDisplay(),
array( 'enwiki' )
);
@@ -273,6 +298,7 @@
'enwiki',
$this->getSiteLinkLookup(),
$this->getSiteLookup(),
+ $this->getSidebarLinkBadgeDisplay(),
array( 'unknown-site' )
);
@@ -315,11 +341,27 @@
->with( $Q123 )
->will( $this->returnValue( array(
new SiteLink( 'enwikiquote', 'Nyan Cat' ),
- new SiteLink( 'enwiki', 'Nyan Cat' ),
+ new SiteLink( 'enwiki', 'Nyan Cat', [ new
ItemId( 'Q4242' ) ] ),
new SiteLink( 'enwiktionary', 'Nyan Cat' )
) ) );
return $lookup;
}
+ /**
+ * @return SidebarLinkBadgeDisplay
+ */
+ private function getSidebarLinkBadgeDisplay() {
+ $labelDescriptionLookup = $this->getMock(
LabelDescriptionLookup::class );
+ $labelDescriptionLookup->method( 'getLabel' )
+ ->with( new ItemId( 'Q4242' ) )
+ ->will( $this->returnValue( new Term( 'en', 'Badge
Label' ) ) );
+
+ return new SidebarLinkBadgeDisplay(
+ $labelDescriptionLookup,
+ [ 'Q4242' => 'badge-class' ],
+ new Language( 'en' )
+ );
+ }
+
}
diff --git
a/extensions/Wikibase/client/tests/phpunit/includes/Hooks/ParserOutputUpdateHookHandlersTest.php
b/extensions/Wikibase/client/tests/phpunit/includes/Hooks/ParserOutputUpdateHookHandlersTest.php
index 004d66e..bbb0a6e 100644
---
a/extensions/Wikibase/client/tests/phpunit/includes/Hooks/ParserOutputUpdateHookHandlersTest.php
+++
b/extensions/Wikibase/client/tests/phpunit/includes/Hooks/ParserOutputUpdateHookHandlersTest.php
@@ -199,10 +199,17 @@
SettingsArray $settings,
SiteLinkLookup $siteLinkLookup
) {
+ $sidebarLinkBadgeDisplay = new SidebarLinkBadgeDisplay(
+ $this->getMock( LabelDescriptionLookup::class ),
+ [],
+ new Language( 'en' )
+ );
+
return new OtherProjectsSidebarGeneratorFactory(
$settings,
$siteLinkLookup,
- $this->getSiteLookup()
+ $this->getSiteLookup(),
+ $sidebarLinkBadgeDisplay
);
}
diff --git
a/extensions/Wikibase/client/tests/phpunit/includes/WikibaseClientTest.php
b/extensions/Wikibase/client/tests/phpunit/includes/WikibaseClientTest.php
index 28e500d..607cfbd 100644
--- a/extensions/Wikibase/client/tests/phpunit/includes/WikibaseClientTest.php
+++ b/extensions/Wikibase/client/tests/phpunit/includes/WikibaseClientTest.php
@@ -15,6 +15,7 @@
use Wikibase\Client\Hooks\LanguageLinkBadgeDisplay;
use Wikibase\Client\Hooks\OtherProjectsSidebarGeneratorFactory;
use Wikibase\Client\Hooks\ParserFunctionRegistrant;
+use Wikibase\Client\Hooks\SidebarLinkBadgeDisplay;
use Wikibase\Client\OtherProjectsSitesProvider;
use Wikibase\Client\ParserOutput\ClientParserOutputDataUpdater;
use Wikibase\Client\RepoLinker;
@@ -365,6 +366,11 @@
$this->assertEquals( $this->getRepositoryDefinitions(),
$repositoryDefinitions );
}
+ public function testGetSidebarLinkBadgeDisplay() {
+ $sidebarLinkBadgeDisplay =
$this->getWikibaseClient()->getSidebarLinkBadgeDisplay();
+ $this->assertInstanceOf( SidebarLinkBadgeDisplay::class,
$sidebarLinkBadgeDisplay );
+ }
+
/**
* @return WikibaseClient
*/
diff --git a/extensions/Wikibase/lib/includes/Formatters/MwTimeIsoFormatter.php
b/extensions/Wikibase/lib/includes/Formatters/MwTimeIsoFormatter.php
index cf0127d..f62a509 100644
--- a/extensions/Wikibase/lib/includes/Formatters/MwTimeIsoFormatter.php
+++ b/extensions/Wikibase/lib/includes/Formatters/MwTimeIsoFormatter.php
@@ -104,10 +104,11 @@
* @return string Date format string to be used by Language::sprintfDate
*/
private function getDateFormat( $precision ) {
- $datePreference = 'dmy';
+ $datePreference = 'default';
- if ( !in_array( $datePreference,
$this->language->getDatePreferences() ) ) {
- $datePreference = 'default';
+ $datePreferences = $this->language->getDatePreferences();
+ if ( is_array( $datePreferences ) && in_array( 'dmy',
$datePreferences ) ) {
+ $datePreference = 'dmy';
}
if ( $precision === TimeValue::PRECISION_MONTH ) {
@@ -273,6 +274,8 @@
}
$year = str_pad( ltrim( $year, '0' ), 1, '0', STR_PAD_LEFT );
+ // TODO: The year should be localized via Language::formatNum()
at this point, but currently
+ // can't because not all relevant time parsers unlocalize
numbers.
if ( empty( $msg ) ) {
// TODO: This needs a message.
diff --git a/extensions/Wikibase/lib/includes/Store/Sql/TermSqlIndex.php
b/extensions/Wikibase/lib/includes/Store/Sql/TermSqlIndex.php
index 7b716ee..53bc131 100644
--- a/extensions/Wikibase/lib/includes/Store/Sql/TermSqlIndex.php
+++ b/extensions/Wikibase/lib/includes/Store/Sql/TermSqlIndex.php
@@ -211,16 +211,7 @@
$success = true;
foreach ( $terms as $term ) {
- $success = $dbw->insert(
- $this->tableName,
- array_merge(
- $this->getTermFields( $term ),
- $entityIdentifiers
- ),
- __METHOD__,
- array( 'IGNORE' )
- );
-
+ $success = $this->insertTerm( $entityIdentifiers,
$term, $dbw );
if ( !$success ) {
break;
}
@@ -230,6 +221,43 @@
}
/**
+ * @param array $entityIdentifiers Term table fields identifying an
entity
+ * @param TermIndexEntry $term
+ * @param Database $dbw
+ *
+ * @return bool Success indicator
+ */
+ private function insertTerm( array $entityIdentifiers, TermIndexEntry
$term, Database $dbw ) {
+ $fields = array_merge(
+ $this->getTermFields( $term ),
+ $entityIdentifiers
+ );
+
+ $hasRow = (bool)$dbw->selectField(
+ $this->tableName,
+ '1',
+ // Compare all fields to insert, but term_weight (as it
is a float)
+ array_diff_key( $fields, [ 'term_weight' => 1 ] ),
+ __METHOD__
+ );
+
+ if ( $hasRow ) {
+ wfDebugLog(
+ 'TermSqlIndex-duplicate',
+ 'Attempted to insert duplicate Term into ' .
$this->tableName .
+ ' for ' .
$term->getEntityId()->getSerialization() . ': ' . implode( ', ', $fields )
+ );
+ return true;
+ }
+
+ return $dbw->insert(
+ $this->tableName,
+ $fields,
+ __METHOD__
+ );
+ }
+
+ /**
* @param EntityDocument $entity
*
* @return TermIndexEntry[]
diff --git
a/extensions/Wikibase/lib/tests/phpunit/Formatters/MwTimeIsoFormatterTest.php
b/extensions/Wikibase/lib/tests/phpunit/Formatters/MwTimeIsoFormatterTest.php
index 35107df..c4b93fe 100644
---
a/extensions/Wikibase/lib/tests/phpunit/Formatters/MwTimeIsoFormatterTest.php
+++
b/extensions/Wikibase/lib/tests/phpunit/Formatters/MwTimeIsoFormatterTest.php
@@ -337,6 +337,11 @@
'16 8 2013',
'yue'
),
+ array(
+ '+2013-08-16T00:00:00Z',
TimeValue::PRECISION_DAY,
+ '16 aŭg. 2013',
+ 'eo'
+ ),
// Valid values with day, month and/or year zero
array(
@@ -514,6 +519,13 @@
'10000000',
'de'
),
+
+ // Spanish has no date preferences
+ array(
+ '+2017-01-16T00:00:00Z',
TimeValue::PRECISION_DAY,
+ '16 ene 2017',
+ 'es'
+ ),
);
$argLists = array();
@@ -536,6 +548,7 @@
'ar', //replaces all numbers and separators
'bo', //replaces only numbers
'de', //switches separators
+ 'es', //no date preferences
'la', //defaults to genitive month names
'or', //replaces all numbers and separators
);
diff --git
a/extensions/Wikibase/lib/tests/phpunit/Store/Sql/TermSqlIndexTest.php
b/extensions/Wikibase/lib/tests/phpunit/Store/Sql/TermSqlIndexTest.php
index a95315e..7586901 100644
--- a/extensions/Wikibase/lib/tests/phpunit/Store/Sql/TermSqlIndexTest.php
+++ b/extensions/Wikibase/lib/tests/phpunit/Store/Sql/TermSqlIndexTest.php
@@ -21,6 +21,7 @@
use Wikibase\Lib\Store\Sql\TermSqlIndex;
use Wikibase\WikibaseSettings;
use Wikimedia\Assert\ParameterAssertionException;
+use Wikimedia\TestingAccessWrapper;
/**
* @covers Wikibase\Lib\Store\Sql\TermSqlIndex
@@ -634,6 +635,43 @@
$this->assertSame( 'Q1112362', $row->term_full_entity_id );
}
+ public function testInsertTerms_duplicate() {
+ $item = new Item( new ItemId( 'Q1112362' ) );
+ $termEs = new TermIndexEntry( [
+ 'entityId' => $item->getId(),
+ 'termText' => 'Spanish',
+ 'termLanguage' => 'es',
+ 'termType' => 'description'
+ ] );
+ $termDe = new TermIndexEntry( [
+ 'entityId' => $item->getId(),
+ 'termText' => 'German',
+ 'termLanguage' => 'de',
+ 'termType' => 'description'
+ ] );
+
+ $termIndex = $this->getTermIndex();
+ $termIndex->setReadFullEntityIdColumn( true );
+ $termIndex = TestingAccessWrapper::newFromObject( $termIndex );
+
+ $this->assertTrue(
+ $termIndex->insertTerms(
+ $item,
+ [ $termEs, $termDe, $termEs ],
+ $termIndex->getConnection( DB_MASTER )
+ )
+ );
+
+ $rowCount = $this->db->selectRowCount(
+ 'wb_terms',
+ null,
+ [ 'term_entity_id' => '1112362', 'term_entity_type' =>
'item' ],
+ __METHOD__
+ );
+
+ $this->assertSame( 2, $rowCount );
+ }
+
public function testDeleteTermsForEntity_withReadFullEntityId() {
$index = $this->getTermIndex();
$index->clear();
diff --git a/extensions/Wikibase/repo/i18n/pt.json
b/extensions/Wikibase/repo/i18n/pt.json
index 0cb5180..071e34e 100644
--- a/extensions/Wikibase/repo/i18n/pt.json
+++ b/extensions/Wikibase/repo/i18n/pt.json
@@ -251,7 +251,7 @@
"wikibase-dispatchstats-pos": "Posição",
"wikibase-dispatchstats-lag-num": "Pendente",
"wikibase-dispatchstats-lag-time": "Atraso",
- "wikibase-dispatchstats-touched": "Último contato",
+ "wikibase-dispatchstats-touched": "Último contacto",
"wikibase-dispatchstats-large-lag": "(muito grande)",
"wikibase-dispatchstats-freshest": "Mais recente",
"wikibase-dispatchstats-stalest": "Mais antigo",
@@ -274,7 +274,6 @@
"wikibase-entitieswithoutlabel-legend": "Obter a lista de entidades sem
rótulo",
"wikibase-entitieswithoutlabel-label-language": "Código de língua:",
"wikibase-entitieswithoutlabel-label-type": "Tipo:",
- "wikibase-entitieswithoutlabel-label-alltypes": "todas",
"wikibase-entitieswithoutlabel-submit": "Procurar",
"wikibase-entitieswithoutlabel-invalid-language": "\"$1\" não é um
código de língua válido.",
"wikibase-entitieswithoutlabel-invalid-type": "\"$1\" não é um tipo de
entidade válido.",
diff --git a/vendor/composer/autoload_classmap.php
b/vendor/composer/autoload_classmap.php
index 37b617c..f8c574b 100644
--- a/vendor/composer/autoload_classmap.php
+++ b/vendor/composer/autoload_classmap.php
@@ -270,7 +270,9 @@
'WikibaseQuality\\ConstraintReport\\ConstraintCheck\\ConstraintChecker' =>
$baseDir .
'/extensions/Constraints/includes/ConstraintCheck/ConstraintChecker.php',
'WikibaseQuality\\ConstraintReport\\ConstraintCheck\\DelegatingConstraintChecker'
=> $baseDir .
'/extensions/Constraints/includes/ConstraintCheck/DelegatingConstraintChecker.php',
'WikibaseQuality\\ConstraintReport\\ConstraintCheck\\Helper\\ConnectionCheckerHelper'
=> $baseDir .
'/extensions/Constraints/includes/ConstraintCheck/Helper/ConnectionCheckerHelper.php',
+
'WikibaseQuality\\ConstraintReport\\ConstraintCheck\\Helper\\ConstraintParameterException'
=> $baseDir .
'/extensions/Constraints/includes/ConstraintCheck/Helper/ConstraintParameterException.php',
'WikibaseQuality\\ConstraintReport\\ConstraintCheck\\Helper\\ConstraintParameterParser'
=> $baseDir .
'/extensions/Constraints/includes/ConstraintCheck/Helper/ConstraintParameterParser.php',
+
'WikibaseQuality\\ConstraintReport\\ConstraintCheck\\Helper\\ConstraintStatementParameterParser'
=> $baseDir .
'/extensions/Constraints/includes/ConstraintCheck/Helper/ConstraintStatementParameterParser.php',
'WikibaseQuality\\ConstraintReport\\ConstraintCheck\\Helper\\RangeCheckerHelper'
=> $baseDir .
'/extensions/Constraints/includes/ConstraintCheck/Helper/RangeCheckerHelper.php',
'WikibaseQuality\\ConstraintReport\\ConstraintCheck\\Helper\\TypeCheckerHelper'
=> $baseDir .
'/extensions/Constraints/includes/ConstraintCheck/Helper/TypeCheckerHelper.php',
'WikibaseQuality\\ConstraintReport\\ConstraintCheck\\Helper\\ValueCountCheckerHelper'
=> $baseDir .
'/extensions/Constraints/includes/ConstraintCheck/Helper/ValueCountCheckerHelper.php',
diff --git a/vendor/composer/autoload_static.php
b/vendor/composer/autoload_static.php
index 8d5da11..d6482b7 100644
--- a/vendor/composer/autoload_static.php
+++ b/vendor/composer/autoload_static.php
@@ -598,7 +598,9 @@
'WikibaseQuality\\ConstraintReport\\ConstraintCheck\\ConstraintChecker' =>
__DIR__ . '/../..' .
'/extensions/Constraints/includes/ConstraintCheck/ConstraintChecker.php',
'WikibaseQuality\\ConstraintReport\\ConstraintCheck\\DelegatingConstraintChecker'
=> __DIR__ . '/../..' .
'/extensions/Constraints/includes/ConstraintCheck/DelegatingConstraintChecker.php',
'WikibaseQuality\\ConstraintReport\\ConstraintCheck\\Helper\\ConnectionCheckerHelper'
=> __DIR__ . '/../..' .
'/extensions/Constraints/includes/ConstraintCheck/Helper/ConnectionCheckerHelper.php',
+
'WikibaseQuality\\ConstraintReport\\ConstraintCheck\\Helper\\ConstraintParameterException'
=> __DIR__ . '/../..' .
'/extensions/Constraints/includes/ConstraintCheck/Helper/ConstraintParameterException.php',
'WikibaseQuality\\ConstraintReport\\ConstraintCheck\\Helper\\ConstraintParameterParser'
=> __DIR__ . '/../..' .
'/extensions/Constraints/includes/ConstraintCheck/Helper/ConstraintParameterParser.php',
+
'WikibaseQuality\\ConstraintReport\\ConstraintCheck\\Helper\\ConstraintStatementParameterParser'
=> __DIR__ . '/../..' .
'/extensions/Constraints/includes/ConstraintCheck/Helper/ConstraintStatementParameterParser.php',
'WikibaseQuality\\ConstraintReport\\ConstraintCheck\\Helper\\RangeCheckerHelper'
=> __DIR__ . '/../..' .
'/extensions/Constraints/includes/ConstraintCheck/Helper/RangeCheckerHelper.php',
'WikibaseQuality\\ConstraintReport\\ConstraintCheck\\Helper\\TypeCheckerHelper'
=> __DIR__ . '/../..' .
'/extensions/Constraints/includes/ConstraintCheck/Helper/TypeCheckerHelper.php',
'WikibaseQuality\\ConstraintReport\\ConstraintCheck\\Helper\\ValueCountCheckerHelper'
=> __DIR__ . '/../..' .
'/extensions/Constraints/includes/ConstraintCheck/Helper/ValueCountCheckerHelper.php',
diff --git a/vendor/composer/installed.json b/vendor/composer/installed.json
index f17965b..2d0f649 100644
--- a/vendor/composer/installed.json
+++ b/vendor/composer/installed.json
@@ -1376,12 +1376,12 @@
"source": {
"type": "git",
"url":
"https://github.com/wikimedia/mediawiki-extensions-Wikibase.git",
- "reference": "1bb3f48e85953e89f54a5a997b8a356e2f384285"
+ "reference": "3ad89acdac353323018a29dc32ae76aaa7866e55"
},
"dist": {
"type": "zip",
- "url":
"https://api.github.com/repos/wikimedia/mediawiki-extensions-Wikibase/zipball/1bb3f48e85953e89f54a5a997b8a356e2f384285",
- "reference": "1bb3f48e85953e89f54a5a997b8a356e2f384285",
+ "url":
"https://api.github.com/repos/wikimedia/mediawiki-extensions-Wikibase/zipball/3ad89acdac353323018a29dc32ae76aaa7866e55",
+ "reference": "3ad89acdac353323018a29dc32ae76aaa7866e55",
"shasum": ""
},
"require": {
@@ -1414,7 +1414,7 @@
"jakub-onderka/php-parallel-lint": ">=0.3 <0.10",
"wikibase/wikibase-codesniffer": "^0.1.0"
},
- "time": "2017-06-07 13:35:32",
+ "time": "2017-06-09 08:00:16",
"type": "mediawiki-extension",
"installation-source": "dist",
"autoload": {
@@ -1712,7 +1712,7 @@
"source": {
"type": "git",
"url":
"https://gerrit.wikimedia.org/r/mediawiki/extensions/PropertySuggester",
- "reference": "154f36bdab44696678da0a5fad13d13c856a1977"
+ "reference": "81a4c1f16488baac1475f36b692ba5135e54d4dc"
},
"require": {
"php": ">=5.5.9",
@@ -1727,7 +1727,7 @@
"wikibase/wikibase-codesniffer": "^0.1.0",
"wikimedia/testing-access-wrapper": "~1.0"
},
- "time": "2017-06-07 11:02:22",
+ "time": "2017-06-08 21:07:10",
"type": "mediawiki-extension",
"installation-source": "source",
"autoload": {
@@ -1839,7 +1839,7 @@
"source": {
"type": "git",
"url":
"https://gerrit.wikimedia.org/r/mediawiki/extensions/WikibaseQualityConstraints",
- "reference": "1ca666bcf75650f02623da140594b50430af1ef8"
+ "reference": "ec938fd93421b4c552c41f94282adde8088e03b8"
},
"require": {
"php": ">=5.5.9",
@@ -1855,7 +1855,7 @@
"satooshi/php-coveralls": "master-dev",
"wikibase/wikibase-codesniffer": "^0.1.0"
},
- "time": "2017-06-07 12:16:47",
+ "time": "2017-06-08 21:17:20",
"type": "mediawiki-extension",
"installation-source": "source",
"autoload": {
--
To view, visit https://gerrit.wikimedia.org/r/357986
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: Ic1ceb3c8960f1124b1a9b4e523bfd3e34ca50b23
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