Adrian Lang has uploaded a new change for review.
https://gerrit.wikimedia.org/r/189731
Change subject: Move Validator builders out of WikibaseDataTypeBuilders
......................................................................
Move Validator builders out of WikibaseDataTypeBuilders
Change-Id: I6fb14c135315c7c064ccf49c019670dfab68c857
---
M lib/includes/WikibaseDataTypeBuilders.php
A repo/includes/DataTypeValidatorFactory.php
A repo/includes/ValidatorBuilders.php
M repo/includes/Validators/SnakValidator.php
M repo/includes/WikibaseRepo.php
5 files changed, 402 insertions(+), 243 deletions(-)
git pull ssh://gerrit.wikimedia.org:29418/mediawiki/extensions/Wikibase
refs/changes/31/189731/1
diff --git a/lib/includes/WikibaseDataTypeBuilders.php
b/lib/includes/WikibaseDataTypeBuilders.php
index 90f7ee4..c6e09c4 100644
--- a/lib/includes/WikibaseDataTypeBuilders.php
+++ b/lib/includes/WikibaseDataTypeBuilders.php
@@ -3,26 +3,6 @@
namespace Wikibase\Lib;
use DataTypes\DataType;
-use DataValues\TimeValue;
-use ValueValidators\ValueValidator;
-use Wikibase\DataModel\Entity\EntityIdParser;
-use Wikibase\DataModel\Entity\Item;
-use Wikibase\DataModel\Entity\Property;
-use Wikibase\Lib\Store\EntityLookup;
-use Wikibase\Utils;
-use Wikibase\Validators\AlternativeValidator;
-use Wikibase\Validators\CompositeValidator;
-use Wikibase\Validators\DataFieldValidator;
-use Wikibase\Validators\DataValueValidator;
-use Wikibase\Validators\EntityExistsValidator;
-use Wikibase\Validators\MembershipValidator;
-use Wikibase\Validators\NumberRangeValidator;
-use Wikibase\Validators\NumberValidator;
-use Wikibase\Validators\RegexValidator;
-use Wikibase\Validators\StringLengthValidator;
-use Wikibase\Validators\TypeValidator;
-use Wikibase\Validators\UrlSchemeValidators;
-use Wikibase\Validators\UrlValidator;
/**
* Defines the data types supported by Wikibase.
@@ -33,36 +13,6 @@
* @author Daniel Kinzler
*/
class WikibaseDataTypeBuilders {
-
- /**
- * @var EntityIdParser
- */
- private $entityIdParser;
-
- /**
- * @var EntityLookup
- */
- private $entityLookup;
-
- /**
- * @var string[]
- */
- private $urlSchemes;
-
- /**
- * @param EntityLookup $lookup
- * @param EntityIdParser $idParser
- * @param string[] $urlSchemes
- */
- public function __construct(
- EntityLookup $lookup,
- EntityIdParser $idParser,
- array $urlSchemes
- ) {
- $this->entityIdParser = $idParser;
- $this->entityLookup = $lookup;
- $this->urlSchemes = $urlSchemes;
- }
/**
* @return array DataType builder specs
@@ -88,6 +38,7 @@
* wikibase-property => wikibase-entityid
*/
+ // Update ValidatorBuilders in repo if you change this
$types = array(
'commonsMedia' => array( $this, 'buildMediaType' ),
'globe-coordinate' => array( $this,
'buildCoordinateType' ),
@@ -117,13 +68,7 @@
* @return DataType
*/
public function buildItemType( $id ) {
- $validators = array();
-
- //NOTE: The DataValue in question is going to be an instance of
EntityId!
- $validators[] = new TypeValidator(
'Wikibase\DataModel\Entity\EntityIdValue' );
- $validators[] = new EntityExistsValidator( $this->entityLookup,
Item::ENTITY_TYPE );
-
- return new DataType( $id, 'wikibase-entityid', $validators );
+ return new DataType( $id, 'wikibase-entityid', array() );
}
/**
@@ -132,30 +77,7 @@
* @return DataType
*/
public function buildPropertyType( $id ) {
- $validators = array();
-
- //NOTE: The DataValue in question is going to be an instance of
EntityId!
- $validators[] = new TypeValidator(
'Wikibase\DataModel\Entity\EntityIdValue' );
- $validators[] = new EntityExistsValidator( $this->entityLookup,
Property::ENTITY_TYPE );
-
- return new DataType( $id, 'wikibase-entityid', $validators );
- }
-
- /**
- * @param int $maxLength Defaults to 400 characters. This was an
arbitrary decision when it
- * turned out that 255 was to short for descriptions.
- *
- * @return ValueValidator[]
- */
- private function getCommonStringValidators( $maxLength = 400 ) {
- $validators = array();
-
- $validators[] = new TypeValidator( 'string' );
- //TODO: validate UTF8 (here and elsewhere)
- $validators[] = new StringLengthValidator( 1, $maxLength,
'mb_strlen' );
- $validators[] = new RegexValidator( '/^\s|[\r\n\t]|\s$/', true
); // no leading/trailing whitespace, no line breaks.
-
- return $validators;
+ return new DataType( $id, 'wikibase-entityid', array() );
}
/**
@@ -164,22 +86,8 @@
* @return DataType
*/
public function buildMediaType( $id ) {
- // oi_archive_name is max 255 bytes, which include a timestamp
and an exclamation mark,
- // so restrict file name to 240 bytes (see
UploadBase::getTitle).
- $validators = $this->getCommonStringValidators( 240 );
- $validators[] = new RegexValidator( '@[#/:\\\\]@u', true ); //
no nasty chars
- // Must contain a non-empty file name and a non-empty,
character-only file extension.
- $validators[] = new RegexValidator( '/.\.\w+$/u' );
- //TODO: add a validator that checks the rules that MediaWiki
imposes on filenames for uploads.
- // $wgLegalTitleChars and $wgIllegalFileChars define this,
but we need these for the *target* wiki.
- //TODO: add a validator that uses a foreign DB query to check
whether the file actually exists on commons.
-
- $topValidator = new DataValueValidator(
- new CompositeValidator( $validators ) //Note: each
validator is fatal
- );
-
- return new DataType( $id, 'string', array( new TypeValidator(
'DataValues\DataValue' ), $topValidator ) );
+ return new DataType( $id, 'string', array() );
}
/**
@@ -188,13 +96,7 @@
* @return DataType
*/
public function buildStringType( $id ) {
- $validators = $this->getCommonStringValidators();
-
- $topValidator = new DataValueValidator(
- new CompositeValidator( $validators ) //Note: each
validator is fatal
- );
-
- return new DataType( $id, 'string', array( new TypeValidator(
'DataValues\DataValue' ), $topValidator ) );
+ return new DataType( $id, 'string', array() );
}
/**
@@ -203,23 +105,7 @@
* @return DataType
*/
public function buildMonolingualTextType( $id ) {
- $validators = array();
-
- $validators[] = new DataFieldValidator(
- 'text',
- new CompositeValidator(
$this->getCommonStringValidators() ) //Note: each validator is fatal
- );
-
- $validators[] = new DataFieldValidator(
- 'language',
- new MembershipValidator( Utils::getLanguageCodes() )
- );
-
- $topValidator = new DataValueValidator(
- new CompositeValidator( $validators ) //Note: each
validator is fatal
- );
-
- return new DataType( $id, 'monolingualtext', array( new
TypeValidator( 'DataValues\DataValue' ), $topValidator ) );
+ return new DataType( $id, 'monolingualtext', array() );
}
/**
@@ -228,48 +114,7 @@
* @return DataType
*/
public function buildTimeType( $id ) {
- $validators = array();
- $validators[] = new TypeValidator( 'array' );
-
- // Expected to be a short IRI, see TimeFormatter and TimeParser.
- $urlValidator = $this->buildUrlValidator( array( 'http',
'https' ), 255 );
- //TODO: enforce well known calendar models from config
-
- $validators[] = new DataFieldValidator( 'calendarmodel',
$urlValidator );
-
- // time string field
- $timeStringValidators = array();
- $timeStringValidators[] = new TypeValidator( 'string' );
-
- // down to the second
- //$maxPrecision = TimeValue::PRECISION_SECOND;
- //$isoDataPattern =
'!^[-+]\d{1,16}-(0\d|1[012])-([012]\d|3[01])T([01]\d|2[0123]):[0-5]\d:([0-5]\d|6[012])Z$!';
-
- // down to the day
- $maxPrecision = TimeValue::PRECISION_DAY;
- $isoDataPattern =
'!^[-+]\d{1,16}-(0\d|1[012])-([012]\d|3[01])T00:00:00Z$!';
-
- $timeStringValidators[] = new RegexValidator( $isoDataPattern );
-
- $validators[] = new DataFieldValidator(
- 'time',
- new CompositeValidator( $timeStringValidators ) //Note:
each validator is fatal
- );
-
- $precisionValidators = array();
- $precisionValidators[] = new TypeValidator( 'integer' );
- $precisionValidators[] = new NumberRangeValidator(
TimeValue::PRECISION_Ga, $maxPrecision );
-
- $validators[] = new DataFieldValidator(
- 'precision',
- new CompositeValidator( $precisionValidators ) //Note:
each validator is fatal
- );
-
- $topValidator = new DataValueValidator(
- new CompositeValidator( $validators ) //Note: each
validator is fatal
- );
-
- return new DataType( $id, 'time', array( new TypeValidator(
'DataValues\DataValue' ), $topValidator ) );
+ return new DataType( $id, 'time', array() );
}
/**
@@ -278,42 +123,7 @@
* @return DataType
*/
public function buildCoordinateType( $id ) {
- $validators = array();
- $validators[] = new TypeValidator( 'array' );
-
- // Expected to be a short IRI, see GlobeCoordinateValue and
GlobeCoordinateParser.
- $urlValidator = $this->buildUrlValidator( array( 'http',
'https' ), 255 );
- //TODO: enforce well known reference globes from config
-
- $validators[] = new DataFieldValidator( 'precision', new
NumberValidator() );
-
- $validators[] = new DataFieldValidator( 'globe', $urlValidator
);
-
- $topValidator = new DataValueValidator(
- new CompositeValidator( $validators ) //Note: each
validator is fatal
- );
-
- return new DataType( $id, 'globecoordinate', array( new
TypeValidator( 'DataValues\DataValue' ), $topValidator ) );
- }
-
- /**
- * @param string[] $urlSchemes List of URL schemes, e.g. 'http'
- * @param int $maxLength Defaults to 500 characters. Even if URLs are
unlimited in theory they
- * should be limited to about 2000. About 500 is a reasonable
compromise.
- * @see http://stackoverflow.com/a/417184
- *
- * @return CompositeValidator
- */
- public function buildUrlValidator( $urlSchemes, $maxLength = 500 ) {
- $validators = array();
- $validators[] = new TypeValidator( 'string' );
- $validators[] = new StringLengthValidator( 2, $maxLength );
-
- $urlValidators = new UrlSchemeValidators();
- $urlSchemeValidators = $urlValidators->getValidators(
$urlSchemes );
- $validators[] = new UrlValidator( $urlSchemeValidators );
-
- return new CompositeValidator( $validators ); //Note: each
validator is fatal
+ return new DataType( $id, 'globecoordinate', array() );
}
/**
@@ -322,13 +132,7 @@
* @return DataType
*/
public function buildUrlType( $id ) {
- $urlValidator = $this->buildUrlValidator( $this->urlSchemes );
-
- $topValidator = new DataValueValidator(
- $urlValidator
- );
-
- return new DataType( $id, 'string', array( new TypeValidator(
'DataValues\DataValue' ), $topValidator ) );
+ return new DataType( $id, 'string', array() );
}
/**
@@ -337,26 +141,7 @@
* @return DataType
*/
public function buildQuantityType( $id ) {
- $validators = array();
- $validators[] = new TypeValidator( 'array' );
-
- // the 'amount' field is already validated by QuantityValue's
constructor
- // the 'digits' field is already validated by QuantityValue's
constructor
-
- $unitValidators = new AlternativeValidator( array(
- // NOTE: "1" is always considered legal for historical
reasons,
- // since we use it to represent "unitless" quantities.
We could also use
- // http://qudt.org/vocab/unit#Unitless or
https://www.wikidata.org/entity/Q199
- new MembershipValidator( array( '1' ) ),
- $this->buildUrlValidator( array( 'http', 'https' ), 255
),
- ) );
- $validators[] = new DataFieldValidator( 'unit', $unitValidators
);
-
- $topValidator = new DataValueValidator(
- new CompositeValidator( $validators ) //Note: each
validator is fatal
- );
-
- return new DataType( $id, 'quantity', array( new TypeValidator(
'DataValues\QuantityValue' ), $topValidator ) );
+ return new DataType( $id, 'quantity', array() );
}
}
diff --git a/repo/includes/DataTypeValidatorFactory.php
b/repo/includes/DataTypeValidatorFactory.php
new file mode 100644
index 0000000..0d492f4
--- /dev/null
+++ b/repo/includes/DataTypeValidatorFactory.php
@@ -0,0 +1,35 @@
+<?php
+
+namespace Wikibase\Repo;
+
+/**
+ * Description of DataTypeValidatorFactory
+ *
+ * @author Adrian Heine < [email protected] >
+ */
+class DataTypeValidatorFactory {
+
+ /**
+ * @var callable[]
+ */
+ private $validatorBuilders;
+
+ //put your code here
+
+ public function __construct( ValidatorBuilders $validatorBuilders ) {
+ $this->validatorBuilders =
$validatorBuilders->getDataTypeValidators();
+ }
+
+ /**
+ *
+ * @param string $dataValueType
+ *
+ * @return ValueValidator[]
+ */
+ public function getValidators( $dataValueType ) {
+ return call_user_func(
+ $this->validatorBuilders[ $dataValueType ]
+ );
+ }
+
+}
diff --git a/repo/includes/ValidatorBuilders.php
b/repo/includes/ValidatorBuilders.php
new file mode 100644
index 0000000..0f799f3
--- /dev/null
+++ b/repo/includes/ValidatorBuilders.php
@@ -0,0 +1,324 @@
+<?php
+
+namespace Wikibase\Repo;
+
+use DataValues\TimeValue;
+use ValueValidators\ValueValidator;
+use Wikibase\DataModel\Entity\EntityIdParser;
+use Wikibase\DataModel\Entity\Item;
+use Wikibase\DataModel\Entity\Property;
+use Wikibase\Lib\Store\EntityLookup;
+use Wikibase\Utils;
+use Wikibase\Validators\AlternativeValidator;
+use Wikibase\Validators\CompositeValidator;
+use Wikibase\Validators\DataFieldValidator;
+use Wikibase\Validators\DataValueValidator;
+use Wikibase\Validators\EntityExistsValidator;
+use Wikibase\Validators\MembershipValidator;
+use Wikibase\Validators\NumberRangeValidator;
+use Wikibase\Validators\NumberValidator;
+use Wikibase\Validators\RegexValidator;
+use Wikibase\Validators\StringLengthValidator;
+use Wikibase\Validators\TypeValidator;
+use Wikibase\Validators\UrlSchemeValidators;
+use Wikibase\Validators\UrlValidator;
+
+/**
+ * Defines validators for the data types supported by Wikibase.
+ *
+ * @since 0.4
+ *
+ * @licence GNU GPL v2+
+ * @author Daniel Kinzler
+ */
+class ValidatorBuilders {
+
+ /**
+ * @var EntityIdParser
+ */
+ private $entityIdParser;
+
+ /**
+ * @var EntityLookup
+ */
+ private $entityLookup;
+
+ /**
+ * @var string[]
+ */
+ private $urlSchemes;
+
+ /**
+ * @param EntityLookup $lookup
+ * @param EntityIdParser $idParser
+ * @param string[] $urlSchemes
+ */
+ public function __construct(
+ EntityLookup $lookup,
+ EntityIdParser $idParser,
+ array $urlSchemes
+ ) {
+ $this->entityIdParser = $idParser;
+ $this->entityLookup = $lookup;
+ $this->urlSchemes = $urlSchemes;
+ }
+
+ /**
+ * @return callable[] ValueValidator for DataTypes build spec
+ */
+ public function getDataTypeValidators() {
+
+ $types = array(
+ 'commonsMedia' => array( $this,
'buildMediaValidators' ),
+ 'globe-coordinate' => array( $this,
'buildCoordinateValidators' ),
+ 'quantity' => array( $this,
'buildQuantityValidators' ),
+ 'string' => array( $this,
'buildStringValidators' ),
+ 'time' => array( $this,
'buildTimeValidators' ),
+ 'url' => array( $this,
'buildUrlValidators' ),
+ 'wikibase-item' => array( $this,
'buildItemValidators' ),
+ 'wikibase-property' => array( $this,
'buildPropertyValidators' ),
+ 'monolingualtext' => array( $this,
'buildMonolingualTextValidators' ),
+ );
+
+ $experimental = array(
+ // 'multilingualtext' => array( $this,
'buildMultilingualTextValidators' ),
+ );
+
+ if ( defined( 'WB_EXPERIMENTAL_FEATURES' ) &&
WB_EXPERIMENTAL_FEATURES ) {
+ $types = array_merge( $types, $experimental );
+ }
+
+ return $types;
+ }
+
+ /**
+ * @return ValueValidator[]
+ */
+ public function buildItemValidators() {
+ $validators = array();
+
+ //NOTE: The DataValue in question is going to be an instance of
EntityId!
+ $validators[] = new TypeValidator(
'Wikibase\DataModel\Entity\EntityIdValue' );
+ $validators[] = new EntityExistsValidator( $this->entityLookup,
Item::ENTITY_TYPE );
+
+ return $validators;
+ }
+
+ /**
+ * @return ValueValidator[]
+ */
+ public function buildPropertyValidators( ) {
+ $validators = array();
+
+ //NOTE: The DataValue in question is going to be an instance of
EntityId!
+ $validators[] = new TypeValidator(
'Wikibase\DataModel\Entity\EntityIdValue' );
+ $validators[] = new EntityExistsValidator( $this->entityLookup,
Property::ENTITY_TYPE );
+
+ return $validators;
+ }
+
+ /**
+ * @param int $maxLength Defaults to 400 characters. This was an
arbitrary decision when it
+ * turned out that 255 was to short for descriptions.
+ *
+ * @return ValueValidator[]
+ */
+ private function getCommonStringValidators( $maxLength = 400 ) {
+ $validators = array();
+
+ $validators[] = new TypeValidator( 'string' );
+ //TODO: validate UTF8 (here and elsewhere)
+ $validators[] = new StringLengthValidator( 1, $maxLength,
'mb_strlen' );
+ $validators[] = new RegexValidator( '/^\s|[\r\n\t]|\s$/', true
); // no leading/trailing whitespace, no line breaks.
+
+ return $validators;
+ }
+
+ /**
+ * @return ValueValidator[]
+ */
+ public function buildMediaValidators() {
+ // oi_archive_name is max 255 bytes, which include a timestamp
and an exclamation mark,
+ // so restrict file name to 240 bytes (see
UploadBase::getTitle).
+ $validators = $this->getCommonStringValidators( 240 );
+
+ $validators[] = new RegexValidator( '@[#/:\\\\]@u', true ); //
no nasty chars
+ // Must contain a non-empty file name and a non-empty,
character-only file extension.
+ $validators[] = new RegexValidator( '/.\.\w+$/u' );
+ //TODO: add a validator that checks the rules that MediaWiki
imposes on filenames for uploads.
+ // $wgLegalTitleChars and $wgIllegalFileChars define this,
but we need these for the *target* wiki.
+ //TODO: add a validator that uses a foreign DB query to check
whether the file actually exists on commons.
+
+ $topValidator = new DataValueValidator(
+ new CompositeValidator( $validators ) //Note: each
validator is fatal
+ );
+
+ return array( new TypeValidator( 'DataValues\DataValue' ),
$topValidator );
+ }
+
+ /**
+ * @return ValueValidator[]
+ */
+ public function buildStringValidators() {
+ $validators = $this->getCommonStringValidators();
+
+ $topValidator = new DataValueValidator(
+ new CompositeValidator( $validators ) //Note: each
validator is fatal
+ );
+
+ return array( new TypeValidator( 'DataValues\DataValue' ),
$topValidator );
+ }
+
+ /**
+ * @return ValueValidator[]
+ */
+ public function buildMonolingualTextValidators() {
+ $validators = array();
+
+ $validators[] = new DataFieldValidator(
+ 'text',
+ new CompositeValidator(
$this->getCommonStringValidators() ) //Note: each validator is fatal
+ );
+
+ $validators[] = new DataFieldValidator(
+ 'language',
+ new MembershipValidator( Utils::getLanguageCodes() )
+ );
+
+ $topValidator = new DataValueValidator(
+ new CompositeValidator( $validators ) //Note: each
validator is fatal
+ );
+
+ return array( new TypeValidator( 'DataValues\DataValue' ),
$topValidator );
+ }
+
+ /**
+ * @return ValueValidator[]
+ */
+ public function buildTimeValidators() {
+ $validators = array();
+ $validators[] = new TypeValidator( 'array' );
+
+ // Expected to be a short IRI, see TimeFormatter and TimeParser.
+ $urlValidator = $this->getUrlValidator( array( 'http', 'https'
), 255 );
+ //TODO: enforce well known calendar models from config
+
+ $validators[] = new DataFieldValidator( 'calendarmodel',
$urlValidator );
+
+ // time string field
+ $timeStringValidators = array();
+ $timeStringValidators[] = new TypeValidator( 'string' );
+
+ // down to the second
+ //$maxPrecision = TimeValue::PRECISION_SECOND;
+ //$isoDataPattern =
'!^[-+]\d{1,16}-(0\d|1[012])-([012]\d|3[01])T([01]\d|2[0123]):[0-5]\d:([0-5]\d|6[012])Z$!';
+
+ // down to the day
+ $maxPrecision = TimeValue::PRECISION_DAY;
+ $isoDataPattern =
'!^[-+]\d{1,16}-(0\d|1[012])-([012]\d|3[01])T00:00:00Z$!';
+
+ $timeStringValidators[] = new RegexValidator( $isoDataPattern );
+
+ $validators[] = new DataFieldValidator(
+ 'time',
+ new CompositeValidator( $timeStringValidators ) //Note:
each validator is fatal
+ );
+
+ $precisionValidators = array();
+ $precisionValidators[] = new TypeValidator( 'integer' );
+ $precisionValidators[] = new NumberRangeValidator(
TimeValue::PRECISION_Ga, $maxPrecision );
+
+ $validators[] = new DataFieldValidator(
+ 'precision',
+ new CompositeValidator( $precisionValidators ) //Note:
each validator is fatal
+ );
+
+ $topValidator = new DataValueValidator(
+ new CompositeValidator( $validators ) //Note: each
validator is fatal
+ );
+
+ return array( new TypeValidator( 'DataValues\DataValue' ),
$topValidator );
+ }
+
+ /**
+ * @return ValueValidator[]
+ */
+ public function buildCoordinateValidators() {
+ $validators = array();
+ $validators[] = new TypeValidator( 'array' );
+
+ // Expected to be a short IRI, see GlobeCoordinateValue and
GlobeCoordinateParser.
+ $urlValidator = $this->getUrlValidator( array( 'http', 'https'
), 255 );
+ //TODO: enforce well known reference globes from config
+
+ $validators[] = new DataFieldValidator( 'precision', new
NumberValidator() );
+
+ $validators[] = new DataFieldValidator( 'globe', $urlValidator
);
+
+ $topValidator = new DataValueValidator(
+ new CompositeValidator( $validators ) //Note: each
validator is fatal
+ );
+
+ return array( new TypeValidator( 'DataValues\DataValue' ),
$topValidator );
+ }
+
+ /**
+ * @param string[] $urlSchemes List of URL schemes, e.g. 'http'
+ * @param int $maxLength Defaults to 500 characters. Even if URLs are
unlimited in theory they
+ * should be limited to about 2000. About 500 is a reasonable
compromise.
+ * @see http://stackoverflow.com/a/417184
+ *
+ * @return CompositeValidator
+ */
+ private function getUrlValidator( $urlSchemes, $maxLength = 500 ) {
+ $validators = array();
+ $validators[] = new TypeValidator( 'string' );
+ $validators[] = new StringLengthValidator( 2, $maxLength );
+
+ $urlValidators = new UrlSchemeValidators();
+ $urlSchemeValidators = $urlValidators->getValidator(
$urlSchemes );
+ $validators[] = new UrlValidator( $urlSchemeValidators );
+
+ return new CompositeValidator( $validators ); //Note: each
validator is fatal
+ }
+
+ /**
+ * @return ValueValidator[]
+ */
+ public function buildUrlValidators( ) {
+ $urlValidator = $this->getUrlValidator( $this->urlSchemes );
+
+ $topValidator = new DataValueValidator(
+ $urlValidator
+ );
+
+ return array( new TypeValidator( 'DataValues\DataValue' ),
$topValidator );
+ }
+
+ /**
+ * @return ValueValidator[]
+ */
+ public function buildQuantityValidators( ) {
+ $validators = array();
+ $validators[] = new TypeValidator( 'array' );
+
+ // the 'amount' field is already validated by QuantityValue's
constructor
+ // the 'digits' field is already validated by QuantityValue's
constructor
+
+ $unitValidators = new AlternativeValidator( array(
+ // NOTE: "1" is always considered legal for historical
reasons,
+ // since we use it to represent "unitless" quantities.
We could also use
+ // http://qudt.org/vocab/unit#Unitless or
https://www.wikidata.org/entity/Q199
+ new MembershipValidator( array( '1' ) ),
+ $this->getUrlValidator( array( 'http', 'https' ), 255 ),
+ ) );
+ $validators[] = new DataFieldValidator( 'unit', $unitValidators
);
+
+ $topValidator = new DataValueValidator(
+ new CompositeValidator( $validators ) //Note: each
validator is fatal
+ );
+
+ return array( new TypeValidator( 'DataValues\QuantityValue' ),
$topValidator );
+ }
+
+}
diff --git a/repo/includes/Validators/SnakValidator.php
b/repo/includes/Validators/SnakValidator.php
index 14aa045..d1bbbd1 100644
--- a/repo/includes/Validators/SnakValidator.php
+++ b/repo/includes/Validators/SnakValidator.php
@@ -17,6 +17,7 @@
use Wikibase\DataModel\Snak\PropertyValueSnak;
use Wikibase\DataModel\Snak\Snak;
use Wikibase\DataModel\Statement\Statement;
+use Wikibase\Repo\DataTypeValidatorFactory;
/**
* Class SnakValidator for validating Snaks.
@@ -29,21 +30,28 @@
class SnakValidator implements ValueValidator {
/**
+ * @var DataTypeFactory
+ */
+ private $dataTypeFactory;
+
+ /**
* @var PropertyDataTypeLookup
*/
private $propertyDataTypeLookup;
/**
- * @var DataTypeFactory
+ * @var DataTypeValidatorFactory
*/
- private $dataTypeFactory;
+ private $validatorFactory;
public function __construct(
PropertyDataTypeLookup $propertyDataTypeLookup,
- DataTypeFactory $dataTypeFactory
+ DataTypeFactory $dataTypeFactory,
+ DataTypeValidatorFactory $validatorFactory
) {
- $this->propertyDataTypeLookup = $propertyDataTypeLookup;
$this->dataTypeFactory = $dataTypeFactory;
+ $this->propertyDataTypeLookup = $propertyDataTypeLookup;
+ $this->validatorFactory = $validatorFactory;
}
/**
@@ -174,7 +182,7 @@
* @return Result
*/
public function validateDataValue( DataValue $dataValue, $dataTypeId ) {
- $dataType = $this->dataTypeFactory->getType( $dataTypeId );
+ $dataValueType = $this->dataTypeFactory->getType( $dataTypeId
)->getDataValueType();
if ( $dataValue instanceof UnDeserializableValue ) {
$result = Result::newError( array(
@@ -185,22 +193,21 @@
array( $dataValue->getReason() )
),
) );
- } elseif ( $dataType->getDataValueType() !=
$dataValue->getType() ) {
+ } elseif ( $dataValueType != $dataValue->getType() ) {
$result = Result::newError( array(
Error::newError(
- 'Bad value type: ' .
$dataValue->getType() . ', expected ' . $dataType->getDataValueType(),
+ 'Bad value type: ' .
$dataValue->getType() . ', expected ' . $dataValueType,
null,
'bad-value-type',
- array( $dataValue->getType(),
$dataType->getDataValueType() )
+ array( $dataValue->getType(),
$dataValueType )
),
) );
} else {
$result = Result::newSuccess();
}
- //XXX: Perhaps DataType should have a validate() method (even
implement ValueValidator)
- // At least, DataType should expose only one validator,
which would be a CompositeValidator
- foreach ( $dataType->getValidators() as $validator ) {
+ //XXX: DataTypeValidatorFactory should expose only one
validator, which would be a CompositeValidator
+ foreach ( $this->validatorFactory->getValidators(
$dataValueType ) as $validator ) {
$subResult = $validator->validate( $dataValue );
//XXX: Some validators should be fatal and cause us to
abort the loop.
diff --git a/repo/includes/WikibaseRepo.php b/repo/includes/WikibaseRepo.php
index fbfbe04..c48d125 100644
--- a/repo/includes/WikibaseRepo.php
+++ b/repo/includes/WikibaseRepo.php
@@ -211,12 +211,7 @@
*/
public function getDataTypeFactory() {
if ( $this->dataTypeFactory === null ) {
- $urlSchemes = $this->settings->getSetting( 'urlSchemes'
);
- $builders = new WikibaseDataTypeBuilders(
- $this->getEntityLookup(),
- $this->getEntityIdParser(),
- $urlSchemes
- );
+ $builders = new WikibaseDataTypeBuilders();
$typeBuilderSpecs = array_intersect_key(
$builders->getDataTypeBuilders(),
@@ -424,7 +419,8 @@
public function getSnakValidator() {
return new SnakValidator(
$this->getPropertyDataTypeLookup(),
- $this->getDataTypeFactory()
+ $this->getDataTypeFactory(),
+ $this->getDataTypeValidatorFactory()
);
}
@@ -1030,4 +1026,16 @@
);
}
+ private function getDataTypeValidatorFactory() {
+ $urlSchemes = $this->settings->getSetting( 'urlSchemes' );
+
+ return new DataTypeValidatorFactory(
+ new ValidatorBuilders(
+ $this->getEntityLookup(),
+ $this->getEntityIdParser(),
+ $urlSchemes
+ )
+ );
+ }
+
}
--
To view, visit https://gerrit.wikimedia.org/r/189731
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: I6fb14c135315c7c064ccf49c019670dfab68c857
Gerrit-PatchSet: 1
Gerrit-Project: mediawiki/extensions/Wikibase
Gerrit-Branch: master
Gerrit-Owner: Adrian Lang <[email protected]>
_______________________________________________
MediaWiki-commits mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits