registration: Allow string value for Hooks
authorFlorian <florian.schmidt.stargatewissen@gmail.com>
Fri, 29 Apr 2016 21:21:40 +0000 (23:21 +0200)
committerKunal Mehta <legoktm@member.fsf.org>
Tue, 3 May 2016 20:23:07 +0000 (13:23 -0700)
Instead of forcing an object even for single-hook-listeners, allow
string values, too (one hook listener for one hook, only). Also:
use it as default for the conversion script, if only one listener
is added to a hook (which is usually the case). This leads into a
much cleaner output of the Hooks section of extension.json.

Bug: T133628
Change-Id: Ie9e54f0931c41706eb8d82d00256698992ec41cc

docs/extension.schema.json [changed mode: 0644->0755]
includes/registration/ExtensionProcessor.php [changed mode: 0644->0755]
maintenance/convertExtensionToRegistration.php [changed mode: 0644->0755]
tests/phpunit/includes/registration/ExtensionProcessorTest.php

old mode 100644 (file)
new mode 100755 (executable)
index 3c2c057..ed3eaa9
                        "type": "object"
                },
                "Hooks": {
-                       "type": "object",
+                       "type": [ "string", "object" ],
                        "description": "Hooks this extension uses (mapping of hook name to callback)"
                },
                "JobClasses": {
old mode 100644 (file)
new mode 100755 (executable)
index f977124..415e664
@@ -209,8 +209,12 @@ class ExtensionProcessor implements Processor {
        protected function extractHooks( array $info ) {
                if ( isset( $info['Hooks'] ) ) {
                        foreach ( $info['Hooks'] as $name => $value ) {
-                               foreach ( (array)$value as $callback ) {
-                                       $this->globals['wgHooks'][$name][] = $callback;
+                               if ( is_array( $value ) ) {
+                                       foreach ( $value as $callback ) {
+                                               $this->globals['wgHooks'][$name][] = $callback;
+                                       }
+                               } else {
+                                       $this->globals['wgHooks'][$name][] = $value;
                                }
                        }
                }
old mode 100644 (file)
new mode 100755 (executable)
index 8993146..f9dd58c
@@ -216,7 +216,7 @@ class ConvertExtensionToRegistration extends Maintenance {
        }
 
        public function handleHooks( $realName, $value ) {
-               foreach ( $value as $hookName => $handlers ) {
+               foreach ( $value as $hookName => &$handlers ) {
                        foreach ( $handlers as $func ) {
                                if ( $func instanceof Closure ) {
                                        $this->error( "Error: Closures cannot be converted to JSON. " .
@@ -230,6 +230,9 @@ class ConvertExtensionToRegistration extends Maintenance {
                                        );
                                }
                        }
+                       if ( count( $handlers ) === 1 ) {
+                               $handlers = $handlers[0];
+                       }
                }
                $this->json[$realName] = $value;
        }
index 27c0c60..0120d79 100644 (file)
@@ -50,7 +50,7 @@ class ExtensionProcessorTest extends MediaWikiTestCase {
                                self::$default,
                                $merge,
                        ],
-                       // No current hooks, adding one for "FooBaz"
+                       // No current hooks, adding one for "FooBaz" in string format
                        [
                                [],
                                [ 'Hooks' => [ 'FooBaz' => 'FooBazCallback' ] ] + self::$default,
@@ -62,6 +62,12 @@ class ExtensionProcessorTest extends MediaWikiTestCase {
                                [ 'Hooks' => [ 'FooBaz' => 'FooBazCallback' ] ] + self::$default,
                                [ 'FooBaz' => [ 'PriorCallback', 'FooBazCallback' ] ] + $merge,
                        ],
+                       // No current hooks, adding one for "FooBaz" in verbose array format
+                       [
+                               [],
+                               [ 'Hooks' => [ 'FooBaz' => [ 'FooBazCallback' ] ] ] + self::$default,
+                               [ 'FooBaz' => [ 'FooBazCallback' ] ] + $merge,
+                       ],
                        // Hook for "BarBaz", adding one for "FooBaz"
                        [
                                [ 'BarBaz' => [ 'BarBazCallback' ] ],