Lucas Werkmeister (WMDE) has uploaded a new change for review. ( 
https://gerrit.wikimedia.org/r/356421 )

Change subject: Parse Inverse constraints from statements
......................................................................

Parse Inverse constraints from statements

ConstraintStatementParameterParser gains a new method to parse a single
property parameter, which will also be used for several other constraint
types. Configuration variables for the inverse constraint item and the
property parameter property are added. InverseChecker gets a
ConstraintStatementParameterParser injected.

Change-Id: Idf365b7445af7918208cc56342b8646fb6a13e97
---
M extension.json
M i18n/en.json
M i18n/qqq.json
M includes/ConstraintCheck/Checker/InverseChecker.php
M includes/ConstraintCheck/Helper/ConstraintStatementParameterParser.php
M includes/ConstraintReportFactory.php
M tests/phpunit/Checker/ConnectionChecker/InverseCheckerTest.php
7 files changed, 87 insertions(+), 26 deletions(-)


  git pull 
ssh://gerrit.wikimedia.org:29418/mediawiki/extensions/WikibaseQualityConstraints
 refs/changes/21/356421/1

diff --git a/extension.json b/extension.json
index 418f6e8..e1d3a41 100644
--- a/extension.json
+++ b/extension.json
@@ -116,6 +116,11 @@
                        "description": "The item ID of the 'value type 
constraint' item, which, when used in a 'property constraint' statement on a 
property, indicates that the referenced entity should have a certain type, with 
the class and relation given in the parameters.",
                        "public": true
                },
+               "WBQualityConstraintsInverseConstraintId": {
+                       "value": "Q21510855",
+                       "description": "The item ID of the 'inverse 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 
with the property given in the parameters.",
+                       "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.",
@@ -135,6 +140,11 @@
                        "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
+               },
+               "WBQualityConstraintsPropertyId": {
+                       "value": "P2306",
+                       "description": "The property ID of the 'property' 
property, which specifies the property parameter of an 'inverse', 'item 
requires claim', 'value requires claim', 'difference within range', 'mandatory 
qualifiers', or 'qualifiers' constraint.",
+                       "public": true
                }
        },
        "manifest_version": 2
diff --git a/i18n/en.json b/i18n/en.json
index 327b448..6ca3dcc 100644
--- a/i18n/en.json
+++ b/i18n/en.json
@@ -56,6 +56,7 @@
        "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-property": "The value for the 
parameter \"$1\" must be a property, 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 
one of $2.",
 
diff --git a/i18n/qqq.json b/i18n/qqq.json
index 4e9ab16..5cb56f8 100644
--- a/i18n/qqq.json
+++ b/i18n/qqq.json
@@ -52,6 +52,7 @@
        "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 parameter that 
must be an actual value. $1 contains the parameter.",
        "wbqc-violation-message-parameter-entity": "Message for when the value 
of a 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-property": "Message for when the 
value of a parameter must be a property, but is some other kind of entity. $1 
contains the parameter, $2 the data value 
type.{{Related|wbqc-violation-message-parameter-entity}}",
        "wbqc-violation-message-parameter-single": "Message for when a 
parameter has multiple values but only supports one. $1 contains the 
parameter.",
        "wbqc-violation-message-parameter-oneof": "Message for when a parameter 
must be one of several values, but is something different. $1 contains the 
parameter, $2 a comma-separated list of allowed values.",
        "wbqc-violation-message-commons-link-no-existent": "Message for 
violation of Commons link constraint. When linked commons page does not exist.",
diff --git a/includes/ConstraintCheck/Checker/InverseChecker.php 
b/includes/ConstraintCheck/Checker/InverseChecker.php
index cc7a67c..997954d 100644
--- a/includes/ConstraintCheck/Checker/InverseChecker.php
+++ b/includes/ConstraintCheck/Checker/InverseChecker.php
@@ -10,6 +10,7 @@
 use WikibaseQuality\ConstraintReport\Constraint;
 use WikibaseQuality\ConstraintReport\ConstraintCheck\ConstraintChecker;
 use 
WikibaseQuality\ConstraintReport\ConstraintCheck\Helper\ConstraintParameterParser;
+use 
WikibaseQuality\ConstraintReport\ConstraintCheck\Helper\ConstraintStatementParameterParser;
 use 
WikibaseQuality\ConstraintReport\ConstraintCheck\Helper\ConnectionCheckerHelper;
 use WikibaseQuality\ConstraintReport\ConstraintCheck\Result\CheckResult;
 use WikibaseQuality\ConstraintReport\ConstraintParameterRenderer;
@@ -28,7 +29,7 @@
        private $entityLookup;
 
        /**
-        * @var ConstraintParameterParser
+        * @var ConstraintStatementParameterParser
         */
        private $constraintParameterParser;
 
@@ -44,18 +45,18 @@
 
        /**
         * @param EntityLookup $lookup
-        * @param ConstraintParameterParser $helper
+        * @param ConstraintStatementParameterParser $constraintParameterParser
         * @param ConnectionCheckerHelper $connectionCheckerHelper
         * @param ConstraintParameterRenderer $constraintParameterRenderer
         */
        public function __construct(
                EntityLookup $lookup,
-               ConstraintParameterParser $helper,
+               ConstraintStatementParameterParser $constraintParameterParser,
                ConnectionCheckerHelper $connectionCheckerHelper,
                ConstraintParameterRenderer $constraintParameterRenderer
        ) {
                $this->entityLookup = $lookup;
-               $this->constraintParameterParser = $helper;
+               $this->constraintParameterParser = $constraintParameterParser;
                $this->connectionCheckerHelper = $connectionCheckerHelper;
                $this->constraintParameterRenderer = 
$constraintParameterRenderer;
        }
@@ -73,9 +74,12 @@
                $parameters = [];
                $constraintParameters = $constraint->getConstraintParameters();
 
-               if ( array_key_exists( 'property', $constraintParameters ) ) {
-                       $parameters['property'] = 
$this->constraintParameterParser->parseSingleParameter( 
$constraintParameters['property'] );
-               };
+               $propertyId = 
$this->constraintParameterParser->parsePropertyParameter( 
$constraintParameters, $constraint->getConstraintTypeName() );
+               if ( is_string( $propertyId ) ) {
+                       return new CheckResult( $entity->getId(), $statement, 
$constraint->getConstraintTypeQid(), $constraint->getConstraintId(), 
$parameters, CheckResult::STATUS_VIOLATION, $propertyId );
+               } else {
+                       $parameters['property'] = [ $propertyId ];
+               }
 
                if ( array_key_exists( 'constraint_status', 
$constraintParameters ) ) {
                        $parameters['constraint_status'] = 
$this->constraintParameterParser->parseSingleParameter( 
$constraintParameters['constraint_status'], true );
@@ -97,7 +101,6 @@
                /*
                 * error handling:
                 *   type of $dataValue for properties with 'Inverse' 
constraint has to be 'wikibase-entityid'
-                *   parameter $property must not be null
                 */
                if ( $dataValue->getType() !== 'wikibase-entityid' ) {
                        $message = wfMessage( 
"wbqc-violation-message-value-needed-of-type" )->params( 
$constraint->getConstraintTypeName(), 'wikibase-entityid' )->escaped();
@@ -105,12 +108,6 @@
                }
                /** @var EntityIdValue $dataValue */
 
-               if ( !array_key_exists( 'property', $constraintParameters ) ) {
-                       $message = wfMessage( 
"wbqc-violation-message-property-needed" )->params( 
$constraint->getConstraintTypeName(), 'property' )->escaped();
-                       return new CheckResult( $entity->getId(), $statement, 
$constraint->getConstraintTypeQid(), $constraint->getConstraintId(), 
$parameters, CheckResult::STATUS_VIOLATION, $message );
-               }
-
-               $property = $constraintParameters['property'];
                $targetItem = $this->entityLookup->getEntity( 
$dataValue->getEntityId() );
                if ( $targetItem === null ) {
                        $message = wfMessage( 
"wbqc-violation-message-target-entity-must-exist" )->escaped();
@@ -118,14 +115,14 @@
                }
                $targetItemStatementList = $targetItem->getStatements();
 
-               if ( $this->connectionCheckerHelper->findStatement( 
$targetItemStatementList, $property, $entity->getId()->getSerialization() ) !== 
null ) {
+               if ( $this->connectionCheckerHelper->findStatement( 
$targetItemStatementList, $propertyId->getSerialization(), 
$entity->getId()->getSerialization() ) !== null ) {
                        $message = '';
                        $status = CheckResult::STATUS_COMPLIANCE;
                } else {
                        $message = wfMessage( 'wbqc-violation-message-inverse' )
                                         ->rawParams(
                                                 
$this->constraintParameterRenderer->formatEntityId( $targetItem->getId() ),
-                                                
$this->constraintParameterRenderer->formatPropertyId( $property ),
+                                                
$this->constraintParameterRenderer->formatPropertyId( $propertyId ),
                                                 
$this->constraintParameterRenderer->formatEntityId( $entity->getId() )
                                         )
                                         ->escaped();
diff --git 
a/includes/ConstraintCheck/Helper/ConstraintStatementParameterParser.php 
b/includes/ConstraintCheck/Helper/ConstraintStatementParameterParser.php
index e31f22b..9fc8da8 100644
--- a/includes/ConstraintCheck/Helper/ConstraintStatementParameterParser.php
+++ b/includes/ConstraintCheck/Helper/ConstraintStatementParameterParser.php
@@ -3,6 +3,7 @@
 namespace WikibaseQuality\ConstraintReport\ConstraintCheck\Helper;
 
 use Config;
+use DataValues\StringValue;
 use InvalidArgumentException;
 use Message;
 use Wikibase\DataModel\DeserializerFactory;
@@ -161,4 +162,61 @@
                }
        }
 
+       /**
+        * @param array $constraintParameters
+        * @param string $constraintTypeName
+        * @return PropertyId|string property ID or error message
+        */
+       public function parsePropertyParameter( array $constraintParameters, 
$constraintTypeName ) {
+               $propertyIdString = $this->config->get( 
'WBQualityConstraintsPropertyId' );
+               if ( array_key_exists( $propertyIdString, $constraintParameters 
) ) {
+                       if ( count( $constraintParameters[$propertyIdString] ) 
!== 1 ) {
+                               return wfMessage( 
"wbqc-violation-message-parameter-single" )->escaped();
+                       }
+                       $snak = $this->snakDeserializer->deserialize( 
$constraintParameters[$propertyIdString][0] );
+                       if ( $snak instanceof PropertyValueSnak ) {
+                               $value = $snak->getDataValue();
+                               if ( $value instanceof EntityIdValue ) {
+                                       $propertyId = $value->getEntityId();
+                                       if ( $propertyId instanceof PropertyId 
) {
+                                               return $propertyId;
+                                       } else {
+                                               return wfMessage( 
"wbqc-violation-message-parameter-property" )
+                                                       ->rawParams(
+                                                               
$this->constraintParameterRenderer->formatPropertyId( $propertyIdString ),
+                                                               
$this->constraintParameterRenderer->formatDataValue( $value )
+                                                       )
+                                                       ->escaped();
+                                       }
+                               } else {
+                                       return wfMessage( 
"wbqc-violation-message-parameter-entity" )
+                                               ->rawParams(
+                                                       
$this->constraintParameterRenderer->formatPropertyId( $propertyIdString ),
+                                                       
$this->constraintParameterRenderer->formatDataValue( $value )
+                                               )
+                                               ->escaped();
+                               }
+                       } else {
+                               return wfMessage( 
'wbqc-violation-message-parameter-value' )
+                                       ->rawParams( 
$this->constraintParameterRenderer->formatPropertyId( $propertyIdString ) )
+                                       ->escaped();
+                       }
+               } elseif ( array_key_exists( 'property', $constraintParameters 
) ) {
+                       try {
+                               return new PropertyId( 
$constraintParameters['property'] );
+                       } catch ( InvalidArgumentException $e ) {
+                               return wfMessage( 
"wbqc-violation-message-parameter-property" )
+                                       ->rawParams(
+                                               
$this->constraintParameterRenderer->formatPropertyId( $propertyIdString ),
+                                               
$this->constraintParameterRenderer->formatDataValue( new StringValue( 
$constraintParameters['property'] ) )
+                                       )
+                                       ->escaped();
+                       }
+               } else {
+                       return wfMessage( 
"wbqc-violation-message-parameter-needed" )
+                               ->params( $constraintTypeName, 'property' )
+                               ->escaped();
+               }
+       }
+
 }
diff --git a/includes/ConstraintReportFactory.php 
b/includes/ConstraintReportFactory.php
index 01bfe8f..ceb2a55 100644
--- a/includes/ConstraintReportFactory.php
+++ b/includes/ConstraintReportFactory.php
@@ -166,7 +166,7 @@
                                'Item' => new ItemChecker( $this->lookup, 
$constraintParameterParser, $connectionCheckerHelper, 
$this->constraintParameterRenderer ),
                                'Target required claim' => new 
TargetRequiredClaimChecker( $this->lookup, $constraintParameterParser, 
$connectionCheckerHelper, $this->constraintParameterRenderer ),
                                'Symmetric' => new SymmetricChecker( 
$this->lookup, $constraintParameterParser, $connectionCheckerHelper, 
$this->constraintParameterRenderer ),
-                               'Inverse' => new InverseChecker( $this->lookup, 
$constraintParameterParser, $connectionCheckerHelper, 
$this->constraintParameterRenderer ),
+                               'Inverse' => new InverseChecker( $this->lookup, 
$this->constraintStatementParameterParser, $connectionCheckerHelper, 
$this->constraintParameterRenderer ),
                                'Qualifier' => new QualifierChecker( 
$constraintParameterParser ),
                                'Qualifiers' => new QualifiersChecker( 
$constraintParameterParser, $this->constraintParameterRenderer ),
                                'Mandatory qualifiers' => new 
MandatoryQualifiersChecker( $constraintParameterParser, 
$this->constraintParameterRenderer ),
@@ -188,7 +188,8 @@
                                $this->config->get( 
'WBQualityConstraintsSingleValueConstraintId' ) => 
$this->constraintCheckerMap['Single value'],
                                $this->config->get( 
'WBQualityConstraintsSymmetricConstraintId' ) => 
$this->constraintCheckerMap['Symmetric'],
                                $this->config->get( 
'WBQualityConstraintsTypeConstraintId' ) => $this->constraintCheckerMap['Type'],
-                               $this->config->get( 
'WBQualityConstraintsValueTypeConstraintId' ) => 
$this->constraintCheckerMap['Value type']
+                               $this->config->get( 
'WBQualityConstraintsValueTypeConstraintId' ) => 
$this->constraintCheckerMap['Value type'],
+                               $this->config->get( 
'WBQualityConstraintsInverseConstraintId' ) => 
$this->constraintCheckerMap['Inverse'],
                        ];
                }
 
diff --git a/tests/phpunit/Checker/ConnectionChecker/InverseCheckerTest.php 
b/tests/phpunit/Checker/ConnectionChecker/InverseCheckerTest.php
index c7bb5ec..7ded9dc 100644
--- a/tests/phpunit/Checker/ConnectionChecker/InverseCheckerTest.php
+++ b/tests/phpunit/Checker/ConnectionChecker/InverseCheckerTest.php
@@ -37,11 +37,6 @@
        private $lookup;
 
        /**
-        * @var ConstraintParameterParser
-        */
-       private $helper;
-
-       /**
         * @var ConnectionCheckerHelper
         */
        private $connectionCheckerHelper;
@@ -54,11 +49,10 @@
        protected function setUp() {
                parent::setUp();
                $this->lookup = new JsonFileEntityLookup( __DIR__ );
-               $this->helper = new ConstraintParameterParser();
                $this->connectionCheckerHelper = new ConnectionCheckerHelper();
                $this->checker = new InverseChecker(
                        $this->lookup,
-                       $this->helper,
+                       $this->getConstraintParameterParser(),
                        $this->connectionCheckerHelper,
                        $this->getConstraintParameterRenderer()
                );
@@ -66,7 +60,6 @@
 
        protected function tearDown() {
                unset( $this->lookup );
-               unset( $this->helper );
                unset( $this->connectionCheckerHelper );
                unset( $this->checker );
                parent::tearDown();

-- 
To view, visit https://gerrit.wikimedia.org/r/356421
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings

Gerrit-MessageType: newchange
Gerrit-Change-Id: Idf365b7445af7918208cc56342b8646fb6a13e97
Gerrit-PatchSet: 1
Gerrit-Project: mediawiki/extensions/WikibaseQualityConstraints
Gerrit-Branch: master
Gerrit-Owner: Lucas Werkmeister (WMDE) <[email protected]>

_______________________________________________
MediaWiki-commits mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits

Reply via email to