From 9e3e3306b0224a2c5dedfa08c31b6559918171f1 Mon Sep 17 00:00:00 2001 From: Bene Date: Fri, 5 Feb 2016 14:40:39 +0100 Subject: [PATCH] Allow callbacks to be passed to $wgContentHandlers Change-Id: Icf980313a6e7fcc83f5183c450b0a824353596b8 --- RELEASE-NOTES-1.27 | 2 ++ docs/contenthandler.txt | 3 ++- includes/DefaultSettings.php | 3 ++- includes/content/ContentHandler.php | 11 +++++--- .../includes/content/ContentHandlerTest.php | 25 +++++++++++++++++++ 5 files changed, 39 insertions(+), 5 deletions(-) diff --git a/RELEASE-NOTES-1.27 b/RELEASE-NOTES-1.27 index 5b9b2b81e0..d1f8ca77ce 100644 --- a/RELEASE-NOTES-1.27 +++ b/RELEASE-NOTES-1.27 @@ -158,6 +158,8 @@ production. aria-describedby, aria-flowto, aria-label, aria-labelledby, aria-owns. * Removed "presentation" restriction on the HTML role attribute in wikitext. All values are now allowed for the role attribute. +* $wgContentHandlers now also supports callbacks to create an instance of the + appropriate ContentHandler subclass. === External library changes in 1.27 === diff --git a/docs/contenthandler.txt b/docs/contenthandler.txt index 5f9a0b039e..f1f478ef31 100644 --- a/docs/contenthandler.txt +++ b/docs/contenthandler.txt @@ -148,7 +148,8 @@ using a model or format different from the default will result in an error. There are some new globals that can be used to control the behavior of the ContentHandler facility: -* $wgContentHandlers associates content model IDs with the names of the appropriate ContentHandler subclasses. +* $wgContentHandlers associates content model IDs with the names of the appropriate ContentHandler subclasses + or callbacks that create an instance of the appropriate ContentHandler subclass. * $wgNamespaceContentModels maps namespace IDs to a content model that should be the default for that namespace. diff --git a/includes/DefaultSettings.php b/includes/DefaultSettings.php index 9c7106f83f..3ac3c8fc4e 100644 --- a/includes/DefaultSettings.php +++ b/includes/DefaultSettings.php @@ -904,7 +904,8 @@ $wgMediaHandlers = array( /** * Plugins for page content model handling. - * Each entry in the array maps a model id to a class name. + * Each entry in the array maps a model id to a class name or callback + * that creates an instance of the appropriate ContentHandler subclass. * * @since 1.21 */ diff --git a/includes/content/ContentHandler.php b/includes/content/ContentHandler.php index acaa288f43..e898e720b8 100644 --- a/includes/content/ContentHandler.php +++ b/includes/content/ContentHandler.php @@ -357,11 +357,16 @@ abstract class ContentHandler { throw new MWException( "ContentHandlerForModelID must supply a ContentHandler instance" ); } } else { - $class = $wgContentHandlers[$modelId]; - $handler = new $class( $modelId ); + $classOrCallback = $wgContentHandlers[$modelId]; + + if ( is_callable( $classOrCallback ) ) { + $handler = call_user_func( $classOrCallback, $modelId ); + } else { + $handler = new $classOrCallback( $modelId ); + } if ( !( $handler instanceof ContentHandler ) ) { - throw new MWException( "$class from \$wgContentHandlers is not " . + throw new MWException( "$classOrCallback from \$wgContentHandlers is not " . "compatible with ContentHandler" ); } } diff --git a/tests/phpunit/includes/content/ContentHandlerTest.php b/tests/phpunit/includes/content/ContentHandlerTest.php index 8178c12efa..a72247ba69 100644 --- a/tests/phpunit/includes/content/ContentHandlerTest.php +++ b/tests/phpunit/includes/content/ContentHandlerTest.php @@ -26,6 +26,9 @@ class ContentHandlerTest extends MediaWikiTestCase { CONTENT_MODEL_CSS => 'CssContentHandler', CONTENT_MODEL_TEXT => 'TextContentHandler', 'testing' => 'DummyContentHandlerForTesting', + 'testing-callbacks' => function( $modelId ) { + return new DummyContentHandlerForTesting( $modelId ); + } ), ) ); @@ -378,4 +381,26 @@ class ContentHandlerTest extends MediaWikiTestCase { return true; } + + public function provideGetModelForID() { + return array( + array( CONTENT_MODEL_WIKITEXT, 'WikitextContentHandler' ), + array( CONTENT_MODEL_JAVASCRIPT, 'JavaScriptContentHandler' ), + array( CONTENT_MODEL_JSON, 'JsonContentHandler' ), + array( CONTENT_MODEL_CSS, 'CssContentHandler' ), + array( CONTENT_MODEL_TEXT, 'TextContentHandler' ), + array( 'testing', 'DummyContentHandlerForTesting' ), + array( 'testing-callbacks', 'DummyContentHandlerForTesting' ), + ); + } + + /** + * @dataProvider provideGetModelForID + */ + public function testGetModelForID( $modelId, $handlerClass ) { + $handler = ContentHandler::getForModelID( $modelId ); + + $this->assertInstanceOf( $handlerClass, $handler ); + } + } -- 2.20.1