From f303047f680d465694cad69ce0f30d7a2e675d54 Mon Sep 17 00:00:00 2001 From: jeroendedauw Date: Mon, 18 Feb 2013 23:23:16 +0100 Subject: [PATCH] Allow registration of Actions using a callback that returns an Action instance Basically implementing what Brion suggested on wikitech This allows for injecting dependencies while still only loading the actual class when needed. Simple example: $wgActions['epundo'] = function( Page $page, IContextSource $context = null ) use ( $differ ) { $undoAction = new \EducationProgram\UndoAction( $page, $context ); $undoAction->setDiffer( $differ ); return $undoAction; }; Change-Id: I6c0f4022f1df1ebaf9cd1a5fe4bd362d0ecc0d62 --- RELEASE-NOTES-1.22 | 3 +++ includes/Action.php | 24 ++++++++++++++++-------- 2 files changed, 19 insertions(+), 8 deletions(-) diff --git a/RELEASE-NOTES-1.22 b/RELEASE-NOTES-1.22 index e743b48b60..44b0faedca 100644 --- a/RELEASE-NOTES-1.22 +++ b/RELEASE-NOTES-1.22 @@ -151,6 +151,9 @@ production. ** editmyoptions controls whether a user may change their preferences. * Add new hook AbortTalkPageEmailNotification, this will be used to determine whether to send the regular talk page email notification +* Action classes registered in $wgActions are now also supported in the form of + a callback (which returns an instance of Action) instead of providing the name + of a subclass of Action. * (bug 46513) Vector: Add the collapsibleTabs script from the Vector extension. * Added $wgRecentChangesFlags for defining new flags for RecentChanges and watchlists. diff --git a/includes/Action.php b/includes/Action.php index e9961042a1..23b648f421 100644 --- a/includes/Action.php +++ b/includes/Action.php @@ -59,7 +59,7 @@ abstract class Action { * the action is disabled, or null if it's not recognised * @param $action String * @param $overrides Array - * @return bool|null|string + * @return bool|null|string|callable */ final private static function getClass( $action, array $overrides ) { global $wgActions; @@ -89,12 +89,18 @@ abstract class Action { * if it is not recognised */ final public static function factory( $action, Page $page, IContextSource $context = null ) { - $class = self::getClass( $action, $page->getActionOverrides() ); - if ( $class ) { - $obj = new $class( $page, $context ); + $classOrCallable = self::getClass( $action, $page->getActionOverrides() ); + + if ( is_string( $classOrCallable ) ) { + $obj = new $classOrCallable( $page, $context ); return $obj; } - return $class; + + if ( is_callable( $classOrCallable ) ) { + return call_user_func_array( $classOrCallable, array( $page, $context ) ); + } + + return $classOrCallable; } /** @@ -241,12 +247,14 @@ abstract class Action { } /** - * Protected constructor: use Action::factory( $action, $page ) to actually build - * these things in the real world + * Constructor. + * + * Only public since 1.21 + * * @param $page Page * @param $context IContextSource */ - protected function __construct( Page $page, IContextSource $context = null ) { + public function __construct( Page $page, IContextSource $context = null ) { $this->page = $page; $this->context = $context; } -- 2.20.1