Daniel Werner has submitted this change and it was merged. Change subject: (bug 49306) introducing URL data type ......................................................................
(bug 49306) introducing URL data type Note that this is only a baseline implementation. It does not yet provide integration with MediaWiki's notion of external links, and will not trigger (all) spam filters. Change-Id: I2d26307ad4fb2c48a7373a8867b34f7b9b4f0690 --- M lib/config/WikibaseLib.default.php M lib/includes/WikibaseDataTypeBuilders.php M lib/tests/phpunit/WikibaseDataTypeBuildersTest.php M repo/Wikibase.i18n.php 4 files changed, 66 insertions(+), 2 deletions(-) Approvals: Daniel Werner: Looks good to me, approved jenkins-bot: Verified diff --git a/lib/config/WikibaseLib.default.php b/lib/config/WikibaseLib.default.php index 89f5a68..819bf42 100644 --- a/lib/config/WikibaseLib.default.php +++ b/lib/config/WikibaseLib.default.php @@ -100,6 +100,7 @@ if ( defined( 'WB_EXPERIMENTAL_FEATURES' ) && WB_EXPERIMENTAL_FEATURES ) { // experimental data types $defaults['dataTypes'] = array_merge( $defaults['dataTypes'], array( + 'url', 'quantity', 'monolingual-text', 'multilingual-text', diff --git a/lib/includes/WikibaseDataTypeBuilders.php b/lib/includes/WikibaseDataTypeBuilders.php index bbbc60f..3e2e746 100644 --- a/lib/includes/WikibaseDataTypeBuilders.php +++ b/lib/includes/WikibaseDataTypeBuilders.php @@ -3,6 +3,7 @@ namespace Wikibase\Lib; use DataTypes\DataType; +use Parser; use Wikibase\Client\WikibaseClient; use Wikibase\EntityLookup; use Wikibase\Item; @@ -73,13 +74,26 @@ // the dataTypes setting. On the other hand, perhaps that setting should only // be used for the UI, and the factory should simply know all data types always. - return array( + $types = array( 'wikibase-item' => array( $this, 'buildItemType' ), 'commonsMedia' => array( $this, 'buildMediaType' ), 'string' => array( $this, 'buildStringType' ), 'time' => array( $this, 'buildTimeType' ), 'globe-coordinate' => array( $this, 'buildCoordinateType' ), ); + + $experimental = array( + 'url' => array( $this, 'buildUrlType' ), + // 'quantity'=> array( $this, 'buildQuantityType' ), + // 'monolingual-text' => array( $this, 'buildMonolingualTextType' ), + // 'multilingual-text' => array( $this, 'buildMultilingualTextType' ), + ); + + if ( defined( 'WB_EXPERIMENTAL_FEATURES' ) && WB_EXPERIMENTAL_FEATURES ) { + $types = array_merge( $types, $experimental ); + } + + return $types; } public function buildItemType( $id ) { @@ -184,4 +198,24 @@ return new DataType( $id, 'globecoordinate', array(), array(), array( new TypeValidator( 'DataValues\DataValue' ), $topValidator ) ); } + public function buildUrlType( $id ) { + $validators = array(); + + $validators[] = new TypeValidator( 'string' ); + $validators[] = new StringLengthValidator( 1, 500 ); + //TODO: validate UTF8 (here and elsewhere) + + $protocols = wfUrlProtocolsWithoutProtRel(); + $urlPattern = '#^' . $protocols .':(' . Parser::EXT_LINK_URL_CLASS . ')+#'; + + //TODO: custom messages would be nice for RegexValidator + $validators[] = new RegexValidator( $urlPattern ); + + $topValidator = new DataValueValidator( //Note: validate the DataValue's native value. + new CompositeValidator( $validators, true ) //Note: each validator is fatal + ); + + return new DataType( $id, 'string', array(), array(), array( new TypeValidator( 'DataValues\DataValue' ), $topValidator ) ); + } + } diff --git a/lib/tests/phpunit/WikibaseDataTypeBuildersTest.php b/lib/tests/phpunit/WikibaseDataTypeBuildersTest.php index de9196c..5944eb9 100644 --- a/lib/tests/phpunit/WikibaseDataTypeBuildersTest.php +++ b/lib/tests/phpunit/WikibaseDataTypeBuildersTest.php @@ -78,7 +78,7 @@ } public function provideDataTypeValidation() { - return array( + $cases = array( //wikibase-item array( 'wikibase-item', 'q8', false, 'Expected EntityId, string supplied' ), array( 'wikibase-item', new StringValue( 'q8' ), false, 'Expected EntityId, StringValue supplied' ), @@ -139,6 +139,26 @@ //TODO: must be an item reference //TODO: must be from a list of configured values ); + + if ( defined( 'WB_EXPERIMENTAL_FEATURES' ) && WB_EXPERIMENTAL_FEATURES ) { + $cases = array_merge( $cases, array( + + // url + array( 'url', 'Foo', false, 'StringValue expected, string supplied' ), + array( 'url', new NumberValue( 7 ), false, 'StringValue expected' ), + + array( 'url', new StringValue( 'http://acme.com' ), true, 'Simple HTTP URL' ), + array( 'url', new StringValue( 'http://acme.com/foo/bar?some=stuff#fragment' ), true, 'Complex HTTP URL' ), + + // evil url + array( 'url', new StringValue( '//bla' ), false, 'Protocol-relative' ), + array( 'url', new StringValue( '/bla/bla' ), false, 'relative path' ), + array( 'url', new StringValue( 'just stuff' ), false, 'just words' ), + array( 'url', new StringValue( 'javascript:alert("evil")' ), false, 'JavaScript URL' ), + ) ); + } + + return $cases; } /** diff --git a/repo/Wikibase.i18n.php b/repo/Wikibase.i18n.php index 038c2a8..6cb784f 100644 --- a/repo/Wikibase.i18n.php +++ b/repo/Wikibase.i18n.php @@ -379,6 +379,12 @@ * after – explicit integer value for how many units before the given time it could be. The unit is given by the precision. * precision – explicit value encoded in a shortint. The numbers have the following meaning: 0 - billion years, 1 - hundred million years, ..., 6 - millennia, 7 - century, 8 - decade, 9 - year, 10 - month, 11 - day, 12 - hour, 13 - minute, 14 - second. * calendarmodel – explicit value given as a URI. It will identify the calendar model that should be used to display this time value.', + '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.', + + //extra data types + 'datatypes-type-url' => 'URL', + //content model names 'content-model-wikibase-item' => 'Wikibase item', 'content-model-wikibase-property' => 'Wikibase property', @@ -1058,6 +1064,9 @@ 'wikibase-listdatatypes-time-head' => '{{Wikibase-datatype-head|Time}} {{Identical|Time}}', 'wikibase-listdatatypes-time-body' => '{{Wikibase-datatype-body|Time}}', + 'wikibase-listdatatypes-url-head' => '{{Wikibase-datatype-head|Url}} +{{Identical|Url}}', + 'wikibase-listdatatypes-url-body' => '{{Wikibase-datatype-body|Url}}', 'content-model-wikibase-item' => 'The name for Wikibase item content model, used when describing what type of content a page contains.', 'content-model-wikibase-property' => 'The name for Wikibase property content model, used when describing what type of content a page contains.', 'content-model-wikibase-query' => 'The name for Wikibase query content model, used when describing what type of content a page contains.', -- To view, visit https://gerrit.wikimedia.org/r/73993 To unsubscribe, visit https://gerrit.wikimedia.org/r/settings Gerrit-MessageType: merged Gerrit-Change-Id: I2d26307ad4fb2c48a7373a8867b34f7b9b4f0690 Gerrit-PatchSet: 2 Gerrit-Project: mediawiki/extensions/Wikibase Gerrit-Branch: master Gerrit-Owner: Daniel Kinzler <daniel.kinz...@wikimedia.de> Gerrit-Reviewer: Aude <aude.w...@gmail.com> Gerrit-Reviewer: Daniel Kinzler <daniel.kinz...@wikimedia.de> Gerrit-Reviewer: Daniel Werner <daniel.wer...@wikimedia.de> Gerrit-Reviewer: Denny Vrandecic <denny.vrande...@wikimedia.de> Gerrit-Reviewer: Jeroen De Dauw <jeroended...@gmail.com> Gerrit-Reviewer: Tobias Gritschacher <tobias.gritschac...@wikimedia.de> Gerrit-Reviewer: jenkins-bot _______________________________________________ MediaWiki-commits mailing list MediaWiki-commits@lists.wikimedia.org https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits