mirror of
https://gerrit.wikimedia.org/r/mediawiki/extensions/Gadgets
synced 2024-12-11 06:56:03 +00:00
7793a9475f
Gadgets can mark themselves as ES6-only by specifying the requiresES6 boolean attribute. Syntax validation is disabled for them (as the validator doesn't support ES6 yet), and they are loaded together in a separate request. The minifier doesn't reject syntax errors, and thus these would be passed through to web clients. Hence, communities using this feature are encouraged to use ESLint or another linter to make sure only valid ES <= 6 code is being used. Because of the above, this feature is only made available for non-default gadgets. Bug: T75714 Change-Id: Ib98ac0700471554d5721d7ab858d4660e1e0e980
101 lines
3.2 KiB
PHP
101 lines
3.2 KiB
PHP
<?php
|
|
|
|
namespace MediaWiki\Extension\Gadgets\Content;
|
|
|
|
use Status;
|
|
|
|
/**
|
|
* Class responsible for validating Gadget definition contents
|
|
*
|
|
* @todo maybe this should use a formal JSON schema validator or something
|
|
*/
|
|
class GadgetDefinitionValidator {
|
|
/**
|
|
* @var array Validation metadata.
|
|
* 'foo.bar.baz' => [ 'type check callback',
|
|
* 'type name' [, 'member type check callback', 'member type name'] ]
|
|
*/
|
|
protected static $propertyValidation = [
|
|
'settings' => [ 'is_array', 'array' ],
|
|
'settings.rights' => [ 'is_array', 'array' , 'is_string', 'string' ],
|
|
'settings.default' => [ 'is_bool', 'boolean' ],
|
|
'settings.hidden' => [ 'is_bool', 'boolean' ],
|
|
'settings.package' => [ 'is_bool', 'boolean' ],
|
|
'settings.skins' => [ [ __CLASS__, 'isArrayOrTrue' ], 'array or true', 'is_string', 'string' ],
|
|
'settings.actions' => [ 'is_array', 'array', 'is_string', 'string' ],
|
|
'settings.category' => [ 'is_string', 'string' ],
|
|
'settings.supportsUrlLoad' => [ 'is_bool', 'boolean' ],
|
|
'settings.requiresES6' => [ 'is_bool', 'boolean' ],
|
|
'module' => [ 'is_array', 'array' ],
|
|
'module.scripts' => [ 'is_array', 'array', 'is_string', 'string' ],
|
|
'module.styles' => [ 'is_array', 'array', 'is_string', 'string' ],
|
|
'module.datas' => [ 'is_array', 'array', 'is_string', 'string' ],
|
|
'module.dependencies' => [ 'is_array', 'array', 'is_string', 'string' ],
|
|
'module.peers' => [ 'is_array', 'array', 'is_string', 'string' ],
|
|
'module.messages' => [ 'is_array', 'array', 'is_string', 'string' ],
|
|
'module.type' => [ 'is_string', 'string' ],
|
|
];
|
|
|
|
/**
|
|
* @param mixed $value
|
|
* @return bool
|
|
*/
|
|
public static function isArrayOrTrue( $value ) {
|
|
return is_array( $value ) || $value === true;
|
|
}
|
|
|
|
/**
|
|
* Check the validity of the given properties array
|
|
* @param array $properties Return value of FormatJson::decode( $blob, true )
|
|
* @param bool $tolerateMissing If true, don't complain about missing keys
|
|
* @return Status object with error message if applicable
|
|
*/
|
|
public function validate( array $properties, $tolerateMissing = false ) {
|
|
foreach ( self::$propertyValidation as $property => $validation ) {
|
|
$path = explode( '.', $property );
|
|
$val = $properties;
|
|
|
|
// Walk down and verify that the path from the root to this property exists
|
|
foreach ( $path as $p ) {
|
|
if ( !array_key_exists( $p, $val ) ) {
|
|
if ( $tolerateMissing ) {
|
|
// Skip validation of this property altogether
|
|
continue 2;
|
|
}
|
|
|
|
return Status::newFatal( 'gadgets-validate-notset', $property );
|
|
}
|
|
$val = $val[$p];
|
|
}
|
|
|
|
// Do the actual validation of this property
|
|
$func = $validation[0];
|
|
if ( !call_user_func( $func, $val ) ) {
|
|
return Status::newFatal(
|
|
'gadgets-validate-wrongtype',
|
|
$property,
|
|
$validation[1],
|
|
gettype( $val )
|
|
);
|
|
}
|
|
|
|
if ( isset( $validation[2] ) && isset( $validation[3] ) && is_array( $val ) ) {
|
|
// Descend into the array and check the type of each element
|
|
$func = $validation[2];
|
|
foreach ( $val as $i => $v ) {
|
|
if ( !call_user_func( $func, $v ) ) {
|
|
return Status::newFatal(
|
|
'gadgets-validate-wrongtype',
|
|
"{$property}[{$i}]",
|
|
$validation[3],
|
|
gettype( $v )
|
|
);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return Status::newGood();
|
|
}
|
|
}
|