Pmiazga has uploaded a new change for review. ( 
https://gerrit.wikimedia.org/r/367421 )

Change subject: Allow Hooks::run() to use services.
......................................................................

Allow Hooks::run() to use services.

Currently our hooks system uses lots of static methods, which are
diffuclt to test. Static methods create a global context which might
cause side effects.

Idea: When hook callback starts with "@" instead of using static
method calls, threat first part of callback as a service name and
use MediaWikiServices container to retrieve service object.

Example extension.json hook definition:
  "Hooks": {
    "GetPreferences" : [
      "@ServiceName::hookMethod"
    ]

Changes:
 - added @ handling inside Hooks::run()
 - added unit tests for new behavior

Change-Id: Iba0f5f2fc7378e68df2c7a18a48c93942951eeea
---
M includes/Hooks.php
M tests/phpunit/includes/HooksTest.php
2 files changed, 39 insertions(+), 2 deletions(-)


  git pull ssh://gerrit.wikimedia.org:29418/mediawiki/core 
refs/changes/21/367421/1

diff --git a/includes/Hooks.php b/includes/Hooks.php
index f4f86be..890bb3c 100644
--- a/includes/Hooks.php
+++ b/includes/Hooks.php
@@ -24,6 +24,7 @@
  * @file
  */
 
+use MediaWiki\MediaWikiServices;
 /**
  * Hooks class.
  *
@@ -161,11 +162,20 @@
                                if ( $method === null ) {
                                        $method = "on$event";
                                }
-
                                $func = get_class( $object ) . '::' . $method;
                                $callback = [ $object, $method ];
                        } elseif ( is_string( $hook[0] ) ) {
-                               $func = $callback = array_shift( $hook );
+                               if ( $hook[0][0] === '@' ) {
+                                       list( $serviceName, $method ) = 
explode( '::',
+                                               substr( array_shift( $hook ), 1 
) );
+
+                                       $service = 
MediaWikiServices::getInstance()->getService( $serviceName );
+                                       $callback = [ $service, $method ];
+                                       $func = get_class( $service ) . '::' . 
$method;
+                               } else {
+                                       $func = $callback = array_shift( $hook 
);
+                               }
+
                        } else {
                                throw new MWException( 'Unknown datatype in 
hooks for ' . $event . "\n" );
                        }
diff --git a/tests/phpunit/includes/HooksTest.php 
b/tests/phpunit/includes/HooksTest.php
index 527e129..448e632 100644
--- a/tests/phpunit/includes/HooksTest.php
+++ b/tests/phpunit/includes/HooksTest.php
@@ -1,5 +1,7 @@
 <?php
 
+use MediaWiki\MediaWikiServices;
+
 class HooksTest extends MediaWikiTestCase {
 
        function setUp() {
@@ -146,6 +148,31 @@
        }
 
        /**
+        * @covers Hooks::run
+        */
+       public function testServiceHandling() {
+               $serviceMock = $this->getMockBuilder( stdClass::class )
+                       ->setMethods( ['doHookTest' ] )
+                       ->getMock();
+
+               $serviceMock->expects ( $this->once() )
+                       ->method( 'doHookTest' )
+                       ->with( 'arguments', 'test' );
+
+               // We cannot use $this->setService as it allows to override 
only existing service
+               $this->overrideMwServices();
+               MediaWikiServices::getInstance()->defineService( 
'HooksTestService',
+                       function () use ( $serviceMock ) {
+                               return $serviceMock;
+                       }
+               );
+
+               Hooks::register( 'MediaWikiHooksTest001', 
'@HooksTestService::doHookTest' );
+               Hooks::run( 'MediaWikiHooksTest001', ['arguments', 'test' ] );
+               MediaWikiServices::getInstance()->disableService( 
'HooksTestService' );
+       }
+
+       /**
         * @expectedException FatalError
         * @covers Hooks::run
         */

-- 
To view, visit https://gerrit.wikimedia.org/r/367421
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings

Gerrit-MessageType: newchange
Gerrit-Change-Id: Iba0f5f2fc7378e68df2c7a18a48c93942951eeea
Gerrit-PatchSet: 1
Gerrit-Project: mediawiki/core
Gerrit-Branch: master
Gerrit-Owner: Pmiazga <pmia...@wikimedia.org>

_______________________________________________
MediaWiki-commits mailing list
MediaWiki-commits@lists.wikimedia.org
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits

Reply via email to