WikidataBuilder has uploaded a new change for review. (
https://gerrit.wikimedia.org/r/381526 )
Change subject: New Wikidata Build - 2017-09-30T10:00:02+0000
......................................................................
New Wikidata Build - 2017-09-30T10:00:02+0000
Change-Id: Ia73eb3a326437b3bd906acb53297c8090e395c3c
---
M Wikidata.localisation.php
M Wikidata.php
M composer.lock
M extensions/Constraints/README.md
M extensions/Constraints/extension.json
M extensions/Constraints/i18n/en.json
M extensions/Constraints/i18n/qqq.json
A extensions/Constraints/includes/ConstraintCheck/Checker/ValueOnlyChecker.php
M
extensions/Constraints/includes/ConstraintCheck/DelegatingConstraintChecker.php
M extensions/Constraints/includes/ConstraintReportFactory.php
M extensions/Constraints/tests/phpunit/Api/CheckConstraintsTest.php
A extensions/Constraints/tests/phpunit/Checker/ValueOnlyCheckerTest.php
M extensions/Wikibase/client/WikibaseClient.php
M extensions/Wikibase/lib/includes/Formatters/EntityIdHtmlLinkFormatter.php
M vendor/composer/autoload_classmap.php
M vendor/composer/autoload_static.php
M vendor/composer/installed.json
17 files changed, 410 insertions(+), 78 deletions(-)
git pull ssh://gerrit.wikimedia.org:29418/mediawiki/extensions/Wikidata
refs/changes/26/381526/1
diff --git a/Wikidata.localisation.php b/Wikidata.localisation.php
index e1cad1c..e166629 100644
--- a/Wikidata.localisation.php
+++ b/Wikidata.localisation.php
@@ -4,10 +4,6 @@
die( 'Not an entry point.' );
}
-// no magic, use wmf configs instead to control which entry points to load
-$wgEnableWikibaseRepo = false;
-$wgEnableWikibaseClient = false;
-
$wgWikidataBaseDir = $IP;
if ( file_exists( __DIR__ . '/vendor/autoload.php' ) ) {
diff --git a/Wikidata.php b/Wikidata.php
index dcb4143..b96b27c 100755
--- a/Wikidata.php
+++ b/Wikidata.php
@@ -12,10 +12,6 @@
$wmgUseArticlePlaceholder = true;
}
-// no magic, use wmf configs instead to control which entry points to load
-$wgEnableWikibaseRepo = false;
-$wgEnableWikibaseClient = false;
-
$wgWikidataBaseDir = $IP;
if ( file_exists( __DIR__ . '/vendor/autoload.php' ) ) {
diff --git a/composer.lock b/composer.lock
index 4612f5e..79c8573 100644
--- a/composer.lock
+++ b/composer.lock
@@ -977,7 +977,7 @@
"source": {
"type": "git",
"url":
"https://gerrit.wikimedia.org/r/mediawiki/extensions/WikibaseQualityConstraints",
- "reference": "0a46d56c378cd40d15bc4e0e479f1588261648b1"
+ "reference": "0d4d91f03dafd535e231900ae510c92634682b3e"
},
"require": {
"php": ">=5.5.9",
@@ -1037,7 +1037,7 @@
"support": {
"issues":
"https://phabricator.wikimedia.org/project/profile/1202/"
},
- "time": "2017-09-29 09:37:36"
+ "time": "2017-09-29 10:04:34"
},
{
"name": "wikibase/data-model",
@@ -1548,12 +1548,12 @@
"source": {
"type": "git",
"url":
"https://github.com/wikimedia/mediawiki-extensions-Wikibase.git",
- "reference": "79f95b564f54ae5499e665a75ffa24860abb9f4b"
+ "reference": "151dde0e4154467a0195a468ef2468daed1c88ee"
},
"dist": {
"type": "zip",
- "url":
"https://api.github.com/repos/wikimedia/mediawiki-extensions-Wikibase/zipball/79f95b564f54ae5499e665a75ffa24860abb9f4b",
- "reference": "79f95b564f54ae5499e665a75ffa24860abb9f4b",
+ "url":
"https://api.github.com/repos/wikimedia/mediawiki-extensions-Wikibase/zipball/151dde0e4154467a0195a468ef2468daed1c88ee",
+ "reference": "151dde0e4154467a0195a468ef2468daed1c88ee",
"shasum": ""
},
"require": {
@@ -1631,7 +1631,7 @@
"wikibaserepo",
"wikidata"
],
- "time": "2017-09-29 09:36:10"
+ "time": "2017-09-29 15:47:38"
},
{
"name": "wikibase/wikimedia-badges",
diff --git a/extensions/Constraints/README.md b/extensions/Constraints/README.md
index 5ff3655..099b55a 100644
--- a/extensions/Constraints/README.md
+++ b/extensions/Constraints/README.md
@@ -146,3 +146,94 @@
This runs the tests without coverage report
and is therefore much faster.
+
+### Adding a new constraint type
+
+To add a new constraint type, the following steps are necessary:
+
+* Define the constraint checker class.
+ * It should be defined in a new file in `includes/ConstraintCheck/Checker/`,
+ named after the class name.
+ It should be in the
`WikibaseQuality\ConstraintReport\ConstraintCheck\Checker` namespace.
+ * The class name should follow the constraint type name (in English), ending
in “Checker”.
+ * The class must implement the `ConstraintChecker` interface.
+ * It should have at least the following class-level documentation comment:
+ ```php
+ /**
+ * @package WikibaseQuality\ConstraintReport\ConstraintCheck\Checker
+ * @author YOUR NAME HERE
+ * @license GNU GPL v2+
+ */
+ ```
+ * Any services you need (`Config`, `EntityLookup`, …) should be injected as
constructor parameters.
+ * If the constraint has parameters,
+ add support for parsing them to `ConstraintParameterParser`
+ (add a config setting for the associated property in `extension.json`
+ and a method to parse the parameter in `ConstraintParameterParser`),
+ and then add tests for them in `ConstraintParameterParserTest`.
+ This should be done in a separate commit.
+* Define new messages (at least a violation message for the constraint type).
+ * Define the message in `i18n/en.json`.
+ A violation message should have a key like
`wbqc-violation-message-constraintType`.
+ * Document the message in `i18n/qqq.json`.
+ Use the same message key,
+ and insert the documentation in the same location where you also added the
message in `en.json`
+ (that is, `en.json` and `qqq.json` should contain message keys in the same
order).
+* Add a configuration setting for the constraint type item ID.
+ * Configuration settings are defined in `extension.json`,
+ as members of the `config` object.
+ * It should be added right after the current last `…ConstraintId` entry.
+ * It should be named after the constraint type item’s English label,
+ following the pattern `WBQualityConstraints___ConstraintId`.
+ * The default value should be the item ID on Wikidata,
+ so that no extra configuration is required for Wikidata
+ and importing the constraint type item (see “Data import” section) works.
+ * The first part of the description can be copied from similar settings,
+ the rest should contain a short description of the constraint type.
+ * The ID can always be public (`"public": true`).
+* Configure the constraint type checker in `ConstraintReportFactory`.
+ * Add an array entry like
+ ```php
+ $this->config->get( 'WBQualityConstraints___ConstraintId' )
+ => new ___Checker(
+ // injected services
+ ),
+ ```
+ at the end of the `getConstraintCheckerMap()` function.
+* Add tests for the new constraint checker.
+ * The test class name should be the same as the checker class name,
+ with an additional suffix `Test` (i. e., `…CheckerTest`).
+ * The test class should be placed somewhere in `tests/phpunit/Checker/`,
+ either in the most suitable subdirectory
+ or directly in that directory if none of the subdirectories are suitable.
+ (The division into subdirectories there is dubious anyways,
+ and we may get rid of it in the future.)
+ * It should have at least the following class-level documentation comment:
+ ```php
+ /**
+ * @covers
\WikibaseQuality\ConstraintReport\ConstraintCheck\Checker\___Checker
+ *
+ * @group WikibaseQualityConstraints
+ *
+ * @uses
\WikibaseQuality\ConstraintReport\ConstraintCheck\Result\CheckResult
+ *
+ * @author YOUR NAME HERE
+ * @license GNU GPL v2+
+ */
+ ```
+ * It should have at least one test for compliance with a constraint,
+ one test for a constraint violation,
+ one test for behavior on a deprecated statement,
+ and one test for the `checkConstraintParameters` method.
+ * Use the `ResultAssertions` trait’s methods to check constraint check
results.
+ * Use the `NewItem` and `NewStatement` builders to construct test data.
+ (You might see `JsonFileEntityLookup` and separate JSON files used in some
existing tests,
+ but that’s a lot less readable.)
+ * If the checker uses a `Config`, use the `DefaultConfig` trait.
+ * If the constraint has parameters,
+ add methods for them to the `ConstraintParameterns` trait and use it in
the tests.
+ * You can copy+paste a `getConstraintMock` function from one of the existing
tests,
+ adjusting the `getConstraintTypeItemId` mocked return value.
+ (Hopefully we’ll improve this in the future.)
+
+An example commit that performs all of these steps is [Change
Id45d80e7a0](https://gerrit.wikimedia.org/r/381005).
diff --git a/extensions/Constraints/extension.json
b/extensions/Constraints/extension.json
index f48a3f0..e550c7a 100644
--- a/extensions/Constraints/extension.json
+++ b/extensions/Constraints/extension.json
@@ -121,6 +121,16 @@
"description": "Whether to use the new API output
format, based on the Wikibase entity JSON format, which can accommodate
constraint results on qualifiers and references.",
"public": true
},
+ "WBQualityConstraintsCheckQualifiers": {
+ "value": false,
+ "description": "Whether to check constraints on
qualifiers. Requires the new API output format (otherwise ignored).",
+ "public": true
+ },
+ "WBQualityConstraintsCheckReferences": {
+ "value": false,
+ "description": "Whether to check constraints on
references. Requires the new API output format (otherwise ignored).",
+ "public": true
+ },
"WBQualityConstraintsSparqlEndpoint": {
"value": "",
"description": "The URL of the SPARQL endpoint. Should
accept the URL parameters 'query', 'format' and 'maxQueryTimeMillis'. Set to ''
(empty string, default) to disable SPARQL functionality.",
@@ -269,6 +279,11 @@
"description": "The item ID of the 'format constraint'
item, which, when used in a 'property constraint' statement on a property,
indicates that the value of a given statement should conform to a given
pattern.",
"public": true
},
+ "WBQualityConstraintsUsedForValuesOnlyConstraintId": {
+ "value": "Q21528958",
+ "description": "The item ID of the 'used for values
only constraint' item, which, when used in a 'property constraint' statement on
a property, indicates that the property should only be used for the main value
of a statement, not for qualifiers or references.",
+ "public": true
+ },
"WBQualityConstraintsClassId": {
"value": "P2308",
"description": "The property ID of the 'relation'
property (data type: item), which specifies the class/type of a 'type' or
'value type' constraint.",
diff --git a/extensions/Constraints/i18n/en.json
b/extensions/Constraints/i18n/en.json
index 2b9c2cf..265731a 100644
--- a/extensions/Constraints/i18n/en.json
+++ b/extensions/Constraints/i18n/en.json
@@ -124,6 +124,7 @@
"wbqc-violation-message-valueType-subclass": "Values of $1 statements
should be subclasses of {{PLURAL:$3|1=$5|2=$5 or $6|one of the following
classes}} (or of {{PLURAL:$3|1=a subclass of it|2=a subclass of them|one of
their subclasses}}), but $2 currently {{PLURAL:$3|1=isn't.|2=isn't.|isn't:
$4}}",
"wbqc-violation-message-target-required-claim": "$1 should have
{{PLURAL:$3|0=a statement $2.|1=a statement $2 $5.|a statement for $2 with one
of the following values:$4}}",
"wbqc-violation-message-unique-value": "This property's value must not
be present on any other item, but is also present on {{PLURAL:$1|1=$3.|2=$3 and
$4.|the following items: $2}}",
+ "wbqc-violation-message-valueOnly": "This property should only be used
for the main value of a statement, not for qualifiers or references.",
"wbqc-exception-message": "This entity is a known exception for this
constraint and has been marked as such."
}
diff --git a/extensions/Constraints/i18n/qqq.json
b/extensions/Constraints/i18n/qqq.json
index f31c8b1..3d169ce 100644
--- a/extensions/Constraints/i18n/qqq.json
+++ b/extensions/Constraints/i18n/qqq.json
@@ -120,5 +120,6 @@
"wbqc-violation-message-valueType-subclass": "Message for a violation
of the “Value type” constraint, when the value of a statement should have be a
subclass of a certain type but isn't. $1 is the property of the statement, $2
is the value of the statement, $3 is the number of classes, $4 is an HTML list
of all classes, and $5, $6 etc. are the individual
classes.\n{{Related|wbqc-violation-message-valueType-instance}}",
"wbqc-violation-message-target-required-claim": "Message for a
violation of the “Target required claim” constraint, when the target entity of
a statement is missing an expected statement. Parameters:\n* $1 is the subject
entity of the missing statement, i. e. the target entity of the statement that
has the constraint.\n* $2 is the property of the missing statement.\n* $3 is
the number of values permitted for the missing statement (or 0, in which case
the constraint only specifies that there should be a statement but not the
values it should have).\n* $4 is an HTML list of all values permitted for the
missing statement.\n* $5, $6 etc. are the individual values permitted for the
missing statement.\n{{Related|wbqc-violation-message-item}}",
"wbqc-violation-message-unique-value": "Message for violation of the
Unique Value constraint, when other items are found. Parameters:\n* $1 is the
number of other items with the same value.\n* $2 is an HTML list of all other
items found with the same value.\n* $3, $4 etc. are the individual other items
with the same value.",
+ "wbqc-violation-message-valueOnly": "Message for a violation of the
“used for values only” constraint, when a property intended for the main value
only was used in a qualifier or reference.",
"wbqc-exception-message": "Message for a constraint check result on an
entity that has been marked as an exception to the constraint. This message
only appears on [[Special:ConstraintReport]]; the gadget does not show
exception reports."
}
diff --git
a/extensions/Constraints/includes/ConstraintCheck/Checker/ValueOnlyChecker.php
b/extensions/Constraints/includes/ConstraintCheck/Checker/ValueOnlyChecker.php
new file mode 100644
index 0000000..03c8adf
--- /dev/null
+++
b/extensions/Constraints/includes/ConstraintCheck/Checker/ValueOnlyChecker.php
@@ -0,0 +1,31 @@
+<?php
+
+namespace WikibaseQuality\ConstraintReport\ConstraintCheck\Checker;
+
+use WikibaseQuality\ConstraintReport\Constraint;
+use WikibaseQuality\ConstraintReport\ConstraintCheck\ConstraintChecker;
+use WikibaseQuality\ConstraintReport\ConstraintCheck\Context\Context;
+use WikibaseQuality\ConstraintReport\ConstraintCheck\Result\CheckResult;
+
+/**
+ * @package WikibaseQuality\ConstraintReport\ConstraintCheck\Checker
+ * @author Lucas Werkmeister
+ * @license GNU GPL v2+
+ */
+class ValueOnlyChecker implements ConstraintChecker {
+
+ public function checkConstraint( Context $context, Constraint
$constraint ) {
+ if ( $context->getType() === Context::TYPE_STATEMENT ) {
+ return new CheckResult( $context, $constraint, [],
CheckResult::STATUS_COMPLIANCE, '' );
+ } else {
+ $message = wfMessage(
'wbqc-violation-message-valueOnly' )->escaped();
+ return new CheckResult( $context, $constraint, [],
CheckResult::STATUS_VIOLATION, $message );
+ }
+ }
+
+ public function checkConstraintParameters( Constraint $constraint ) {
+ // no parameters
+ return [];
+ }
+
+}
diff --git
a/extensions/Constraints/includes/ConstraintCheck/DelegatingConstraintChecker.php
b/extensions/Constraints/includes/ConstraintCheck/DelegatingConstraintChecker.php
index 7514830..887fc1c 100644
---
a/extensions/Constraints/includes/ConstraintCheck/DelegatingConstraintChecker.php
+++
b/extensions/Constraints/includes/ConstraintCheck/DelegatingConstraintChecker.php
@@ -13,6 +13,8 @@
use Wikibase\DataModel\Statement\StatementListProvider;
use WikibaseQuality\ConstraintReport\ConstraintCheck\Context\Context;
use WikibaseQuality\ConstraintReport\ConstraintCheck\Context\MainSnakContext;
+use WikibaseQuality\ConstraintReport\ConstraintCheck\Context\QualifierContext;
+use WikibaseQuality\ConstraintReport\ConstraintCheck\Context\ReferenceContext;
use WikibaseQuality\ConstraintReport\ConstraintCheck\Context\StatementContext;
use
WikibaseQuality\ConstraintReport\ConstraintCheck\Helper\ConstraintParameterException;
use
WikibaseQuality\ConstraintReport\ConstraintCheck\Helper\ConstraintParameterParser;
@@ -71,6 +73,16 @@
private $apiV2;
/**
+ * @var bool
+ */
+ private $checkQualifiers;
+
+ /**
+ * @var bool
+ */
+ private $checkReferences;
+
+ /**
* @param EntityLookup $lookup
* @param ConstraintChecker[] $checkerMap
* @param ConstraintLookup $constraintRepository
@@ -78,6 +90,8 @@
* @param StatementGuidParser $statementGuidParser
* @param LoggingHelper $loggingHelper
* @param bool $apiV2 whether to use the new API output format
+ * @param bool $checkQualifiers whether to check qualifiers
+ * @param bool $checkReferences whether to check references
*/
public function __construct(
EntityLookup $lookup,
@@ -86,7 +100,9 @@
ConstraintParameterParser $constraintParameterParser,
StatementGuidParser $statementGuidParser,
LoggingHelper $loggingHelper,
- $apiV2
+ $apiV2,
+ $checkQualifiers,
+ $checkReferences
) {
$this->entityLookup = $lookup;
$this->checkerMap = $checkerMap;
@@ -95,6 +111,8 @@
$this->statementGuidParser = $statementGuidParser;
$this->loggingHelper = $loggingHelper;
$this->apiV2 = $apiV2;
+ $this->checkQualifiers = $apiV2 && $checkQualifiers;
+ $this->checkReferences = $apiV2 && $checkReferences;
}
/**
@@ -254,9 +272,33 @@
private function checkStatement( EntityDocument $entity, Statement
$statement, $constraintIds = null ) {
$result = [];
- $constraints =
$this->constraintLookup->queryConstraintsForProperty(
- $statement->getPropertyId()
- );
+ $result = array_merge( $result,
+ $this->checkConstraintsForMainSnak( $entity,
$statement, $constraintIds ) );
+
+ if ( $this->checkQualifiers ) {
+ $result = array_merge( $result,
+ $this->checkConstraintsForQualifiers( $entity,
$statement, $constraintIds ) );
+ }
+
+ if ( $this->checkReferences ) {
+ $result = array_merge( $result,
+ $this->checkConstraintsForReferences( $entity,
$statement, $constraintIds ) );
+ }
+
+ return $result;
+ }
+
+ /**
+ * Get the constraints to actually check for a given property ID.
+ * If $constraintIds is not null, only check constraints with those
constraint IDs,
+ * otherwise check all constraints for that property.
+ *
+ * @param PropertyId $propertyId
+ * @param string[]|null $constraintIds
+ * @return Constraint[]
+ */
+ private function getConstraintsToUse( PropertyId $propertyId, array
$constraintIds = null ) {
+ $constraints =
$this->constraintLookup->queryConstraintsForProperty( $propertyId );
if ( $constraintIds !== null ) {
$constraintsToUse = [];
foreach ( $constraints as $constraint ) {
@@ -264,30 +306,31 @@
$constraintsToUse[] = $constraint;
}
}
+ return $constraintsToUse;
} else {
- $constraintsToUse = $constraints;
+ return $constraints;
}
- $result = array_merge(
- $result,
- $this->checkConstraintsForStatementOnEntity(
$constraintsToUse, $entity, $statement )
- );
-
- return $result;
}
/**
- * @param Constraint[] $constraints
- * @param EntityDocument|StatementListProvider $entity
+ * @param EntityDocument $entity
* @param Statement $statement
- *
+ * @param string[]|null $constraintIds list of constraints to check (if
null: all constraints)
* @return CheckResult[]
*/
- private function checkConstraintsForStatementOnEntity( array
$constraints, EntityDocument $entity, $statement ) {
- $entityId = $entity->getId();
+ private function checkConstraintsForMainSnak(
+ EntityDocument $entity,
+ Statement $statement,
+ array $constraintIds = null
+ ) {
$result = [];
$context = $this->apiV2 ?
new MainSnakContext( $entity, $statement ) :
new StatementContext( $entity, $statement );
+ $constraints = $this->getConstraintsToUse(
+ $statement->getPropertyId(),
+ $constraintIds
+ );
foreach ( $constraints as $constraint ) {
$parameters = $constraint->getConstraintParameters();
@@ -298,13 +341,74 @@
continue;
}
- if ( in_array( $entityId, $exceptions ) ) {
+ if ( in_array( $entity->getId(), $exceptions ) ) {
$message = wfMessage( 'wbqc-exception-message'
)->escaped();
$result[] = new CheckResult( $context,
$constraint, [], CheckResult::STATUS_EXCEPTION, $message );
continue;
}
- $result[ ] = $this->getCheckResultFor( $context,
$constraint );
+ $result[] = $this->getCheckResultFor( $context,
$constraint );
+ }
+
+ return $result;
+ }
+
+ /**
+ * @param EntityDocument $entity
+ * @param Statement $statement
+ * @param string[]|null $constraintIds list of constraints to check (if
null: all constraints)
+ * @return CheckResult[]
+ */
+ private function checkConstraintsForQualifiers(
+ EntityDocument $entity,
+ Statement $statement,
+ array $constraintIds = null
+ ) {
+ $result = [];
+
+ foreach ( $statement->getQualifiers() as $qualifier ) {
+ $qualifierContext = new QualifierContext( $entity,
$statement, $qualifier );
+ $qualifierConstraints = $this->getConstraintsToUse(
+ $qualifierContext->getSnak()->getPropertyId(),
+ $constraintIds
+ );
+ foreach ( $qualifierConstraints as $qualifierConstraint
) {
+ $result[] = $this->getCheckResultFor(
$qualifierContext, $qualifierConstraint );
+ }
+ }
+
+ return $result;
+ }
+
+ /**
+ * @param EntityDocument $entity
+ * @param Statement $statement
+ * @param string[]|null $constraintIds list of constraints to check (if
null: all constraints)
+ * @return CheckResult[]
+ */
+ private function checkConstraintsForReferences(
+ EntityDocument $entity,
+ Statement $statement,
+ array $constraintIds = null
+ ) {
+ $result = [];
+
+ foreach ( $statement->getReferences() as $reference ) {
+ foreach ( $reference->getSnaks() as $snak ) {
+ $referenceContext = new ReferenceContext(
+ $entity, $statement, $reference, $snak
+ );
+ $referenceConstraints =
$this->getConstraintsToUse(
+
$referenceContext->getSnak()->getPropertyId(),
+ $constraintIds
+ );
+ foreach ( $referenceConstraints as
$referenceConstraint ) {
+ $result[] = $this->getCheckResultFor(
+ $referenceContext,
+ $referenceConstraint
+ );
+ }
+ }
}
return $result;
diff --git a/extensions/Constraints/includes/ConstraintReportFactory.php
b/extensions/Constraints/includes/ConstraintReportFactory.php
index dfe82d5..7750506 100644
--- a/extensions/Constraints/includes/ConstraintReportFactory.php
+++ b/extensions/Constraints/includes/ConstraintReportFactory.php
@@ -35,6 +35,7 @@
use
WikibaseQuality\ConstraintReport\ConstraintCheck\Checker\SingleValueChecker;
use WikibaseQuality\ConstraintReport\ConstraintCheck\Checker\MultiValueChecker;
use
WikibaseQuality\ConstraintReport\ConstraintCheck\Checker\UniqueValueChecker;
+use WikibaseQuality\ConstraintReport\ConstraintCheck\Checker\ValueOnlyChecker;
use WikibaseQuality\ConstraintReport\ConstraintCheck\ConstraintChecker;
use
WikibaseQuality\ConstraintReport\ConstraintCheck\Helper\ConnectionCheckerHelper;
use WikibaseQuality\ConstraintReport\ConstraintCheck\Helper\LoggingHelper;
@@ -193,7 +194,9 @@
LoggerFactory::getInstance(
'WikibaseQualityConstraints' ),
$this->config
),
- $this->config->get(
'WBQualityConstraintsNewApiOutputFormat' )
+ $this->config->get(
'WBQualityConstraintsNewApiOutputFormat' ),
+ $this->config->get(
'WBQualityConstraintsCheckQualifiers' ),
+ $this->config->get(
'WBQualityConstraintsCheckReferences' )
);
}
@@ -326,6 +329,8 @@
$this->constraintParameterParser,
$this->constraintParameterRenderer
),
+ $this->config->get(
'WBQualityConstraintsUsedForValuesOnlyConstraintId' )
+ => new ValueOnlyChecker(),
];
}
diff --git a/extensions/Constraints/tests/phpunit/Api/CheckConstraintsTest.php
b/extensions/Constraints/tests/phpunit/Api/CheckConstraintsTest.php
index a59d405..63cf1a9 100644
--- a/extensions/Constraints/tests/phpunit/Api/CheckConstraintsTest.php
+++ b/extensions/Constraints/tests/phpunit/Api/CheckConstraintsTest.php
@@ -131,6 +131,8 @@
LoggerFactory::getInstance(
'WikibaseQualityConstraints' ),
$config
),
+ false,
+ false,
false
);
diff --git
a/extensions/Constraints/tests/phpunit/Checker/ValueOnlyCheckerTest.php
b/extensions/Constraints/tests/phpunit/Checker/ValueOnlyCheckerTest.php
new file mode 100644
index 0000000..56c43d5
--- /dev/null
+++ b/extensions/Constraints/tests/phpunit/Checker/ValueOnlyCheckerTest.php
@@ -0,0 +1,97 @@
+<?php
+
+namespace WikibaseQuality\ConstraintReport\Test;
+
+use Wikibase\Repo\Tests\NewItem;
+use Wikibase\Repo\Tests\NewStatement;
+use WikibaseQuality\ConstraintReport\Constraint;
+use WikibaseQuality\ConstraintReport\ConstraintCheck\Checker\ValueOnlyChecker;
+use WikibaseQuality\ConstraintReport\ConstraintCheck\Context\Context;
+use WikibaseQuality\ConstraintReport\ConstraintCheck\Context\StatementContext;
+use WikibaseQuality\ConstraintReport\Tests\ResultAssertions;
+
+/**
+ * @covers
\WikibaseQuality\ConstraintReport\ConstraintCheck\Checker\ValueOnlyChecker
+ *
+ * @group WikibaseQualityConstraints
+ *
+ * @uses \WikibaseQuality\ConstraintReport\ConstraintCheck\Result\CheckResult
+ *
+ * @author Lucas Werkmeister
+ * @license GNU GPL v2+
+ */
+class ValueOnlyCheckerTest extends \PHPUnit_Framework_TestCase {
+
+ use ResultAssertions;
+
+ /**
+ * @param string $type context type
+ * @param string|null $messageKey key of violation message, or null if
compliance is expected
+ * @dataProvider contextTypes
+ */
+ public function testQualifierConstraint( $type, $messageKey ) {
+ $context = $this->getMock( Context::class );
+ $context->method( 'getType' )->willReturn( $type );
+ $checker = new ValueOnlyChecker();
+ $constraint = $this->getConstraintMock( [] );
+
+ $checkResult = $checker->checkConstraint( $context, $constraint
);
+
+ if ( $messageKey === null ) {
+ $this->assertCompliance( $checkResult );
+ } else {
+ $this->assertViolation( $checkResult, $messageKey );
+ }
+ }
+
+ public function contextTypes() {
+ return [
+ [ Context::TYPE_STATEMENT, null ],
+ [ Context::TYPE_QUALIFIER,
'wbqc-violation-message-valueOnly' ],
+ [ Context::TYPE_REFERENCE,
'wbqc-violation-message-valueOnly' ],
+ ];
+ }
+
+ public function testQualifierConstraintDeprecatedStatement() {
+ $checker = new ValueOnlyChecker();
+ $statement = NewStatement::noValueFor( 'P1' )
+ ->withDeprecatedRank()
+ ->build();
+ $constraint = $this->getConstraintMock( [] );
+ $entity = NewItem::withId( 'Q1' )
+ ->build();
+
+ $checkResult = $checker->checkConstraint( new StatementContext(
$entity, $statement ), $constraint );
+
+ // this constraint is still checked on deprecated statements
+ $this->assertCompliance( $checkResult );
+ }
+
+ public function testCheckConstraintParameters() {
+ $checker = new ValueOnlyChecker();
+ $constraint = $this->getConstraintMock( [] );
+
+ $result = $checker->checkConstraintParameters( $constraint );
+
+ $this->assertCount( 0, $result );
+ }
+
+ /**
+ * @return Constraint
+ */
+ private function getConstraintMock() {
+ $mock = $this
+ ->getMockBuilder( Constraint::class )
+ ->disableOriginalConstructor()
+ ->getMock();
+ $mock->expects( $this->any() )
+ ->method( 'getConstraintParameters' )
+ ->will( $this->returnValue( [] ) );
+ $mock->expects( $this->any() )
+ ->method( 'getConstraintTypeItemId' )
+ ->will( $this->returnValue( 'ValueOnly' ) );
+
+ return $mock;
+ }
+
+}
diff --git a/extensions/Wikibase/client/WikibaseClient.php
b/extensions/Wikibase/client/WikibaseClient.php
index baf0bec..cae926c 100644
--- a/extensions/Wikibase/client/WikibaseClient.php
+++ b/extensions/Wikibase/client/WikibaseClient.php
@@ -70,6 +70,7 @@
global $wgAPIListModules,
$wgAPIMetaModules,
$wgAPIPropModules,
+ $wgAPIUselessQueryPages,
$wgExtensionCredits,
$wgExtensionFunctions,
$wgExtensionMessagesFiles,
@@ -267,6 +268,7 @@
);
}
];
+ $wgAPIUselessQueryPages[] = 'PagesWithBadges';
// Special page registration
$wgSpecialPages['UnconnectedPages'] =
Wikibase\Client\Specials\SpecialUnconnectedPages::class;
diff --git
a/extensions/Wikibase/lib/includes/Formatters/EntityIdHtmlLinkFormatter.php
b/extensions/Wikibase/lib/includes/Formatters/EntityIdHtmlLinkFormatter.php
index 2377f1b..2066f6c 100644
--- a/extensions/Wikibase/lib/includes/Formatters/EntityIdHtmlLinkFormatter.php
+++ b/extensions/Wikibase/lib/includes/Formatters/EntityIdHtmlLinkFormatter.php
@@ -3,6 +3,7 @@
namespace Wikibase\Lib;
use Html;
+use Title;
use Wikibase\DataModel\Entity\EntityId;
use Wikibase\DataModel\Services\EntityId\EntityIdLabelFormatter;
use Wikibase\DataModel\Services\Lookup\LabelDescriptionLookup;
@@ -20,14 +21,14 @@
class EntityIdHtmlLinkFormatter extends EntityIdLabelFormatter {
/**
- * @var LanguageFallbackIndicator
- */
- private $languageFallbackIndicator;
-
- /**
* @var EntityTitleLookup
*/
protected $entityTitleLookup;
+
+ /**
+ * @var LanguageFallbackIndicator
+ */
+ private $languageFallbackIndicator;
public function __construct(
LabelDescriptionLookup $labelDescriptionLookup,
@@ -56,60 +57,48 @@
$term = $this->lookupEntityLabel( $entityId );
- $url = $title->isLocal() ? $title->getLocalURL() :
$title->getFullURL();
- $isRedirect = $title->isLocal() && $title->isRedirect();
-
- if ( $term ) {
- return $this->getHtmlForTerm( $url, $term,
$title->getPrefixedText(), $isRedirect );
+ // We can skip the expensive exists() check if we found a term.
+ if ( $term !== null ) {
+ $label = $term->getText();
} elseif ( $title->isLocal() && !$title->exists() ) {
return $this->getHtmlForNonExistent( $entityId );
+ } else {
+ $label = $entityId->getSerialization();
}
- $attributes = [
- 'title' => $title->getPrefixedText(),
- 'href' => $url
- ];
- if ( $isRedirect ) {
- $attributes['class'] = 'mw-redirect';
- }
+ $html = Html::element( 'a', $this->getAttributes( $title, $term
), $label );
- $html = Html::element( 'a', $attributes,
$entityId->getSerialization() );
+ if ( $term instanceof TermFallback ) {
+ $html .= $this->languageFallbackIndicator->getHtml(
$term );
+ }
return $html;
}
/**
- * @param string $targetUrl
- * @param Term $term
- * @param string $titleText
- * @param bool $isRedirect
+ * @param Title $title
+ * @param Term|null $term
*
- * @return string HTML
+ * @return string[]
*/
- private function getHtmlForTerm( $targetUrl, Term $term, $titleText =
'', $isRedirect = false ) {
- $fallbackIndicatorHtml = '';
-
+ private function getAttributes( Title $title, Term $term = null ) {
$attributes = [
- 'title' => $titleText,
- 'href' => $targetUrl
+ 'title' => $title->getPrefixedText(),
+ 'href' => $title->isLocal() ? $title->getLocalURL() :
$title->getFullURL()
];
- if ( $term instanceof TermFallback ) {
- $fallbackIndicatorHtml =
$this->languageFallbackIndicator->getHtml( $term );
-
- if ( $term->getActualLanguageCode() !==
$term->getLanguageCode() ) {
- $attributes['lang'] =
$term->getActualLanguageCode();
- //TODO: mark as rtl/ltr if appropriate.
- }
+ if ( $term instanceof TermFallback
+ && $term->getActualLanguageCode() !==
$term->getLanguageCode()
+ ) {
+ $attributes['lang'] = $term->getActualLanguageCode();
+ // TODO: Mark as RTL/LTR if appropriate.
}
- if ( $isRedirect ) {
+ if ( $title->isLocal() && $title->isRedirect() ) {
$attributes['class'] = 'mw-redirect';
}
- $html = Html::element( 'a', $attributes, $term->getText() );
-
- return $html . $fallbackIndicatorHtml;
+ return $attributes;
}
/**
diff --git a/vendor/composer/autoload_classmap.php
b/vendor/composer/autoload_classmap.php
index fd16fec..3a442e1 100644
--- a/vendor/composer/autoload_classmap.php
+++ b/vendor/composer/autoload_classmap.php
@@ -270,6 +270,7 @@
'WikibaseQuality\\ConstraintReport\\ConstraintCheck\\Checker\\TargetRequiredClaimChecker'
=> $baseDir .
'/extensions/Constraints/includes/ConstraintCheck/Checker/TargetRequiredClaimChecker.php',
'WikibaseQuality\\ConstraintReport\\ConstraintCheck\\Checker\\TypeChecker'
=> $baseDir .
'/extensions/Constraints/includes/ConstraintCheck/Checker/TypeChecker.php',
'WikibaseQuality\\ConstraintReport\\ConstraintCheck\\Checker\\UniqueValueChecker'
=> $baseDir .
'/extensions/Constraints/includes/ConstraintCheck/Checker/UniqueValueChecker.php',
+
'WikibaseQuality\\ConstraintReport\\ConstraintCheck\\Checker\\ValueOnlyChecker'
=> $baseDir .
'/extensions/Constraints/includes/ConstraintCheck/Checker/ValueOnlyChecker.php',
'WikibaseQuality\\ConstraintReport\\ConstraintCheck\\Checker\\ValueTypeChecker'
=> $baseDir .
'/extensions/Constraints/includes/ConstraintCheck/Checker/ValueTypeChecker.php',
'WikibaseQuality\\ConstraintReport\\ConstraintCheck\\ConstraintChecker' =>
$baseDir .
'/extensions/Constraints/includes/ConstraintCheck/ConstraintChecker.php',
'WikibaseQuality\\ConstraintReport\\ConstraintCheck\\Context\\AbstractContext'
=> $baseDir .
'/extensions/Constraints/includes/ConstraintCheck/Context/AbstractContext.php',
diff --git a/vendor/composer/autoload_static.php
b/vendor/composer/autoload_static.php
index 1011b6d..6ccb2b1 100644
--- a/vendor/composer/autoload_static.php
+++ b/vendor/composer/autoload_static.php
@@ -574,6 +574,7 @@
'WikibaseQuality\\ConstraintReport\\ConstraintCheck\\Checker\\TargetRequiredClaimChecker'
=> __DIR__ . '/../..' .
'/extensions/Constraints/includes/ConstraintCheck/Checker/TargetRequiredClaimChecker.php',
'WikibaseQuality\\ConstraintReport\\ConstraintCheck\\Checker\\TypeChecker' =>
__DIR__ . '/../..' .
'/extensions/Constraints/includes/ConstraintCheck/Checker/TypeChecker.php',
'WikibaseQuality\\ConstraintReport\\ConstraintCheck\\Checker\\UniqueValueChecker'
=> __DIR__ . '/../..' .
'/extensions/Constraints/includes/ConstraintCheck/Checker/UniqueValueChecker.php',
+
'WikibaseQuality\\ConstraintReport\\ConstraintCheck\\Checker\\ValueOnlyChecker'
=> __DIR__ . '/../..' .
'/extensions/Constraints/includes/ConstraintCheck/Checker/ValueOnlyChecker.php',
'WikibaseQuality\\ConstraintReport\\ConstraintCheck\\Checker\\ValueTypeChecker'
=> __DIR__ . '/../..' .
'/extensions/Constraints/includes/ConstraintCheck/Checker/ValueTypeChecker.php',
'WikibaseQuality\\ConstraintReport\\ConstraintCheck\\ConstraintChecker' =>
__DIR__ . '/../..' .
'/extensions/Constraints/includes/ConstraintCheck/ConstraintChecker.php',
'WikibaseQuality\\ConstraintReport\\ConstraintCheck\\Context\\AbstractContext'
=> __DIR__ . '/../..' .
'/extensions/Constraints/includes/ConstraintCheck/Context/AbstractContext.php',
diff --git a/vendor/composer/installed.json b/vendor/composer/installed.json
index 16b4245..8f580d7 100644
--- a/vendor/composer/installed.json
+++ b/vendor/composer/installed.json
@@ -1389,12 +1389,12 @@
"source": {
"type": "git",
"url":
"https://github.com/wikimedia/mediawiki-extensions-Wikibase.git",
- "reference": "79f95b564f54ae5499e665a75ffa24860abb9f4b"
+ "reference": "151dde0e4154467a0195a468ef2468daed1c88ee"
},
"dist": {
"type": "zip",
- "url":
"https://api.github.com/repos/wikimedia/mediawiki-extensions-Wikibase/zipball/79f95b564f54ae5499e665a75ffa24860abb9f4b",
- "reference": "79f95b564f54ae5499e665a75ffa24860abb9f4b",
+ "url":
"https://api.github.com/repos/wikimedia/mediawiki-extensions-Wikibase/zipball/151dde0e4154467a0195a468ef2468daed1c88ee",
+ "reference": "151dde0e4154467a0195a468ef2468daed1c88ee",
"shasum": ""
},
"require": {
@@ -1429,7 +1429,7 @@
"mediawiki/minus-x": "0.1.0",
"wikibase/wikibase-codesniffer": "^0.1.0"
},
- "time": "2017-09-29 09:36:10",
+ "time": "2017-09-29 15:47:38",
"type": "mediawiki-extension",
"installation-source": "dist",
"autoload": {
@@ -1780,7 +1780,7 @@
"source": {
"type": "git",
"url":
"https://gerrit.wikimedia.org/r/mediawiki/extensions/WikibaseQualityConstraints",
- "reference": "0a46d56c378cd40d15bc4e0e479f1588261648b1"
+ "reference": "0d4d91f03dafd535e231900ae510c92634682b3e"
},
"require": {
"php": ">=5.5.9",
@@ -1796,7 +1796,7 @@
"satooshi/php-coveralls": "master-dev",
"wikibase/wikibase-codesniffer": "^0.1.0"
},
- "time": "2017-09-29 09:37:36",
+ "time": "2017-09-29 10:04:34",
"type": "mediawiki-extension",
"installation-source": "source",
"autoload": {
--
To view, visit https://gerrit.wikimedia.org/r/381526
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: Ia73eb3a326437b3bd906acb53297c8090e395c3c
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