Mwjames has uploaded a new change for review. https://gerrit.wikimedia.org/r/85417
Change subject: Replace SkinTemplateToolboxEnd hook with \SMW\BaseTemplateToolbox ...................................................................... Replace SkinTemplateToolboxEnd hook with \SMW\BaseTemplateToolbox [1] states "BaseTemplateToolbox also does the same thing, is cleaner and more future proof than SkinTemplateToolboxEnd" [1] https://www.mediawiki.org/wiki/Manual:Hooks/SkinTemplateToolboxEnd Bug 45320 Change-Id: I4b3b7ed768479342e6a762d2dbacd3316fd510dd --- M SemanticMediaWiki.classes.php M SemanticMediaWiki.hooks.php M includes/Setup.php M includes/dic/SharedDependencyContainer.php A includes/hooks/BaseTemplateToolbox.php M includes/hooks/FunctionHookRegistry.php M tests/phpunit/includes/SetupTest.php M tests/phpunit/includes/dic/SharedDependencyContainerTest.php A tests/phpunit/includes/hooks/BaseTemplateToolboxTest.php 9 files changed, 339 insertions(+), 38 deletions(-) git pull ssh://gerrit.wikimedia.org:29418/mediawiki/extensions/SemanticMediaWiki refs/changes/17/85417/1 diff --git a/SemanticMediaWiki.classes.php b/SemanticMediaWiki.classes.php index d6bea72..c94d55f 100644 --- a/SemanticMediaWiki.classes.php +++ b/SemanticMediaWiki.classes.php @@ -106,6 +106,7 @@ 'SMW\CacheIdGenerator' => 'includes/cache/CacheIdGenerator.php', // Hooks + 'SMW\BaseTemplateToolbox' => 'includes/hooks/BaseTemplateToolbox.php', 'SMW\SpecialStatsAddExtra' => 'includes/hooks/SpecialStatsAddExtra.php', 'SMW\OutputPageParserOutput' => 'includes/hooks/OutputPageParserOutput.php', 'SMW\SkinAfterContent' => 'includes/hooks/SkinAfterContent.php', diff --git a/SemanticMediaWiki.hooks.php b/SemanticMediaWiki.hooks.php index 78f8f07..9eb3e87 100644 --- a/SemanticMediaWiki.hooks.php +++ b/SemanticMediaWiki.hooks.php @@ -238,30 +238,6 @@ } /** - * Add a link to the toolbox to view the properties of the current page in - * Special:Browse. The links has the CSS id "t-smwbrowselink" so that it can be - * skinned or hidden with all standard mechanisms (also by individual users - * with custom CSS). - * - * @since 1.7.1 - * - * @param $skintemplate - * - * @return boolean - */ - public static function showBrowseLink( $skintemplate ) { - // @codeCoverageIgnoreStart - if ( $skintemplate->data['isarticle'] ) { - $browselink = SMWInfolink::newBrowsingLink( wfMessage( 'smw_browselink' )->text(), - $skintemplate->data['titleprefixeddbkey'], false ); - echo '<li id="t-smwbrowselink">' . $browselink->getHTML() . '</li>'; - } - - return true; - // @codeCoverageIgnoreEnd - } - - /** * Alter the structured navigation links in SkinTemplates. * @see https://www.mediawiki.org/wiki/Manual:Hooks/SkinTemplateNavigation * diff --git a/includes/Setup.php b/includes/Setup.php index 453daf9..43ccbdb 100644 --- a/includes/Setup.php +++ b/includes/Setup.php @@ -2,6 +2,8 @@ namespace SMW; +use OutOfBoundsExeception; + /** * Extension setup and registration * @@ -28,6 +30,9 @@ /** @var Settings */ protected $settings; + + /** @var DependencyBuilder */ + protected $dependencyBuilder = null; /** * @since 1.9 @@ -101,6 +106,22 @@ $this->settings = Settings::newFromGlobals( $this->globals ); + } + + /** + * Returns a DependencyBuilder + * + * @since 1.9 + */ + protected function getDependencyBuilder() { + + // Use the DefaultContext to determine the builder + if ( $this->dependencyBuilder === null ) { + $this->dependencyBuilder = new SimpleDependencyBuilder( new SharedDependencyContainer() ); + $this->dependencyBuilder->getContainer()->registerObject( 'Settings', $this->settings ); + } + + return $this->dependencyBuilder; } /** @@ -288,13 +309,21 @@ */ protected function registerFunctionHooks() { - // FIXME Registration should follow + $hookRegistry = $this->getDependencyBuilder()->newObject( 'FunctionHookRegistry' ); - // $hookRegistry = new FunctionHookRegistry( $this->settings ); + /** + * Hook: Called by BaseTemplate when building the toolbox array and + * returning it for the skin to output. + * + * @see http://www.mediawiki.org/wiki/Manual:Hooks/BaseTemplateToolbox + * + * @since 1.9 + */ + $this->globals['wgHooks']['BaseTemplateToolbox'][] = function ( $skinTemplate, &$toolbox ) use ( $hookRegistry ) { + return $hookRegistry->register( new BaseTemplateToolbox( $skinTemplate, $toolbox ) )->process(); + }; - // $this->globals['wgHooks']['BeforePageDisplay'][] = function ( OutputPage &$outputPage, Skin &$skin ) use ( $hookRegistry ) { - // return $hookRegistry->register( new BeforePageDisplay( $outputPage, $skin ) )->process(); - // }; + // Old-style registration $this->globals['wgHooks']['LoadExtensionSchemaUpdates'][] = 'SMWHooks::onSchemaUpdate'; $this->globals['wgHooks']['ParserTestTables'][] = 'SMWHooks::onParserTestTables'; @@ -321,11 +350,6 @@ $this->globals['wgHooks']['SkinAfterContent'][] = 'SMWHooks::onSkinAfterContent'; $this->globals['wgHooks']['ExtensionTypes'][] = 'SMWHooks::addSemanticExtensionType'; - // FIXME Use BaseTemplateToolbox instead - if ( $this->settings->get( 'smwgToolboxBrowseLink' ) ) { - $this->globals['wgHooks']['SkinTemplateToolboxEnd'][] = 'SMWHooks::showBrowseLink'; - } - } /** @@ -336,10 +360,7 @@ protected function registerParserHooks() { $settings = $this->settings; - - // Inject the ObjectBuilder using the DefaultContext - $objectBuilder = new SimpleDependencyBuilder( new SharedDependencyContainer() ); - $objectBuilder->getContainer()->registerObject( 'Settings', $settings ); + $objectBuilder = $this->getDependencyBuilder(); /** * Called when the parser initialises for the first time diff --git a/includes/dic/SharedDependencyContainer.php b/includes/dic/SharedDependencyContainer.php index 9b56c77..d6b009c 100644 --- a/includes/dic/SharedDependencyContainer.php +++ b/includes/dic/SharedDependencyContainer.php @@ -180,6 +180,17 @@ $instance = new AskParserFunction( $parserData, $queryData, $messageFormatter ); return $instance; + }, + + /** + * FunctionHookRegistry object definition + * + * @since 1.9 + * + * @return FunctionHookRegistry + */ + 'FunctionHookRegistry' => function ( DependencyBuilder $builder ) { + return new FunctionHookRegistry(); } ); diff --git a/includes/hooks/BaseTemplateToolbox.php b/includes/hooks/BaseTemplateToolbox.php new file mode 100644 index 0000000..8d5715b --- /dev/null +++ b/includes/hooks/BaseTemplateToolbox.php @@ -0,0 +1,85 @@ +<?php + +namespace SMW; + +use Title; + +/** + * BaseTemplateToolbox hook + * + * @file + * + * @license GNU GPL v2+ + * @since 1.9 + * + * @author mwjames + */ + +/** + * Hook: Called by BaseTemplate when building the toolbox array and + * returning it for the skin to output. + * + * Add a link to the toolbox to view the properties of the current page in + * Special:Browse. The links has the CSS id "t-smwbrowselink" so that it can be + * skinned or hidden with all standard mechanisms (also by individual users + * with custom CSS). + * + * @see http://www.mediawiki.org/wiki/Manual:Hooks/BaseTemplateToolbox + * + * @since 1.9 + * + * @ingroup Hook + */ +class BaseTemplateToolbox extends FunctionHook { + + /** + * @since 1.9 + * + * @param $skinTemplate + * @param &$toolbox + */ + public function __construct( $skinTemplate, &$toolbox ) { + $this->skinTemplate = $skinTemplate; + $this->toolbox =& $toolbox; + } + + /** + * @see FunctionHook::process + * + * @since 1.9 + * + * @return true + */ + public function process() { + return $this->isValid( $this->skinTemplate->getSkin()->getTitle() ) ? $this->performUpdate() : true; + } + + /** + * @since 1.9 + * + * @return boolean + */ + protected function isValid( Title $title ) { + return !$title->isSpecialPage() && + $this->getDependencyBuilder()->newObject( 'Settings' )->get( 'smwgToolboxBrowseLink' ) && + $this->getDependencyBuilder()->newObject( 'NamespaceExaminer' )->isSemanticEnabled( $title->getNamespace() ) && + $this->skinTemplate->data['isarticle']; + } + + /** + * @since 1.9 + * + * @return true + */ + protected function performUpdate() { + + $this->toolbox['smw-browse'] = array( + 'text' => $this->skinTemplate->getSkin()->getContext()->msg( 'smw_browselink' )->text(), + 'href' => \SpecialPage::getTitleFor( 'Browse', $this->skinTemplate->getSkin()->getTitle() )->getLocalUrl(), + 'id' => 't-smwbrowselink', + 'rel' => 'smw-browse' + ); + + return true; + } +} diff --git a/includes/hooks/FunctionHookRegistry.php b/includes/hooks/FunctionHookRegistry.php index 2ed851f..891e090 100644 --- a/includes/hooks/FunctionHookRegistry.php +++ b/includes/hooks/FunctionHookRegistry.php @@ -30,6 +30,9 @@ * @return FunctionHook */ public static function register( FunctionHook $hook ) { + + // FIXME Expecting a context object to derive a builder + $hook->setDependencyBuilder( new SimpleDependencyBuilder( new SharedDependencyContainer() ) ); return $hook; } diff --git a/tests/phpunit/includes/SetupTest.php b/tests/phpunit/includes/SetupTest.php index 7a3923c..9b134cf 100644 --- a/tests/phpunit/includes/SetupTest.php +++ b/tests/phpunit/includes/SetupTest.php @@ -460,6 +460,7 @@ 'SkinAfterContent', 'OutputPageParserOutput', 'ExtensionTypes', + 'BaseTemplateToolbox' ); foreach ( $hooks as $hook ) { diff --git a/tests/phpunit/includes/dic/SharedDependencyContainerTest.php b/tests/phpunit/includes/dic/SharedDependencyContainerTest.php index 2c8d2f1..8ab3a81 100644 --- a/tests/phpunit/includes/dic/SharedDependencyContainerTest.php +++ b/tests/phpunit/includes/dic/SharedDependencyContainerTest.php @@ -124,6 +124,7 @@ $provider[] = array( 'NamespaceExaminer', array( '\SMW\NamespaceExaminer' => array() ) ); $provider[] = array( 'UpdateObserver', array( '\SMW\UpdateObserver' => array() ) ); $provider[] = array( 'ObservableUpdateDispatcher', array( '\SMW\ObservableSubjectDispatcher' => array() ) ); + $provider[] = array( 'FunctionHookRegistry', array( '\SMW\FunctionHookRegistry' => array() ) ); $provider[] = array( 'ContentParser', array( '\SMW\ContentParser' => array( 'Title' => $this->newMockBuilder()->newObject( 'Title' ) diff --git a/tests/phpunit/includes/hooks/BaseTemplateToolboxTest.php b/tests/phpunit/includes/hooks/BaseTemplateToolboxTest.php new file mode 100644 index 0000000..d98c1f7 --- /dev/null +++ b/tests/phpunit/includes/hooks/BaseTemplateToolboxTest.php @@ -0,0 +1,202 @@ +<?php + +namespace SMW\Test; + +use SMW\SharedDependencyContainer; +use SMW\BaseTemplateToolbox; + +/** + * Tests for the BaseTemplateToolbox class + * + * @file + * + * @license GNU GPL v2+ + * @since 1.9 + * + * @author mwjames + */ + +/** + * @covers \SMW\BaseTemplateToolbox + * + * @ingroup Test + * + * @group SMW + * @group SMWExtension + */ +class BaseTemplateToolboxTest extends SemanticMediaWikiTestCase { + + /** + * Returns the name of the class to be tested + * + * @return string|false + */ + public function getClass() { + return '\SMW\BaseTemplateToolbox'; + } + + /** + * Helper method that returns a BaseTemplateToolbox object + * + * @since 1.9 + * + * @return BaseTemplateToolbox + */ + private function newInstance( $skinTemplate = null, $settings = array(), &$toolbox = '' ) { + + if ( $skinTemplate === null ) { + $skinTemplate = $this->newMockBuilder()->newObject( 'SkinTemplate' ); + } + + $instance = new BaseTemplateToolbox( $skinTemplate, $toolbox ); + + $container = new SharedDependencyContainer(); + $container->registerObject( 'Settings', $this->newSettings( $settings ) ); + $instance->setDependencyBuilder( $this->newDependencyBuilder( $container ) ); + + return $instance; + } + + /** + * @test BaseTemplateToolbox::__construct + * + * @since 1.9 + */ + public function testConstructor() { + $this->assertInstanceOf( $this->getClass(), $this->newInstance() ); + } + + /** + * @test BaseTemplateToolbox::process + * @dataProvider skinTemplateDataProvider + * + * @since 1.9 + * + * @param $setup + * @param $expected + */ + public function testProcess( $setup, $expected ) { + + $toolbox = ''; + + $instance = $this->newInstance( $setup['skinTemplate'], $setup['settings'], $toolbox ); + + $this->assertTrue( + $instance->process(), + 'Asserts that process() always returns true' + ); + + if ( $expected['count'] > 0 ) { + $this->assertCount( + $expected['count'], + $toolbox['smw-browse'], + 'Asserts that process() produced a return result' + ); + } else { + $this->assertEmpty( + $toolbox, + 'Asserts that process() returned empty' + ); + } + + } + + /** + * @return array + */ + public function skinTemplateDataProvider() { + + $provider = array(); + + // #0 Standard title + $settings = array( + 'smwgNamespacesWithSemanticLinks' => array( NS_MAIN => true ), + 'smwgToolboxBrowseLink' => true + ); + + $mockSkin = $this->newMockBuilder()->newObject( 'Skin', array( + 'getTitle' => $this->newTitle(), + 'getContext' => $this->newContext() + ) ); + + $mockSkinTemplate = $this->newMockBuilder()->newObject( 'SkinTemplate', array( + 'getSkin' => $mockSkin, + ) ); + + $mockSkinTemplate->data['isarticle'] = true; + + $provider[] = array( + array( 'skinTemplate' => $mockSkinTemplate, 'settings' => $settings ), + array( 'count' => 4 ), + ); + + // #1 isarticle = false + $mockSkinTemplate = $this->newMockBuilder()->newObject( 'SkinTemplate', array( + 'getSkin' => $mockSkin, + ) ); + + $mockSkinTemplate->data['isarticle'] = false; + + $provider[] = array( + array( 'skinTemplate' => $mockSkinTemplate, 'settings' => $settings ), + array( 'count' => 0 ), + ); + + // #2 smwgToolboxBrowseLink = false + $mockSkinTemplate = $this->newMockBuilder()->newObject( 'SkinTemplate', array( + 'getSkin' => $mockSkin, + ) ); + + $mockSkinTemplate->data['isarticle'] = true; + + $settings = array( + 'smwgNamespacesWithSemanticLinks' => array( NS_MAIN => true ), + 'smwgToolboxBrowseLink' => false + ); + + $provider[] = array( + array( 'skinTemplate' => $mockSkinTemplate, 'settings' => $settings ), + array( 'count' => 0 ), + ); + + // #3 smwgNamespacesWithSemanticLinks = false + $settings = array( + 'smwgNamespacesWithSemanticLinks' => array( NS_MAIN => false ), + 'smwgToolboxBrowseLink' => true + ); + + $provider[] = array( + array( 'skinTemplate' => $mockSkinTemplate, 'settings' => $settings ), + array( 'count' => 0 ), + ); + + // #4 Special page + $settings = array( + 'smwgNamespacesWithSemanticLinks' => array( NS_MAIN => true ), + 'smwgToolboxBrowseLink' => true + ); + + $mockTitle = $this->newMockBuilder()->newObject( 'Title', array( + 'isSpecialPage' => true + ) ); + + $mockSkin = $this->newMockBuilder()->newObject( 'Skin', array( + 'getTitle' => $mockTitle, + 'getContext' => $this->newContext() + ) ); + + $mockSkinTemplate = $this->newMockBuilder()->newObject( 'SkinTemplate', array( + 'getSkin' => $mockSkin, + ) ); + + $mockSkinTemplate->data['isarticle'] = true; + + $provider[] = array( + array( 'skinTemplate' => $mockSkinTemplate, 'settings' => $settings ), + array( 'count' => 0 ), + ); + + return $provider; + } + +} -- To view, visit https://gerrit.wikimedia.org/r/85417 To unsubscribe, visit https://gerrit.wikimedia.org/r/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I4b3b7ed768479342e6a762d2dbacd3316fd510dd Gerrit-PatchSet: 1 Gerrit-Project: mediawiki/extensions/SemanticMediaWiki Gerrit-Branch: master Gerrit-Owner: Mwjames <[email protected]> _______________________________________________ MediaWiki-commits mailing list [email protected] https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits
