summaryrefslogtreecommitdiff
path: root/www/wiki/extensions/Gadgets/includes/content/GadgetDefinitionValidator.php
diff options
context:
space:
mode:
Diffstat (limited to 'www/wiki/extensions/Gadgets/includes/content/GadgetDefinitionValidator.php')
-rw-r--r--www/wiki/extensions/Gadgets/includes/content/GadgetDefinitionValidator.php91
1 files changed, 91 insertions, 0 deletions
diff --git a/www/wiki/extensions/Gadgets/includes/content/GadgetDefinitionValidator.php b/www/wiki/extensions/Gadgets/includes/content/GadgetDefinitionValidator.php
new file mode 100644
index 00000000..2be75783
--- /dev/null
+++ b/www/wiki/extensions/Gadgets/includes/content/GadgetDefinitionValidator.php
@@ -0,0 +1,91 @@
+<?php
+
+/**
+ * Class responsible for validating Gadget definition contents
+ *
+ * @todo maybe this should use a formal JSON schema validator or something
+ */
+class GadgetDefinitionValidator {
+ /**
+ * 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.skins' => [ [ __CLASS__, 'isArrayOrTrue' ], 'array or true', 'is_string', 'string' ],
+ 'settings.category' => [ 'is_string', 'string' ],
+ 'module' => [ 'is_array', 'array' ],
+ 'module.scripts' => [ 'is_array', 'array', 'is_string', 'string' ],
+ 'module.styles' => [ '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;
+ } else {
+ 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] ) && 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();
+ }
+}