Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
Total | |
0.00% |
0 / 30 |
|
0.00% |
0 / 3 |
CRAP | |
0.00% |
0 / 1 |
GadgetDefinitionValidator | |
0.00% |
0 / 30 |
|
0.00% |
0 / 3 |
306 | |
0.00% |
0 / 1 |
isValidTitleSuffix | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
12 | |||
isValidType | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
12 | |||
validate | |
0.00% |
0 / 28 |
|
0.00% |
0 / 1 |
132 |
1 | <?php |
2 | |
3 | namespace MediaWiki\Extension\Gadgets\Content; |
4 | |
5 | use MediaWiki\Status\Status; |
6 | |
7 | /** |
8 | * Class responsible for validating Gadget definition contents |
9 | * |
10 | * @todo maybe this should use a formal JSON schema validator or something |
11 | */ |
12 | class GadgetDefinitionValidator { |
13 | /** |
14 | * @var array Validation metadata. |
15 | * 'foo.bar.baz' => [ 'type check callback', |
16 | * 'type name' [, 'member type check callback', 'member type name'] ] |
17 | */ |
18 | protected static $propertyValidation = [ |
19 | 'settings' => [ 'is_array', 'array' ], |
20 | 'settings.actions' => [ 'is_array', 'array', 'is_string', 'string' ], |
21 | 'settings.categories' => [ 'is_array', 'array', 'is_string', 'string' ], |
22 | 'settings.category' => [ 'is_string', 'string' ], |
23 | 'settings.contentModels' => [ 'is_array', 'array', 'is_string', 'string' ], |
24 | 'settings.default' => [ 'is_bool', 'boolean' ], |
25 | 'settings.hidden' => [ 'is_bool', 'boolean' ], |
26 | 'settings.namespaces' => [ 'is_array', 'array', 'is_int', 'integer' ], |
27 | 'settings.package' => [ 'is_bool', 'boolean' ], |
28 | 'settings.requiresES6' => [ 'is_bool', 'boolean' ], |
29 | 'settings.rights' => [ 'is_array', 'array', 'is_string', 'string' ], |
30 | 'settings.skins' => [ 'is_array', 'array', 'is_string', 'string' ], |
31 | 'settings.supportsUrlLoad' => [ 'is_bool', 'boolean' ], |
32 | |
33 | 'module' => [ 'is_array', 'array' ], |
34 | 'module.dependencies' => [ 'is_array', 'array', 'is_string', 'string' ], |
35 | 'module.messages' => [ 'is_array', 'array', 'is_string', 'string' ], |
36 | 'module.pages' => [ 'is_array', 'array', [ __CLASS__, 'isValidTitleSuffix' ], '.js, .css or .json page' ], |
37 | 'module.peers' => [ 'is_array', 'array', 'is_string', 'string' ], |
38 | 'module.type' => [ [ __CLASS__, 'isValidType' ], 'general or styles' ], |
39 | ]; |
40 | |
41 | public static function isValidTitleSuffix( string $title ): bool { |
42 | return str_ends_with( $title, '.js' ) || str_ends_with( $title, '.css' ) || str_ends_with( $title, '.json' ); |
43 | } |
44 | |
45 | public static function isValidType( string $type ): bool { |
46 | return $type === '' || $type === 'general' || $type === 'styles'; |
47 | } |
48 | |
49 | /** |
50 | * Check the validity of the given properties array |
51 | * @param array $properties Return value of FormatJson::decode( $blob, true ) |
52 | * @param bool $tolerateMissing If true, don't complain about missing keys |
53 | * @return Status object with error message if applicable |
54 | */ |
55 | public function validate( array $properties, $tolerateMissing = false ) { |
56 | foreach ( self::$propertyValidation as $property => $validation ) { |
57 | $path = explode( '.', $property ); |
58 | $val = $properties; |
59 | |
60 | // Walk down and verify that the path from the root to this property exists |
61 | foreach ( $path as $p ) { |
62 | if ( !array_key_exists( $p, $val ) ) { |
63 | if ( $tolerateMissing ) { |
64 | // Skip validation of this property altogether |
65 | continue 2; |
66 | } |
67 | |
68 | return Status::newFatal( 'gadgets-validate-notset', $property ); |
69 | } |
70 | $val = $val[$p]; |
71 | } |
72 | |
73 | // Do the actual validation of this property |
74 | $func = $validation[0]; |
75 | if ( !call_user_func( $func, $val ) ) { |
76 | return Status::newFatal( |
77 | 'gadgets-validate-wrongtype', |
78 | $property, |
79 | $validation[1], |
80 | gettype( $val ) |
81 | ); |
82 | } |
83 | |
84 | if ( isset( $validation[2] ) && isset( $validation[3] ) && is_array( $val ) ) { |
85 | // Descend into the array and check the type of each element |
86 | $func = $validation[2]; |
87 | foreach ( $val as $i => $v ) { |
88 | if ( !call_user_func( $func, $v ) ) { |
89 | return Status::newFatal( |
90 | 'gadgets-validate-wrongtype', |
91 | "{$property}[{$i}]", |
92 | $validation[3], |
93 | gettype( $v ) |
94 | ); |
95 | } |
96 | } |
97 | } |
98 | } |
99 | |
100 | return Status::newGood(); |
101 | } |
102 | } |