jenkins-bot has submitted this change and it was merged.
Change subject: Define external-id datatype
......................................................................
Define external-id datatype
DEPLOY: Make sure we don't start using the new datatype in the repo
until all client wikis also have the new code (or at least I3074ac0f).
Bug: T95682
Change-Id: I00c38a51cd22966778f47fa0f1c296c7eac33f0f
---
M client/includes/WikibaseClient.php
M lib/WikibaseLib.datatypes.php
M lib/config/WikibaseLib.default.php
M lib/i18n/en.json
M lib/i18n/qqq.json
M lib/includes/formatters/DispatchingSnakFormatter.php
M lib/includes/formatters/PropertyValueSnakFormatter.php
A lib/includes/formatters/WikibaseSnakFormatterBuilders.php
M lib/tests/phpunit/formatters/DispatchingSnakFormatterTest.php
M lib/tests/phpunit/formatters/PropertyValueSnakFormatterTest.php
A lib/tests/phpunit/formatters/WikibaseSnakFormatterBuildersTest.php
M repo/WikibaseRepo.datatypes.php
M repo/i18n/en.json
M repo/i18n/qqq.json
M repo/includes/WikibaseRepo.php
M repo/includes/specials/SpecialListDatatypes.php
16 files changed, 439 insertions(+), 15 deletions(-)
Approvals:
Thiemo Mättig (WMDE): Looks good to me, approved
jenkins-bot: Verified
diff --git a/client/includes/WikibaseClient.php
b/client/includes/WikibaseClient.php
index b92ca27..12f5f9c 100644
--- a/client/includes/WikibaseClient.php
+++ b/client/includes/WikibaseClient.php
@@ -60,6 +60,7 @@
use Wikibase\Lib\PropertyInfoDataTypeLookup;
use Wikibase\Lib\Store\EntityContentDataCodec;
use Wikibase\Lib\MediaWikiContentLanguages;
+use Wikibase\Lib\WikibaseSnakFormatterBuilders;
use Wikibase\Lib\WikibaseValueFormatterBuilders;
use Wikibase\Lib\Interactors\TermIndexSearchInteractor;
use Wikibase\NamespaceChecker;
@@ -213,6 +214,48 @@
}
/**
+ * Returns the default WikibaseSnakFormatterBuilders instance.
+ * @warning This is for use with bootstrap code in
WikibaseClient.datatypes.php only!
+ * Program logic should use WikibaseClient::getSnakFormatterFactory()
instead!
+ *
+ * @since 0.5
+ *
+ * @param string $reset Flag: Pass "reset" to reset the default instance
+ *
+ * @return WikibaseSnakFormatterBuilders
+ */
+ public static function getDefaultSnakFormatterBuilders( $reset =
'noreset' ) {
+ static $builders;
+
+ if ( $builders === null || $reset === 'reset' ) {
+ $builders =
self::getDefaultInstance()->newWikibaseSnakFormatterBuilders(
+ self::getDefaultFormatterBuilders()
+ );
+ }
+
+ return $builders;
+ }
+
+ /**
+ * Returns a low level factory object for creating formatters for well
known data types.
+ *
+ * @warning This is for use with getDefaultFormatterBuilders() during
bootstrap only!
+ * Program logic should use WikibaseClient::getSnakFormatterFactory()
instead!
+ *
+ * @param WikibaseValueFormatterBuilders $valueFormatterBuilders
+ *
+ * @return WikibaseSnakFormatterBuilders
+ */
+ private function newWikibaseSnakFormatterBuilders(
WikibaseValueFormatterBuilders $valueFormatterBuilders ) {
+ return new WikibaseSnakFormatterBuilders(
+ $valueFormatterBuilders,
+ $this->getStore()->getPropertyInfoStore(),
+ $this->getPropertyDataTypeLookup(),
+ $this->getDataTypeFactory()
+ );
+ }
+
+ /**
* @param SettingsArray $settings
* @param Language $contentLanguage
* @param DataTypeDefinitions $dataTypeDefinitions
diff --git a/lib/WikibaseLib.datatypes.php b/lib/WikibaseLib.datatypes.php
index 642bee0..b879d8b 100644
--- a/lib/WikibaseLib.datatypes.php
+++ b/lib/WikibaseLib.datatypes.php
@@ -22,6 +22,7 @@
'PT:string' => array( 'value-type' => 'string' ),
'PT:time' => array( 'value-type' => 'time' ),
'PT:url' => array( 'value-type' => 'string' ),
+ 'PT:external-id' => array( 'value-type' => 'string' ),
'PT:wikibase-item' => array( 'value-type' => 'wikibase-entityid' ),
'PT:wikibase-property' => array( 'value-type' => 'wikibase-entityid' ),
);
diff --git a/lib/config/WikibaseLib.default.php
b/lib/config/WikibaseLib.default.php
index 1e2ce32..de19c74 100644
--- a/lib/config/WikibaseLib.default.php
+++ b/lib/config/WikibaseLib.default.php
@@ -68,6 +68,7 @@
'string',
'time',
'url',
+ 'external-id',
'wikibase-item',
'wikibase-property',
),
diff --git a/lib/i18n/en.json b/lib/i18n/en.json
index f869813..1eeff22 100644
--- a/lib/i18n/en.json
+++ b/lib/i18n/en.json
@@ -71,6 +71,7 @@
"datatypes-type-wikibase-item": "Item",
"datatypes-type-wikibase-property": "Property",
"datatypes-type-commonsMedia": "Commons media file",
+ "datatypes-type-external-id": "External identifier",
"version-wikibase": "Wikibase",
"wikibase-time-precision-Gannum": "$1 billion years CE",
"wikibase-time-precision-Mannum": "$1 million years CE",
diff --git a/lib/i18n/qqq.json b/lib/i18n/qqq.json
index b4112ac..6a01306 100644
--- a/lib/i18n/qqq.json
+++ b/lib/i18n/qqq.json
@@ -81,6 +81,7 @@
"datatypes-type-wikibase-item": "The name of a data type for items in
Wikibase.\n{{Identical|Item}}",
"datatypes-type-wikibase-property": "The name of a data type for
properties in Wikibase.\n{{Identical|Property}}",
"datatypes-type-commonsMedia": "The name of a data type for media files
on Wikimedia Commons (proper name, capitalised in English; first letter
capitalised anyway in this message and
relatives).\n\n{{related|Datatypes-type}}",
+ "datatypes-type-external-id": "The name of a data type for external
identifiers in Wikibase.",
"version-wikibase": "Name of the Wikibase extension collection, used on
[[Special:Version]]",
"wikibase-time-precision-Gannum": "Used to present a point in time with
the precession of 1 billion of years. $1 is the point in time in billion years,
rounded to billion years.\n{{Related|Wikibase-time-precision}}",
"wikibase-time-precision-Mannum": "Used to present a point in time with
the precession of 1 million of years. $1 is the point in time in million years,
rounded to million years.\n{{Related|Wikibase-time-precision}}",
diff --git a/lib/includes/formatters/DispatchingSnakFormatter.php
b/lib/includes/formatters/DispatchingSnakFormatter.php
index 081b1a1..fd7467f 100644
--- a/lib/includes/formatters/DispatchingSnakFormatter.php
+++ b/lib/includes/formatters/DispatchingSnakFormatter.php
@@ -39,8 +39,11 @@
private $formattersBySnakType;
/**
- * @param string $format The output format generated by this formatter.
All formatters
- * provided to the constructor must produce the same output format.
+ * @param string $format The output format generated by this formatter.
All SnakFormatters
+ * provided via $formattersBySnakType and $formattersByDataType must
be safe for this
+ * output format. This is checked by comparing the $format with what
each SnakFormatter
+ * returns from getFormat(). MIME parameters are ignored for this
check, so FORMAT_HTML
+ * is considered compatible with FORMAT_HTML_DIFF, etc.
* @param PropertyDataTypeLookup $dataTypeLookup
* @param SnakFormatter[] $formattersBySnakType An associative array
mapping snak types
* to SnakFormatter objects. If no formatter is defined for the a
given snak type,
@@ -49,7 +52,9 @@
* to SnakFormatter objects. If no formatter is defined for the a
given data type,
* the "*" key in this array is checked for a default formatter.
*
- * @throws InvalidArgumentException
+ * @throws InvalidArgumentException If any of the given formatters is
incompatible
+ * with $format. Formats are assumed to be represented by MIME
types,
+ * MIME parameters are ignored.
*/
public function __construct(
$format,
@@ -78,7 +83,10 @@
throw new InvalidArgumentException( 'formatter
array must contain instances of SnakFormatter.' );
}
- if ( $formatter->getFormat() !== $format ) {
+ // Ignore MIME parameters when checking output format.
We only care that the base format
+ // is the same, so we can assume that all formatters
apply the correct escaping and are
+ // safe to use.
+ if ( $this->getBaseFormat( $formatter->getFormat() )
!== $this->getBaseFormat( $format ) ) {
throw new InvalidArgumentException( 'The
formatter supplied for ' . $type
. ' produces ' .
$formatter->getFormat() . ', but we expect ' . $format . '.' );
}
@@ -86,6 +94,15 @@
}
/**
+ * @param string $format MIME type
+ *
+ * @return string MIME type with parameters stripped.
+ */
+ private function getBaseFormat( $format ) {
+ return preg_replace( '/ *;.*$/', '', $format );
+ }
+
+ /**
* @param Snak $snak
*
* @throws PropertyDataTypeLookupException
diff --git a/lib/includes/formatters/PropertyValueSnakFormatter.php
b/lib/includes/formatters/PropertyValueSnakFormatter.php
index d3e5a66..a00d008 100644
--- a/lib/includes/formatters/PropertyValueSnakFormatter.php
+++ b/lib/includes/formatters/PropertyValueSnakFormatter.php
@@ -10,6 +10,7 @@
use ValueFormatters\Exceptions\MismatchingDataValueTypeException;
use ValueFormatters\FormatterOptions;
use ValueFormatters\FormattingException;
+use ValueFormatters\ValueFormatter;
use Wikibase\DataModel\Services\Lookup\PropertyDataTypeLookup;
use Wikibase\DataModel\Services\Lookup\PropertyDataTypeLookupException;
use Wikibase\DataModel\Snak\PropertyValueSnak;
@@ -35,7 +36,7 @@
private $options;
/**
- * @var TypedValueFormatter
+ * @var ValueFormatter
*/
private $valueFormatter;
@@ -53,7 +54,7 @@
* @param string $format The name of this formatter's output format.
* Use the FORMAT_XXX constants defined in SnakFormatter.
* @param FormatterOptions|null $options
- * @param TypedValueFormatter $valueFormatter
+ * @param ValueFormatter $valueFormatter
* @param PropertyDataTypeLookup $typeLookup
* @param DataTypeFactory $dataTypeFactory
*
@@ -62,7 +63,7 @@
public function __construct(
$format,
FormatterOptions $options = null,
- TypedValueFormatter $valueFormatter,
+ ValueFormatter $valueFormatter,
PropertyDataTypeLookup $typeLookup,
DataTypeFactory $dataTypeFactory
) {
@@ -171,7 +172,11 @@
*/
private function formatValue( DataValue $value, $dataTypeId = null ) {
if ( !$this->isUnDeserializableValue( $value ) ) {
- $text = $this->valueFormatter->formatValue( $value,
$dataTypeId );
+ if ( $this->valueFormatter instanceof
TypedValueFormatter ) {
+ $text = $this->valueFormatter->formatValue(
$value, $dataTypeId );
+ } else {
+ $text = $this->valueFormatter->format( $value );
+ }
} else {
$text = '';
}
diff --git a/lib/includes/formatters/WikibaseSnakFormatterBuilders.php
b/lib/includes/formatters/WikibaseSnakFormatterBuilders.php
new file mode 100644
index 0000000..7293e2d
--- /dev/null
+++ b/lib/includes/formatters/WikibaseSnakFormatterBuilders.php
@@ -0,0 +1,148 @@
+<?php
+
+namespace Wikibase\Lib;
+
+use DataTypes\DataTypeFactory;
+use InvalidArgumentException;
+use ValueFormatters\FormatterOptions;
+use Wikibase\DataModel\Services\Lookup\PropertyDataTypeLookup;
+use Wikibase\Lib\Formatters\HtmlExternalIdentifierFormatter;
+use Wikibase\Lib\Formatters\WikitextExternalIdentifierFormatter;
+use Wikibase\PropertyInfoStore;
+
+/**
+ * Low level factory for SnakFormatters for well known data types.
+ *
+ * @warning: This is a low level factory for use by boostrap code only!
+ * Program logic should use an instance of OutputFormatValueFormatterFactory
+ * resp. OutputFormatSnakFormatterFactory.
+ *
+ * @since 0.5
+ *
+ * @licence GNU GPL v2+
+ * @author Daniel Kinzler
+ */
+class WikibaseSnakFormatterBuilders {
+
+ /**
+ * @var WikibaseValueFormatterBuilders
+ */
+ private $valueFormatterBuilders;
+
+ /**
+ * @var PropertyInfoStore
+ */
+ private $propertyInfoStore;
+
+ /**
+ * @var PropertyDataTypeLookup
+ */
+ private $dataTypeLookup;
+
+ /**
+ * @var DataTypeFactory
+ */
+ private $dataTypeFactory;
+
+ /**
+ * @param WikibaseValueFormatterBuilders $valueFormatterBuilders
+ */
+ public function __construct(
+ WikibaseValueFormatterBuilders $valueFormatterBuilders,
+ PropertyInfoStore $propertyInfoStore,
+ PropertyDataTypeLookup $dataTypeLookup,
+ DataTypeFactory $dataTypeFactory
+ ) {
+ $this->valueFormatterBuilders = $valueFormatterBuilders;
+ $this->propertyInfoStore = $propertyInfoStore;
+ $this->dataTypeLookup = $dataTypeLookup;
+ $this->dataTypeFactory = $dataTypeFactory;
+ }
+
+ /**
+ * @param string $format One of the SnakFormatter::FORMAT_... constants.
+ *
+ * @throws InvalidArgumentException
+ * @return string Either SnakFormatter::FORMAT_HTML, ...WIKI or
...PLAIN.
+ */
+ private function getBaseFormat( $format ) {
+ switch ( $format ) {
+ case SnakFormatter::FORMAT_HTML:
+ case SnakFormatter::FORMAT_HTML_DIFF:
+ case SnakFormatter::FORMAT_HTML_WIDGET:
+ return SnakFormatter::FORMAT_HTML;
+ case SnakFormatter::FORMAT_WIKI:
+ case SnakFormatter::FORMAT_PLAIN:
+ return $format;
+ }
+
+ throw new InvalidArgumentException( 'Unsupported output format:
' . $format );
+ }
+
+ /**
+ * @param string $format The desired target format, see
SnakFormatter::FORMAT_XXX
+ *
+ * @throws InvalidArgumentException
+ * @return bool True if $format is one of the
SnakFormatter::FORMAT_HTML_XXX formats.
+ */
+ private function isHtmlFormat( $format ) {
+ return $this->getBaseFormat( $format ) ===
SnakFormatter::FORMAT_HTML;
+ }
+
+ /**
+ * Wraps the given formatter in an EscapingSnakFormatter if necessary.
+ *
+ * @param string $format The desired target format, see
SnakFormatter::FORMAT_XXX
+ * @param SnakFormatter $formatter The plain text formatter to wrap.
+ *
+ * @throws InvalidArgumentException
+ * @return SnakFormatter
+ */
+ private function escapeSnakFormatter( $format, SnakFormatter $formatter
) {
+ switch ( $this->getBaseFormat( $format ) ) {
+ case SnakFormatter::FORMAT_HTML:
+ return new EscapingSnakFormatter( $format,
$formatter, 'htmlspecialchars' );
+ case SnakFormatter::FORMAT_WIKI:
+ return new EscapingSnakFormatter( $format,
$formatter, 'wfEscapeWikiText' );
+ case SnakFormatter::FORMAT_PLAIN:
+ return $formatter;
+ }
+
+ throw new InvalidArgumentException( 'Unsupported output format:
' . $format );
+ }
+
+ /**
+ * @param string $format The desired target format, see
SnakFormatter::FORMAT_XXX
+ * @param FormatterOptions $options
+ *
+ * @throws InvalidArgumentException
+ * @return SnakFormatter
+ */
+ public function newExternalIdentifierFormatter( $format,
FormatterOptions $options ) {
+ if ( $format === SnakFormatter::FORMAT_PLAIN ) {
+ return new PropertyValueSnakFormatter(
+ $format,
+ $options,
+
$this->valueFormatterBuilders->newStringFormatter( $format, $options ),
+ $this->dataTypeLookup,
+ $this->dataTypeFactory
+ );
+ }
+
+ $urlProvider = new FieldPropertyInfoProvider(
+ $this->propertyInfoStore,
+ PropertyInfoStore::KEY_FORMATTER_URL
+ );
+
+ $urlExpander = new PropertyInfoSnakUrlExpander( $urlProvider );
+
+ if ( $format === SnakFormatter::FORMAT_WIKI ) {
+ return new WikitextExternalIdentifierFormatter(
$urlExpander );
+ } elseif ( $this->isHtmlFormat( $format ) ) {
+ return new HtmlExternalIdentifierFormatter(
$urlExpander );
+ }
+
+ throw new InvalidArgumentException( 'Unsupported output format:
' . $format );
+ }
+
+}
diff --git a/lib/tests/phpunit/formatters/DispatchingSnakFormatterTest.php
b/lib/tests/phpunit/formatters/DispatchingSnakFormatterTest.php
index 76c92cc..10de96d 100644
--- a/lib/tests/phpunit/formatters/DispatchingSnakFormatterTest.php
+++ b/lib/tests/phpunit/formatters/DispatchingSnakFormatterTest.php
@@ -62,6 +62,44 @@
}
/**
+ * @dataProvider constructorProvider
+ */
+ public function testConstructor( $format, array $formattersBySnakType,
array $formattersByDataType ) {
+ $dataTypeLookup = $this->getDataTypeLookup();
+
+ new DispatchingSnakFormatter(
+ $format,
+ $dataTypeLookup,
+ $formattersBySnakType,
+ $formattersByDataType
+ );
+
+ // we are just checking that the constructor did not throw an
exception
+ $this->assertTrue( true );
+ }
+
+ public function constructorProvider() {
+ $formatter = new MessageSnakFormatter(
+ 'novalue',
+ wfMessage( 'wikibase-snakview-snaktypeselector-novalue'
),
+ SnakFormatter::FORMAT_HTML_DIFF
+ );
+
+ return array(
+ 'plain constructor call' => array(
+ SnakFormatter::FORMAT_HTML_DIFF,
+ array( 'novalue' => $formatter ),
+ array( 'string' => $formatter ),
+ ),
+ 'constructor call with formatters for base format ID'
=> array(
+ SnakFormatter::FORMAT_HTML,
+ array( 'novalue' => $formatter ),
+ array( 'string' => $formatter ),
+ ),
+ );
+ }
+
+ /**
* @dataProvider constructorErrorsProvider
*/
public function testConstructorErrors( $format, array
$formattersBySnakType, array $formattersByDataType ) {
diff --git a/lib/tests/phpunit/formatters/PropertyValueSnakFormatterTest.php
b/lib/tests/phpunit/formatters/PropertyValueSnakFormatterTest.php
index 22675a2..4ac73f0 100644
--- a/lib/tests/phpunit/formatters/PropertyValueSnakFormatterTest.php
+++ b/lib/tests/phpunit/formatters/PropertyValueSnakFormatterTest.php
@@ -7,6 +7,8 @@
use DataValues\StringValue;
use DataValues\UnDeserializableValue;
use ValueFormatters\FormatterOptions;
+use ValueFormatters\StringFormatter;
+use ValueFormatters\ValueFormatter;
use Wikibase\DataModel\Entity\PropertyId;
use Wikibase\DataModel\Services\Lookup\PropertyDataTypeLookup;
use Wikibase\DataModel\Services\Lookup\PropertyDataTypeLookupException;
@@ -91,7 +93,7 @@
* @dataProvider formatSnakProvider
*/
public function testFormatSnak(
- $snak, $dataType, $valueType, $targetFormat, $formatters,
+ $snak, $dataType, $valueType, $targetFormat, ValueFormatter
$formatter,
$expected, $expectedException = null
) {
if ( $expectedException !== null ) {
@@ -108,7 +110,7 @@
$formatter = new PropertyValueSnakFormatter(
$targetFormat,
$options,
- new DispatchingValueFormatter( $formatters ),
+ $formatter,
$typeLookup,
$typeFactory
);
@@ -134,13 +136,15 @@
'PT:commonsMedia' => $this->getMockFormatter(
'PT:commonsMedia' )
);
+ $dispatchingFormatter = new DispatchingValueFormatter(
$formatters );
+
return array(
'match PT' => array(
new PropertyValueSnak( 17, new StringValue(
'Foo.jpg' ) ),
'commonsMedia',
'string',
SnakFormatter::FORMAT_PLAIN,
- $formatters,
+ $dispatchingFormatter,
'/^PT:commonsMedia$/'
),
@@ -149,8 +153,17 @@
'someStuff',
'string',
SnakFormatter::FORMAT_WIKI,
- $formatters,
+ $dispatchingFormatter,
'/^VT:string$/'
+ ),
+
+ 'use plain value formatter' => array(
+ new PropertyValueSnak( 33, new StringValue(
'something' ) ),
+ 'url',
+ 'string',
+ SnakFormatter::FORMAT_WIKI,
+ new StringFormatter(),
+ '/^something$/'
),
'UnDeserializableValue, fail' => array(
@@ -160,7 +173,7 @@
'globe-coordinate',
'globecoordinate',
SnakFormatter::FORMAT_HTML,
- $formatters,
+ $dispatchingFormatter,
null,
'ValueFormatters\Exceptions\MismatchingDataValueTypeException'
),
@@ -170,7 +183,7 @@
'url',
'iri', // url expects an iri, but will get a
string
SnakFormatter::FORMAT_WIKI,
- $formatters,
+ $dispatchingFormatter,
null,
'ValueFormatters\Exceptions\MismatchingDataValueTypeException'
),
@@ -180,7 +193,7 @@
'', // triggers an exception from the mock
PropertyDataTypeLookup
'xxx', // should not be used
SnakFormatter::FORMAT_HTML,
- $formatters,
+ $dispatchingFormatter,
null,
'Wikibase\DataModel\Services\Lookup\PropertyDataTypeLookupException'
),
diff --git a/lib/tests/phpunit/formatters/WikibaseSnakFormatterBuildersTest.php
b/lib/tests/phpunit/formatters/WikibaseSnakFormatterBuildersTest.php
new file mode 100644
index 0000000..719bc69
--- /dev/null
+++ b/lib/tests/phpunit/formatters/WikibaseSnakFormatterBuildersTest.php
@@ -0,0 +1,94 @@
+<?php
+
+namespace Wikibase\Lib\Test;
+
+use DataTypes\DataTypeFactory;
+use DataValues\StringValue;
+use ValueFormatters\FormatterOptions;
+use ValueFormatters\StringFormatter;
+use Wikibase\DataModel\Entity\PropertyId;
+use Wikibase\DataModel\Services\Lookup\InMemoryDataTypeLookup;
+use Wikibase\DataModel\Snak\PropertyValueSnak;
+use Wikibase\DataModel\Snak\Snak;
+use Wikibase\Lib\SnakFormatter;
+use Wikibase\Lib\WikibaseSnakFormatterBuilders;
+use Wikibase\PropertyInfoStore;
+use Wikibase\Test\MockPropertyInfoStore;
+
+/**
+ * @covers Wikibase\Lib\WikibaseSnakFormatterBuilders
+ *
+ * @group SnakFormatters
+ * @group DataValueExtensions
+ * @group WikibaseLib
+ * @group Wikibase
+ *
+ * @licence GNU GPL v2+
+ * @author Daniel Kinzler
+ */
+class WikibaseSnakFormatterBuildersTest extends \PHPUnit_Framework_TestCase {
+
+ /**
+ * @return WikibaseSnakFormatterBuilders
+ */
+ private function getWikibaseSnakFormatterBuilders() {
+ $p1 = new PropertyId( 'P1' );
+
+ $valueFormatterBuilders = $this->getMockBuilder(
'Wikibase\Lib\WikibaseValueFormatterBuilders' )
+ ->disableOriginalConstructor()
+ ->getMock();
+
+ $valueFormatterBuilders->expects( $this->any() )
+ ->method( 'newStringFormatter' )
+ ->will( $this->returnValue( new StringFormatter() ) );
+
+ $propertyInfoStore = new MockPropertyInfoStore();
+ $propertyInfoStore->setPropertyInfo( $p1, array(
+ PropertyInfoStore::KEY_DATA_TYPE => 'external-id',
+ PropertyInfoStore::KEY_FORMATTER_URL =>
'http://acme.com/vocab/$1',
+ ) );
+
+ $dataTypeLookup = new InMemoryDataTypeLookup();
+ $dataTypeLookup->setDataTypeForProperty( $p1, 'external-id' );
+
+ $dataTypeFactory = new DataTypeFactory( array( 'external-id' =>
'string' ) );
+
+ return new WikibaseSnakFormatterBuilders(
+ $valueFormatterBuilders,
+ $propertyInfoStore,
+ $dataTypeLookup,
+ $dataTypeFactory
+ );
+ }
+
+ public function provideNewExternalIdentifierFormatter() {
+ $p1 = new PropertyId( 'P1' );
+ $snak = new PropertyValueSnak( $p1, new StringValue( 'AB123' )
);
+
+ return array(
+ array( $snak, SnakFormatter::FORMAT_PLAIN, 'AB123' ),
+ array( $snak, SnakFormatter::FORMAT_WIKI,
'[http://acme.com/vocab/AB123 AB123]' ),
+ array( $snak, SnakFormatter::FORMAT_HTML, '<a
class="wb-external-id" href="http://acme.com/vocab/AB123">AB123</a>' ),
+ );
+ }
+
+ /**
+ * @dataProvider provideNewExternalIdentifierFormatter
+ */
+ public function testNewExternalIdentifierFormatter( Snak $snak,
$format, $expected ) {
+ $options = new FormatterOptions();
+ $builders = $this->getWikibaseSnakFormatterBuilders();
+ $formatter = $builders->newExternalIdentifierFormatter(
$format, $options );
+ $actual = $formatter->formatSnak( $snak );
+ $this->assertSame( $expected, $actual );
+ }
+
+ public function testNewExternalIdentifierFormatter_bad_format() {
+ $options = new FormatterOptions();
+ $builders = $this->getWikibaseSnakFormatterBuilders();
+
+ $this->setExpectedException( 'InvalidArgumentException' );
+ $builders->newExternalIdentifierFormatter( 'unknown', $options
);
+ }
+
+}
diff --git a/repo/WikibaseRepo.datatypes.php b/repo/WikibaseRepo.datatypes.php
index 40e2318..174bd25 100644
--- a/repo/WikibaseRepo.datatypes.php
+++ b/repo/WikibaseRepo.datatypes.php
@@ -239,6 +239,19 @@
return new ObjectUriRdfBuilder();
},
),
+ 'PT:id' => array(
+ 'validator-factory-callback' => function() {
+ $factory =
WikibaseRepo::getDefaultValidatorBuilders();
+ return $factory->buildStringValidators();
+ },
+ 'parser-factory-callback' => $newStringParser,
+ // NOTE: for 'formatter-factory-callback', we fall back
to plain text formatting
+ 'snak-formatter-factory-callback' => function( $format,
FormatterOptions $options ) {
+ $factory =
WikibaseRepo::getDefaultSnakFormatterBuilders();
+ return
$factory->newExternalIdentifierFormatter( $format, $options );
+ },
+ // TODO: RDF mapping using canonical URI patterns
+ ),
'VT:wikibase-entityid' => array(
'validator-factory-callback' => function() {
$factory =
WikibaseRepo::getDefaultValidatorBuilders();
diff --git a/repo/i18n/en.json b/repo/i18n/en.json
index 5fd946d..2d63dac 100644
--- a/repo/i18n/en.json
+++ b/repo/i18n/en.json
@@ -360,6 +360,8 @@
"wikibase-listdatatypes-time-body": "Literal data field for a point in
time. Given as a date and time with some precision and boundaries. The time is
saved internally in the specified calendar model.\n* time – explicit value for
point in time, represented as a timestamp resembling ISO 8601, e.g.
+2013-01-01T00:00:00Z. The year is always signed and padded to have between 4
and 16 digits.\n* timezone – explicit value as a signed integer. Timezone
information as an offset from UTC in minutes.\n* before – explicit integer
value for how many units after the given time it could be. The unit is given by
the precision.\n* after – explicit integer value for how many units before the
given time it could be. The unit is given by the precision.\n* precision –
explicit value encoded in a shortint. The numbers have the following meaning: 0
- billion years, 1 - hundred million years, ..., 6 - millennium, 7 - century, 8
- decade, 9 - year, 10 - month, 11 - day, 12 - hour, 13 - minute, 14 -
second.\n* calendarmodel – explicit value given as a URI. It identifies the
calendar model of the timestamp.",
"wikibase-listdatatypes-url-head": "URL",
"wikibase-listdatatypes-url-body": "Literal data field for a URL. URLs
are restricted to the protocols also supported for external links in wikitext.",
+ "wikibase-listdatatypes-external-id-head": "External identifier",
+ "wikibase-listdatatypes-external-id-body": "Literal data field for an
external identifier. External identifiers may automatically be linked to an
authoritative resource for display.",
"wikibase-concept-uri": "Concept URI",
"wikibase-concept-uri-tooltip": "URI that identifies the concept
described by this item",
"wikibase-add-badges": "Add badges",
diff --git a/repo/i18n/qqq.json b/repo/i18n/qqq.json
index bc1b925..a6ebc52 100644
--- a/repo/i18n/qqq.json
+++ b/repo/i18n/qqq.json
@@ -389,6 +389,8 @@
"wikibase-listdatatypes-time-body": "{{Wikibase-datatype-body|Time}}",
"wikibase-listdatatypes-url-head":
"{{Wikibase-datatype-head|Url}}\n{{Identical|URL}}",
"wikibase-listdatatypes-url-body": "{{Wikibase-datatype-body|Url}}",
+ "wikibase-listdatatypes-external-id-head":
"{{Wikibase-datatype-head|External identifier|external-id}}",
+ "wikibase-listdatatypes-external-id-body":
"{{Wikibase-datatype-body|External identifier}}",
"wikibase-concept-uri": "Label for a link in the toolbox on entity
pages. Target of the link is the one and specific URI for the entity's concept
(\"canonical concept link\").",
"wikibase-concept-uri-tooltip": "Text for the canonical concept link in
toolbox on entity pages.",
"wikibase-add-badges": "Title for an empty (dummy) badge sign that asks
the user to add badges to a sitelink.",
diff --git a/repo/includes/WikibaseRepo.php b/repo/includes/WikibaseRepo.php
index 4bca1f1..34f38b1 100644
--- a/repo/includes/WikibaseRepo.php
+++ b/repo/includes/WikibaseRepo.php
@@ -37,6 +37,7 @@
use Wikibase\DataModel\Services\Statement\StatementGuidValidator;
use Wikibase\EditEntityFactory;
use Wikibase\EntityFactory;
+use Wikibase\Lib\WikibaseSnakFormatterBuilders;
use Wikibase\Repo\ParserOutput\EntityParserOutputGeneratorFactory;
use Wikibase\InternalSerialization\DeserializerFactory as
InternalDeserializerFactory;
use Wikibase\InternalSerialization\SerializerFactory as
InternalSerializerFactory;
@@ -322,6 +323,48 @@
}
/**
+ * Returns the default WikibaseSnakFormatterBuilders instance.
+ * @warning This is for use with bootstrap code in
WikibaseRepo.datatypes.php only!
+ * Program logic should use WikibaseRepo::getSnakFormatterFactory()
instead!
+ *
+ * @since 0.5
+ *
+ * @param string $reset Flag: Pass "reset" to reset the default instance
+ *
+ * @return WikibaseSnakFormatterBuilders
+ */
+ public static function getDefaultSnakFormatterBuilders( $reset =
'noreset' ) {
+ static $builders;
+
+ if ( $builders === null || $reset === 'reset' ) {
+ $builders =
self::getDefaultInstance()->newWikibaseSnakFormatterBuilders(
+ self::getDefaultFormatterBuilders()
+ );
+ }
+
+ return $builders;
+ }
+
+ /**
+ * Returns a low level factory object for creating formatters for well
known data types.
+ *
+ * @warning This is for use with getDefaultFormatterBuilders() during
bootstrap only!
+ * Program logic should use WikibaseRepo::getSnakFormatterFactory()
instead!
+ *
+ * @param WikibaseValueFormatterBuilders $valueFormatterBuilders
+ *
+ * @return WikibaseSnakFormatterBuilders
+ */
+ private function newWikibaseSnakFormatterBuilders(
WikibaseValueFormatterBuilders $valueFormatterBuilders ) {
+ return new WikibaseSnakFormatterBuilders(
+ $valueFormatterBuilders,
+ $this->getStore()->getPropertyInfoStore(),
+ $this->getPropertyDataTypeLookup(),
+ $this->getDataTypeFactory()
+ );
+ }
+
+ /**
* @since 0.4
*
* @param SettingsArray $settings
diff --git a/repo/includes/specials/SpecialListDatatypes.php
b/repo/includes/specials/SpecialListDatatypes.php
index b40abca..86b36b0 100644
--- a/repo/includes/specials/SpecialListDatatypes.php
+++ b/repo/includes/specials/SpecialListDatatypes.php
@@ -56,6 +56,8 @@
// 'wikibase-listdatatypes-string-body'
// 'wikibase-listdatatypes-url-head'
// 'wikibase-listdatatypes-url-body'
+ // 'wikibase-listdatatypes-external-id-head'
+ // 'wikibase-listdatatypes-external-id-body'
foreach ( $this->getDataTypeIds() as $dataTypeId ) {
$this->getOutput()->addHTML(
$this->getHtmlForDataTypeId( $dataTypeId ) );
--
To view, visit https://gerrit.wikimedia.org/r/258460
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings
Gerrit-MessageType: merged
Gerrit-Change-Id: I00c38a51cd22966778f47fa0f1c296c7eac33f0f
Gerrit-PatchSet: 16
Gerrit-Project: mediawiki/extensions/Wikibase
Gerrit-Branch: master
Gerrit-Owner: Daniel Kinzler <[email protected]>
Gerrit-Reviewer: Aude <[email protected]>
Gerrit-Reviewer: Daniel Kinzler <[email protected]>
Gerrit-Reviewer: Hashar <[email protected]>
Gerrit-Reviewer: Hoo man <[email protected]>
Gerrit-Reviewer: Jonas Kress (WMDE) <[email protected]>
Gerrit-Reviewer: Thiemo Mättig (WMDE) <[email protected]>
Gerrit-Reviewer: jenkins-bot <>
_______________________________________________
MediaWiki-commits mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits