Index: branches/RL2/extensions/Gadgets/backend/Gadget.php |
— | — | @@ -43,11 +43,66 @@ |
44 | 44 | /** array of module settings, see "module" key in the JSON blob */ |
45 | 45 | protected $moduleData; |
46 | 46 | |
| 47 | + /** |
| 48 | + * Validation metadata. |
| 49 | + * 'foo.bar.baz' => array( 'callback', 'type name' [, 'membercallback', 'member type name'] ) |
| 50 | + */ |
| 51 | + protected static $propertyValidation = array( |
| 52 | + 'settings' => array( 'is_array', 'array' ), |
| 53 | + 'settings.rights' => array( 'is_array', 'array' , 'is_string', 'string' ), |
| 54 | + 'settings.default' => array( 'is_bool', 'boolean' ), |
| 55 | + 'settings.hidden' => array( 'is_bool', 'boolean' ), |
| 56 | + 'settings.shared' => array( 'is_bool', 'boolean' ), |
| 57 | + 'settings.category' => array( 'is_string', 'string' ), |
| 58 | + 'module' => array( 'is_array', 'array' ), |
| 59 | + 'module.scripts' => array( 'is_array', 'array', 'is_string', 'string' ), |
| 60 | + 'module.styles' => array( 'is_array', 'array', 'is_string', 'string' ), |
| 61 | + 'module.dependencies' => array( 'is_array', 'array', 'is_string', 'string' ), |
| 62 | + 'module.messages' => array( 'is_array', 'array', 'is_string', 'string' ), |
| 63 | + ); |
| 64 | + |
47 | 65 | /*** Public static methods ***/ |
48 | 66 | |
49 | | - public static function isValidPropertiesArray( $properties ) { |
50 | | - // TODO: Also validate existence of individual properties |
51 | | - return is_array( $properties ) && isset( $properties['settings'] ) && isset( $properties['module'] ); |
| 67 | + /** |
| 68 | + * Check the validity of the given properties array |
| 69 | + * @param $properties Return value of FormatJson::decode( $blob, true ) |
| 70 | + * @return Status object with error message if applicable |
| 71 | + */ |
| 72 | + public static function validatePropertiesArray( $properties ) { |
| 73 | + if ( $properties === null ) { |
| 74 | + return Status::newFatal( 'gadgets-validate-invalidjson' ); |
| 75 | + } |
| 76 | + if ( !is_array( $properties ) ) { |
| 77 | + return Status::newFatal( 'gadgets-validate-notanobject', gettype( $properties ) ); // Use JSON terminology |
| 78 | + } |
| 79 | + |
| 80 | + foreach ( self::$propertyValidation as $property => $validation ) { |
| 81 | + $path = explode( '.', $property ); |
| 82 | + $var = $properties; |
| 83 | + foreach ( $path as $p ) { |
| 84 | + if ( !isset( $var[$p] ) ) { |
| 85 | + return Status::newFatal( 'gadgets-validate-notset', $property ); |
| 86 | + } |
| 87 | + $var = $var[$p]; |
| 88 | + } |
| 89 | + |
| 90 | + $func = $validation[0]; |
| 91 | + if ( !$func( $var ) ) { |
| 92 | + return Status::newFatal( 'gadgets-validate-wrongtype', $property, $validation[1], gettype( $var ) ); |
| 93 | + } |
| 94 | + |
| 95 | + if ( isset( $validation[2] ) ) { |
| 96 | + // Descend into the array and check the type of each element |
| 97 | + $func = $validation[2]; |
| 98 | + foreach ( $var as $i => $v ) { |
| 99 | + if ( !$func( $v ) ){ |
| 100 | + return Status::newFatal( 'gadgets-validate-wrongtype', "{$property}[{$i}]", $validation[3], gettype( $v ) ); |
| 101 | + } |
| 102 | + } |
| 103 | + } |
| 104 | + } |
| 105 | + |
| 106 | + return Status::newGood(); |
52 | 107 | } |
53 | 108 | |
54 | 109 | /*** Public methods ***/ |
— | — | @@ -65,8 +120,8 @@ |
66 | 121 | $properties = FormatJson::decode( $properties, true ); |
67 | 122 | } |
68 | 123 | |
69 | | - |
70 | | - if ( !self::isValidPropertiesArray( $properties ) ) { |
| 124 | + // Do a quick sanity check rather than full validation |
| 125 | + if ( !is_array( $properties ) || !isset( $properties['settings'] ) || !isset( $properties['module'] ) ) { |
71 | 126 | throw new MWException( 'Invalid property array passed to ' . __METHOD__ ); |
72 | 127 | } |
73 | 128 | |