Allow aliases to be integers in addition to strings

Parameter names in a template can be numeric. While it makes a lot of
sense to force a specific format in the TemplateData JSON (i.e. only
strings), it's inconvenient and confusing if numbers are rejected for
being "invalid".

Effects of this patch:
* The incoming JSON is allowed to contain numbers in the aliases
  array.
* However, the API normalizes these and forces all aliases to be
  strings, as it was always documented.
* The editor component accepts anything in the aliases array, but
  forces all aliases to be strings. Again, as documented.
* Note that it was never possible to use numeric keys in the `params`
  list. This patch is only about aliases.

At the moment this is a somewhat "hidden" feature. We might or might
not update the documentation to officially allow numeric aliases.

Bug: T298795
Change-Id: I32ea296b4520e7f21b03a1f6390db4f43b613bdd
This commit is contained in:
Thiemo Kreuz 2022-01-10 12:13:05 +01:00
parent e296c87ad2
commit 5f749c6418
3 changed files with 19 additions and 6 deletions

View file

@ -312,10 +312,12 @@ class TemplateDataBlob {
return Status::newFatal( 'templatedata-invalid-type',
"params.{$paramName}.aliases", 'array' );
}
foreach ( $paramObj->aliases as $i => $alias ) {
if ( !is_string( $alias ) ) {
foreach ( $paramObj->aliases as $i => &$alias ) {
if ( is_int( $alias ) ) {
$alias = (string)$alias;
} elseif ( !is_string( $alias ) ) {
return Status::newFatal( 'templatedata-invalid-type',
"params.{$paramName}.aliases[$i]", 'string' );
"params.{$paramName}.aliases[$i]", 'int|string' );
}
}
} else {

View file

@ -1103,6 +1103,11 @@ Dialog.prototype.changeParamPropertyInput = function ( paramKey, propName, value
propInput.selectItem( propInput.findItemFromData( value ) );
} else if ( prop.type === 'boolean' ) {
propInput.setSelected( !!value );
} else if ( prop.type === 'array' ) {
propInput.setValue( value.map( function ( v ) {
// TagMultiselectWidget accepts nothing but strings or objects with a .data property
return v && v.data ? v : String( v );
} ) );
} else {
if ( languageProps.indexOf( propName ) !== -1 ) {
propInput.setValue( value[ lang ] );

View file

@ -114,6 +114,10 @@ class TemplateDataBlobTest extends MediaWikiIntegrationTestCase {
'input' => '{ "params": { "a": { "aliases": "" } } }',
'status' => '(templatedata-invalid-type: params.a.aliases, array)',
],
[
'input' => '{ "params": { "a": { "aliases": [ "1", 2, {} ] } } }',
'status' => '(templatedata-invalid-type: params.a.aliases[2], int|string)',
],
[
'input' => '{ "params": { "a": { "autovalue": [] } } }',
'status' => '(templatedata-invalid-type: params.a.autovalue, string)',
@ -134,6 +138,10 @@ class TemplateDataBlobTest extends MediaWikiIntegrationTestCase {
'input' => '{ "params": { "a": { "suggestedvalues": "" } } }',
'status' => '(templatedata-invalid-type: params.a.suggestedvalues, array)',
],
[
'input' => '{ "params": { "a": { "suggestedvalues": [ {} ] } } }',
'status' => '(templatedata-invalid-type: params.a.suggestedvalues[0], string)',
],
[
'input' => '{
"params": {
@ -209,9 +217,7 @@ class TemplateDataBlobTest extends MediaWikiIntegrationTestCase {
"example": null,
"required": false,
"suggested": true,
"aliases": [
"1"
]
"aliases": [ 1 ]
}
}
}