Mwjames has uploaded a new change for review.

  https://gerrit.wikimedia.org/r/73551


Change subject: \SMW\Setup + \SMW\HooksExtender, create testable hooks 
instantiation
......................................................................

\SMW\Setup + \SMW\HooksExtender, create testable hooks instantiation

Separating static hooks instantiation from execution and introduce
top level factory class

Change-Id: If5b07e693380423e08249d4fb2ad5f0b58885a16
---
M SemanticMediaWiki.hooks.php
M SemanticMediaWiki.php
A includes/GlobalSetup.php
M includes/Settings.php
M includes/Setup.php
A includes/hooks/BeforePageDisplay.php
A includes/hooks/ExtenderFactory.php
A includes/hooks/HooksExtender.php
A includes/hooks/InternalParseBeforeLinks.php
M tests/phpunit/MockObjectBuilder.php
M tests/phpunit/includes/HooksTest.php
A tests/phpunit/includes/hooks/BeforePageDisplayTest.php
A tests/phpunit/includes/hooks/InternalParseBeforeLinksTest.php
13 files changed, 911 insertions(+), 178 deletions(-)


  git pull 
ssh://gerrit.wikimedia.org:29418/mediawiki/extensions/SemanticMediaWiki 
refs/changes/51/73551/1

diff --git a/SemanticMediaWiki.hooks.php b/SemanticMediaWiki.hooks.php
index 346cde1..842089a 100644
--- a/SemanticMediaWiki.hooks.php
+++ b/SemanticMediaWiki.hooks.php
@@ -660,68 +660,4 @@
                return true;
        }
 
-       /**
-        * Hook: InternalParseBeforeLinks is used to process the expanded wiki
-        * code after <nowiki>, HTML-comments, and templates have been treated.
-        *
-        * This method will be called before an article is displayed or 
previewed.
-        * For display and preview we strip out the semantic properties and 
append them
-        * at the end of the article.
-        *
-        * @note MW 1.20+ see InternalParseBeforeSanitize
-        *
-        * @see Parser
-        * @see 
http://www.mediawiki.org/wiki/Manual:Hooks/InternalParseBeforeLinks
-        *
-        * @since  1.9
-        *
-        * @param Parser $parser
-        * @param string $text
-        *
-        * @return true
-        */
-       public static function onInternalParseBeforeLinks( Parser &$parser, 
&$text ) {
-
-               if ( !$parser->getTitle()->isSpecialPage() ) {
-
-                       $processor = new SMW\ParserTextProcessor(
-                               new \SMW\ParserData( $parser->getTitle(), 
$parser->getOutput() ),
-                               \SMW\Settings::newFromGlobals()
-                       );
-
-                       $processor->parse( $text );
-               }
-
-               return true;
-       }
-
-       /**
-        * Hook: Add changes to the output page, e.g. adding of CSS or 
JavaScript
-        *
-        * @see http://www.mediawiki.org/wiki/Manual:Hooks/BeforePageDisplay
-        *
-        * @since 1.9
-        *
-        * @param OutputPage $outputPage
-        * @param Skin $skin
-        *
-        * @return boolean
-        */
-       public static function onBeforePageDisplay( OutputPage &$outputPage, 
Skin &$skin ) {
-               $title = $outputPage->getTitle();
-
-               // Add style resources to avoid unstyled content
-               $outputPage->addModules( array( 'ext.smw.style' ) );
-
-               // Add export link to the head
-               if ( $title instanceof Title && !$title->isSpecialPage() ) {
-                       $linkarr['rel'] = 'ExportRDF';
-                       $linkarr['type'] = 'application/rdf+xml';
-                       $linkarr['title'] = $title->getPrefixedText();
-                       $linkarr['href'] = SpecialPage::getTitleFor( 
'ExportRDF', $title->getPrefixedText() )->getLocalUrl( 'xmlmime=rdf' );
-                       $outputPage->addLink( $linkarr );
-               }
-
-               return true;
-       }
 }
diff --git a/SemanticMediaWiki.php b/SemanticMediaWiki.php
index ee3fd54..aa862ca 100644
--- a/SemanticMediaWiki.php
+++ b/SemanticMediaWiki.php
@@ -126,3 +126,10 @@
 // User group rights
 $wgGroupPermissions['sysop']['smw-admin'] = true;
 $wgGroupPermissions['smwadministrator']['smw-admin'] = true;
+
+// New Registration and setup routine to eliminate
+// global scope of involked objects
+$wgExtensionFunctions[] = function() {
+       $setup = new \SMW\Setup( $GLOBALS );
+       $setup->run();
+};
diff --git a/includes/GlobalSetup.php b/includes/GlobalSetup.php
new file mode 100644
index 0000000..453d091
--- /dev/null
+++ b/includes/GlobalSetup.php
@@ -0,0 +1,132 @@
+<?php
+
+namespace SMW;
+
+use OutputPage;
+use Parser;
+use Skin;
+
+/**
+ * Extension setup and registration
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ * @file
+ * @codeCoverageIgnore
+ *
+ * @license GNU GPL v2+
+ * @since   1.9
+ *
+ * @author mwjames
+ */
+
+/**
+ * Extension setup and registration
+ *
+ * @ingroup SMW
+ */
+final class Setup {
+
+       /** @var array */
+       protected $globals;
+
+       /** @var Settings */
+       protected $settings;
+
+       /**
+        * @since 1.9
+        *
+        * @param array &$globals
+        */
+       public function __construct( &$globals ) {
+               $this->globals = $globals;
+       }
+
+       /**
+        * Do the actual initialisation of the extension. This is just a 
delayed init
+        * that makes sure MediaWiki is set up properly before we add our stuff.
+        *
+        * The main things this function does are: register all hooks, set up 
extension
+        * credits, and init some globals that are not for configuration 
settings.
+        *
+        * @since 1.9
+        */
+       public function run() {
+
+               Profiler::In();
+
+               $this->loadSettings();
+
+               // Register hooks after settings are loaded
+               $this->registerFunctionHooks();
+
+               Profiler::Out();
+       }
+
+       /**
+        * Load Semantic MediaWiki specific settings
+        *
+        * @since 1.9
+        */
+       protected function loadSettings() {
+
+               // $this->globals['smwgMasterStore'] = null;
+               // $this->globals['smwgIQRunningNumber'] = 0;
+               // $this->globals['smwgNamespace'] = parse_url( 
$this->globals['wgServer'], PHP_URL_HOST );
+
+               // Need some fixing because it is right now initialized during 
the
+               // include of settings
+               //$this->registerNamespaces();
+
+               // Load Settings object for general acceesibility
+               $this->settings = Settings::newFromGlobals( $this->globals );
+
+       }
+
+       /**
+        * Register function hooks
+        *
+        * @since 1.9
+        */
+       protected function registerFunctionHooks() {
+
+               $this->extender = new ExtenderFactory( $this->settings );
+
+               /**
+                * Hook: Add changes to the output page, e.g. adding of CSS or 
JavaScript
+                *
+                * @see 
http://www.mediawiki.org/wiki/Manual:Hooks/BeforePageDisplay
+                *
+                * @since 1.9
+                */
+               $this->globals['wgHooks']['BeforePageDisplay'][] = function ( 
OutputPage &$outputPage, Skin &$skin ) {
+                       return $this->extender->addHook( new BeforePageDisplay( 
$outputPage, $skin ) )->extend();
+               };
+
+               /**
+                * Hook: InternalParseBeforeLinks is used to process the 
expanded wiki
+                * code after <nowiki>, HTML-comments, and templates have been 
treated.
+                *
+                * @see 
http://www.mediawiki.org/wiki/Manual:Hooks/InternalParseBeforeLinks
+                *
+                * @since  1.9
+                */
+               $this->globals['wgHooks']['InternalParseBeforeLinks'][] = 
function ( Parser &$parser, &$text ) {
+                       return $this->extender->addHook( new 
InternalParseBeforeLinks( $parser, $text ) )->extend();
+               };
+
+       }
+}
diff --git a/includes/Settings.php b/includes/Settings.php
index db5c8c6..6cc49fd 100644
--- a/includes/Settings.php
+++ b/includes/Settings.php
@@ -56,86 +56,92 @@
         *
         * @since 1.9
         *
+        * @param array $globals
+        *
         * @return Settings
         */
-       public static function newFromGlobals() {
+       public static function newFromGlobals( $globals = null ) {
+
+               if ( $globals === null ) {
+                       $globals = $GLOBALS;
+               }
 
                $settings = array(
-                       'smwgScriptPath' => $GLOBALS['smwgScriptPath'],
-                       'smwgIP' => $GLOBALS['smwgIP'],
-                       'smwgDefaultStore' => $GLOBALS['smwgDefaultStore'],
-                       'smwgSparqlDatabase' => $GLOBALS['smwgSparqlDatabase'],
-                       'smwgSparqlQueryEndpoint' => 
$GLOBALS['smwgSparqlQueryEndpoint'],
-                       'smwgSparqlUpdateEndpoint' => 
$GLOBALS['smwgSparqlUpdateEndpoint'],
-                       'smwgSparqlDataEndpoint' => 
$GLOBALS['smwgSparqlDataEndpoint'],
-                       'smwgSparqlDefaultGraph' => 
$GLOBALS['smwgSparqlDefaultGraph'],
-                       'smwgHistoricTypeNamespace' => 
$GLOBALS['smwgHistoricTypeNamespace'],
-                       'smwgNamespaceIndex' => $GLOBALS['smwgNamespaceIndex'],
-                       'smwgShowFactbox' => $GLOBALS['smwgShowFactbox'],
-                       'smwgShowFactboxEdit' => 
$GLOBALS['smwgShowFactboxEdit'],
-                       'smwgToolboxBrowseLink' => 
$GLOBALS['smwgToolboxBrowseLink'],
-                       'smwgInlineErrors' => $GLOBALS['smwgInlineErrors'],
-                       'smwgUseCategoryHierarchy' => 
$GLOBALS['smwgUseCategoryHierarchy'],
-                       'smwgCategoriesAsInstances' => 
$GLOBALS['smwgCategoriesAsInstances'],
-                       'smwgLinksInValues' => $GLOBALS['smwgLinksInValues'],
-                       'smwgDefaultNumRecurringEvents' => 
$GLOBALS['smwgDefaultNumRecurringEvents'],
-                       'smwgMaxNumRecurringEvents' => 
$GLOBALS['smwgMaxNumRecurringEvents'],
-                       'smwgBrowseShowInverse' => 
$GLOBALS['smwgBrowseShowInverse'],
-                       'smwgBrowseShowAll' => $GLOBALS['smwgBrowseShowAll'],
-                       'smwgSearchByPropertyFuzzy' => 
$GLOBALS['smwgSearchByPropertyFuzzy'],
-                       'smwgTypePagingLimit' => 
$GLOBALS['smwgTypePagingLimit'],
-                       'smwgConceptPagingLimit' => 
$GLOBALS['smwgConceptPagingLimit'],
-                       'smwgPropertyPagingLimit' => 
$GLOBALS['smwgPropertyPagingLimit'],
-                       'smwgQEnabled' => $GLOBALS['smwgQEnabled'],
-                       'smwgQMaxLimit' => $GLOBALS['smwgQMaxLimit'],
-                       'smwgIgnoreQueryErrors' => 
$GLOBALS['smwgIgnoreQueryErrors'],
-                       'smwgQSubcategoryDepth' => 
$GLOBALS['smwgQSubcategoryDepth'],
-                       'smwgQEqualitySupport' => 
$GLOBALS['smwgQEqualitySupport'],
-                       'smwgQSortingSupport' => 
$GLOBALS['smwgQSortingSupport'],
-                       'smwgQRandSortingSupport' => 
$GLOBALS['smwgQRandSortingSupport'],
-                       'smwgQDefaultNamespaces' => 
$GLOBALS['smwgQDefaultNamespaces'],
-                       'smwgQComparators' => $GLOBALS['smwgQComparators'],
-                       'smwStrictComparators' => 
$GLOBALS['smwStrictComparators'],
-                       'smwgQMaxSize' => $GLOBALS['smwgQMaxSize'],
-                       'smwgQMaxDepth' => $GLOBALS['smwgQMaxDepth'],
-                       'smwgQFeatures' => $GLOBALS['smwgQFeatures'],
-                       'smwgQDefaultLimit' => $GLOBALS['smwgQDefaultLimit'],
-                       'smwgQMaxInlineLimit' => 
$GLOBALS['smwgQMaxInlineLimit'],
-                       'smwgQPrintoutLimit' => $GLOBALS['smwgQPrintoutLimit'],
-                       'smwgQDefaultLinking' => 
$GLOBALS['smwgQDefaultLinking'],
-                       'smwgQConceptCaching' => 
$GLOBALS['smwgQConceptCaching'],
-                       'smwgQConceptMaxSize' => 
$GLOBALS['smwgQConceptMaxSize'],
-                       'smwgQConceptMaxDepth' => 
$GLOBALS['smwgQConceptMaxDepth'],
-                       'smwgQConceptFeatures' => 
$GLOBALS['smwgQConceptFeatures'],
-                       'smwgQConceptCacheLifetime' => 
$GLOBALS['smwgQConceptCacheLifetime'],
-                       'smwgResultFormats' => $GLOBALS['smwgResultFormats'],
-                       'smwgResultAliases' => $GLOBALS['smwgResultAliases'],
-                       'smwgQuerySources' => $GLOBALS['smwgQuerySources'],
-                       'smwgPDefaultType' => $GLOBALS['smwgPDefaultType'],
-                       'smwgAllowRecursiveExport' => 
$GLOBALS['smwgAllowRecursiveExport'],
-                       'smwgExportBacklinks' => 
$GLOBALS['smwgExportBacklinks'],
-                       'smwgMaxNonExpNumber' => 
$GLOBALS['smwgMaxNonExpNumber'],
-                       'smwgEnableUpdateJobs' => 
$GLOBALS['smwgEnableUpdateJobs'],
-                       'smwgNamespacesWithSemanticLinks' => 
$GLOBALS['smwgNamespacesWithSemanticLinks'],
-                       'smwgPageSpecialProperties' => 
$GLOBALS['smwgPageSpecialProperties'],
-                       'smwgDeclarationProperties' => 
$GLOBALS['smwgDeclarationProperties'],
-                       'smwgTranslate' => $GLOBALS['smwgTranslate'],
-                       'smwgAdminRefreshStore' => 
$GLOBALS['smwgAdminRefreshStore'],
-                       'smwgAutocompleteInSpecialAsk' => 
$GLOBALS['smwgAutocompleteInSpecialAsk'],
-                       'smwgAutoRefreshSubject' => 
$GLOBALS['smwgAutoRefreshSubject'],
-                       'smwgAutoRefreshOnPurge' => 
$GLOBALS['smwgAutoRefreshOnPurge'],
-                       'smwgAutoRefreshOnPageMove' => 
$GLOBALS['smwgAutoRefreshOnPageMove'],
-                       'smwgContLang' => $GLOBALS['smwgContLang'],
-                       'smwgMaxPropertyValues' => 
$GLOBALS['smwgMaxPropertyValues'],
-                       'smwgQSubpropertyDepth' => 
$GLOBALS['smwgQSubpropertyDepth'],
-                       'smwgNamespace' => $GLOBALS['smwgNamespace'],
-                       'smwgMasterStore' => $GLOBALS['smwgMasterStore'],
-                       'smwgIQRunningNumber' => 
$GLOBALS['smwgIQRunningNumber'],
-                       'smwgCacheType' => $GLOBALS['smwgCacheType'],
-                       'smwgCacheUsage' => $GLOBALS['smwgCacheUsage'],
-                       'smwgFixedProperties' => 
$GLOBALS['smwgFixedProperties'],
-                       'smwgPropertyLowUsageThreshold' => 
$GLOBALS['smwgPropertyLowUsageThreshold'],
-                       'smwgPropertyZeroCountDisplay' => 
$GLOBALS['smwgPropertyZeroCountDisplay'],
+                       'smwgScriptPath' => $globals['smwgScriptPath'],
+                       'smwgIP' => $globals['smwgIP'],
+                       'smwgDefaultStore' => $globals['smwgDefaultStore'],
+                       'smwgSparqlDatabase' => $globals['smwgSparqlDatabase'],
+                       'smwgSparqlQueryEndpoint' => 
$globals['smwgSparqlQueryEndpoint'],
+                       'smwgSparqlUpdateEndpoint' => 
$globals['smwgSparqlUpdateEndpoint'],
+                       'smwgSparqlDataEndpoint' => 
$globals['smwgSparqlDataEndpoint'],
+                       'smwgSparqlDefaultGraph' => 
$globals['smwgSparqlDefaultGraph'],
+                       'smwgHistoricTypeNamespace' => 
$globals['smwgHistoricTypeNamespace'],
+                       'smwgNamespaceIndex' => $globals['smwgNamespaceIndex'],
+                       'smwgShowFactbox' => $globals['smwgShowFactbox'],
+                       'smwgShowFactboxEdit' => 
$globals['smwgShowFactboxEdit'],
+                       'smwgToolboxBrowseLink' => 
$globals['smwgToolboxBrowseLink'],
+                       'smwgInlineErrors' => $globals['smwgInlineErrors'],
+                       'smwgUseCategoryHierarchy' => 
$globals['smwgUseCategoryHierarchy'],
+                       'smwgCategoriesAsInstances' => 
$globals['smwgCategoriesAsInstances'],
+                       'smwgLinksInValues' => $globals['smwgLinksInValues'],
+                       'smwgDefaultNumRecurringEvents' => 
$globals['smwgDefaultNumRecurringEvents'],
+                       'smwgMaxNumRecurringEvents' => 
$globals['smwgMaxNumRecurringEvents'],
+                       'smwgBrowseShowInverse' => 
$globals['smwgBrowseShowInverse'],
+                       'smwgBrowseShowAll' => $globals['smwgBrowseShowAll'],
+                       'smwgSearchByPropertyFuzzy' => 
$globals['smwgSearchByPropertyFuzzy'],
+                       'smwgTypePagingLimit' => 
$globals['smwgTypePagingLimit'],
+                       'smwgConceptPagingLimit' => 
$globals['smwgConceptPagingLimit'],
+                       'smwgPropertyPagingLimit' => 
$globals['smwgPropertyPagingLimit'],
+                       'smwgQEnabled' => $globals['smwgQEnabled'],
+                       'smwgQMaxLimit' => $globals['smwgQMaxLimit'],
+                       'smwgIgnoreQueryErrors' => 
$globals['smwgIgnoreQueryErrors'],
+                       'smwgQSubcategoryDepth' => 
$globals['smwgQSubcategoryDepth'],
+                       'smwgQEqualitySupport' => 
$globals['smwgQEqualitySupport'],
+                       'smwgQSortingSupport' => 
$globals['smwgQSortingSupport'],
+                       'smwgQRandSortingSupport' => 
$globals['smwgQRandSortingSupport'],
+                       'smwgQDefaultNamespaces' => 
$globals['smwgQDefaultNamespaces'],
+                       'smwgQComparators' => $globals['smwgQComparators'],
+                       'smwStrictComparators' => 
$globals['smwStrictComparators'],
+                       'smwgQMaxSize' => $globals['smwgQMaxSize'],
+                       'smwgQMaxDepth' => $globals['smwgQMaxDepth'],
+                       'smwgQFeatures' => $globals['smwgQFeatures'],
+                       'smwgQDefaultLimit' => $globals['smwgQDefaultLimit'],
+                       'smwgQMaxInlineLimit' => 
$globals['smwgQMaxInlineLimit'],
+                       'smwgQPrintoutLimit' => $globals['smwgQPrintoutLimit'],
+                       'smwgQDefaultLinking' => 
$globals['smwgQDefaultLinking'],
+                       'smwgQConceptCaching' => 
$globals['smwgQConceptCaching'],
+                       'smwgQConceptMaxSize' => 
$globals['smwgQConceptMaxSize'],
+                       'smwgQConceptMaxDepth' => 
$globals['smwgQConceptMaxDepth'],
+                       'smwgQConceptFeatures' => 
$globals['smwgQConceptFeatures'],
+                       'smwgQConceptCacheLifetime' => 
$globals['smwgQConceptCacheLifetime'],
+                       'smwgResultFormats' => $globals['smwgResultFormats'],
+                       'smwgResultAliases' => $globals['smwgResultAliases'],
+                       'smwgQuerySources' => $globals['smwgQuerySources'],
+                       'smwgPDefaultType' => $globals['smwgPDefaultType'],
+                       'smwgAllowRecursiveExport' => 
$globals['smwgAllowRecursiveExport'],
+                       'smwgExportBacklinks' => 
$globals['smwgExportBacklinks'],
+                       'smwgMaxNonExpNumber' => 
$globals['smwgMaxNonExpNumber'],
+                       'smwgEnableUpdateJobs' => 
$globals['smwgEnableUpdateJobs'],
+                       'smwgNamespacesWithSemanticLinks' => 
$globals['smwgNamespacesWithSemanticLinks'],
+                       'smwgPageSpecialProperties' => 
$globals['smwgPageSpecialProperties'],
+                       'smwgDeclarationProperties' => 
$globals['smwgDeclarationProperties'],
+                       'smwgTranslate' => $globals['smwgTranslate'],
+                       'smwgAdminRefreshStore' => 
$globals['smwgAdminRefreshStore'],
+                       'smwgAutocompleteInSpecialAsk' => 
$globals['smwgAutocompleteInSpecialAsk'],
+                       'smwgAutoRefreshSubject' => 
$globals['smwgAutoRefreshSubject'],
+                       'smwgAutoRefreshOnPurge' => 
$globals['smwgAutoRefreshOnPurge'],
+                       'smwgAutoRefreshOnPageMove' => 
$globals['smwgAutoRefreshOnPageMove'],
+                       'smwgContLang' => $globals['smwgContLang'],
+                       'smwgMaxPropertyValues' => 
$globals['smwgMaxPropertyValues'],
+                       'smwgQSubpropertyDepth' => 
$globals['smwgQSubpropertyDepth'],
+                       'smwgNamespace' => $globals['smwgNamespace'],
+                       'smwgMasterStore' => $globals['smwgMasterStore'],
+                       'smwgIQRunningNumber' => 
$globals['smwgIQRunningNumber'],
+                       'smwgCacheType' => $globals['smwgCacheType'],
+                       'smwgCacheUsage' => $globals['smwgCacheUsage'],
+                       'smwgFixedProperties' => 
$globals['smwgFixedProperties'],
+                       'smwgPropertyLowUsageThreshold' => 
$globals['smwgPropertyLowUsageThreshold'],
+                       'smwgPropertyZeroCountDisplay' => 
$globals['smwgPropertyZeroCountDisplay'],
                );
 
                if ( self::$instance === null ) {
diff --git a/includes/Setup.php b/includes/Setup.php
index 54e758e..11a6d24 100644
--- a/includes/Setup.php
+++ b/includes/Setup.php
@@ -76,9 +76,6 @@
        // Additional special properties (modification date etc.)
        $wgHooks['NewRevisionFromEditComplete'][] = 
'SMWHooks::onNewRevisionFromEditComplete';
 
-       // Parsing [[link::syntax]] and resolves property annotations
-       $wgHooks['InternalParseBeforeLinks'][] = 
'SMWHooks::onInternalParseBeforeLinks';
-
        $wgHooks['OutputPageParserOutput'][] = 
'SMWFactbox::onOutputPageParserOutput'; // copy some data for later Factbox 
display
        $wgHooks['ArticleFromTitle'][] = 'SMWHooks::onArticleFromTitle'; // 
special implementations for property/type articles
        $wgHooks['ParserFirstCallInit'][] = 'SMWHooks::onParserFirstCallInit';
@@ -97,7 +94,6 @@
        $wgHooks['GetPreferences'][] = 'SMWHooks::onGetPreferences';
 
        // Add changes to the output page
-       $wgHooks['BeforePageDisplay'][] = 'SMWHooks::onBeforePageDisplay';
        $wgHooks['TitleIsAlwaysKnown'][] = 'SMWHooks::onTitleIsAlwaysKnown';
        $wgHooks['BeforeDisplayNoArticleText'][] = 
'SMWHooks::onBeforeDisplayNoArticleText';
 
@@ -124,6 +120,14 @@
        $wgAutoloadClasses['SMWHooks']                  = $smwgIP . 
'SemanticMediaWiki.hooks.php';
 
        $incDir = $smwgIP . 'includes/';
+       $wgAutoloadClasses['SMW\Setup']                    = $incDir . 
'GlobalSetup.php'; // rename to Setup after all registration has been moved
+
+       $wgAutoloadClasses['SMW\Extender']                 = $incDir . 
'/hooks/HooksExtender.php';
+       $wgAutoloadClasses['SMW\HooksExtender']            = $incDir . 
'/hooks/HooksExtender.php';
+       $wgAutoloadClasses['SMW\ExtenderFactory']          = $incDir . 
'/hooks/ExtenderFactory.php';
+       $wgAutoloadClasses['SMW\BeforePageDisplay']        = $incDir . 
'/hooks/BeforePageDisplay.php';
+       $wgAutoloadClasses['SMW\InternalParseBeforeLinks'] = $incDir . 
'/hooks/InternalParseBeforeLinks.php';
+
        $wgAutoloadClasses['SMW\FormatFactory']         = $incDir . 
'FormatFactory.php';
        $wgAutoloadClasses['SMW\Highlighter']           = $incDir . 
'Highlighter.php';
        $wgAutoloadClasses['SMW\ParameterInput']        = $incDir . 
'ParameterInput.php';
diff --git a/includes/hooks/BeforePageDisplay.php 
b/includes/hooks/BeforePageDisplay.php
new file mode 100644
index 0000000..0ae7321
--- /dev/null
+++ b/includes/hooks/BeforePageDisplay.php
@@ -0,0 +1,95 @@
+<?php
+
+namespace SMW;
+
+use OutputPage;
+use Skin;
+use Title;
+use SpecialPage;
+
+/**
+ * Augments the output page
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ * @file
+ *
+ * @license GNU GPL v2+
+ * @since   1.9
+ *
+ * @author mwjames
+ */
+
+/**
+ * Hook: Add changes to the output page, e.g. adding of CSS or JavaScript
+ *
+ * @see http://www.mediawiki.org/wiki/Manual:Hooks/BeforePageDisplay
+ *
+ * @since 1.9
+ *
+ * @ingroup Extender
+ */
+class BeforePageDisplay extends HooksExtender {
+
+       /**
+        * @since 1.9
+        *
+        * @param OutputPage $outputPage
+        * @param Skin $skin
+        */
+       public function __construct( OutputPage &$outputPage, Skin &$skin ) {
+               $this->outputPage = $outputPage;
+               $this->skin = $skin;
+       }
+
+       /**
+        * Returns associative array
+        *
+        * @since 1.9
+        *
+        * @return array
+        */
+       protected function getExportLink( Title $title ) {
+               return array(
+                       'rel'   => 'ExportRDF',
+                       'type'  => 'application/rdf+xml',
+                       'title' => $title->getPrefixedText(),
+                       'href'  => SpecialPage::getTitleFor( 'ExportRDF', 
$title->getPrefixedText() )->getLocalUrl( 'xmlmime=rdf' )
+               );
+       }
+
+       /**
+        * Extends the BeforePageDisplay hook
+        *
+        * @since 1.9
+        *
+        * @return boolean
+        */
+       public function extend() {
+
+               $title = $this->outputPage->getTitle();
+
+               // Add style resources to avoid unstyled content
+               $this->outputPage->addModules( array( 'ext.smw.style' ) );
+
+               if ( $title instanceof Title && !$title->isSpecialPage() ) {
+                       $this->outputPage->addLink( $this->getExportLink( 
$title ) );
+               }
+
+               return true;
+       }
+
+}
diff --git a/includes/hooks/ExtenderFactory.php 
b/includes/hooks/ExtenderFactory.php
new file mode 100644
index 0000000..0ec4e52
--- /dev/null
+++ b/includes/hooks/ExtenderFactory.php
@@ -0,0 +1,65 @@
+<?php
+
+namespace SMW;
+
+/**
+ * ...
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ * @file
+ *
+ * @license GNU GPL v2+
+ * @since   1.9
+ *
+ * @author mwjames
+ */
+
+/**
+ * Collector base class
+ *
+ * @ingroup Extender
+ */
+class ExtenderFactory {
+
+       /** @var Settings */
+       protected $settings;
+
+       /**
+        * @since 1.9
+        *
+        * @param Settings $settings
+        */
+       public function __construct( Settings $settings ) {
+               $this->settings = $settings;
+       }
+
+       /**
+        * Collects and returns information in an associative array
+        *
+        * @since 1.9
+        *
+        * @param Extendable $extender
+        *
+        * @return HooksExtender
+        */
+       public function addHook( HooksExtender $extender ) {
+               $extender->setAccessor( new ArrayAccessor( array( 'settings' => 
$this->settings ) ) );
+
+               return $extender->setSettings( $this->settings );
+       }
+
+}
diff --git a/includes/hooks/HooksExtender.php b/includes/hooks/HooksExtender.php
new file mode 100644
index 0000000..1ef3d85
--- /dev/null
+++ b/includes/hooks/HooksExtender.php
@@ -0,0 +1,189 @@
+<?php
+
+namespace SMW;
+
+/**
+ * Base class that allows to augment invoked objects through MW's
+ * hook interface
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ * @file
+ *
+ * @license GNU GPL v2+
+ * @since   1.9
+ *
+ * @author mwjames
+ */
+interface Extender {
+
+       /**
+        * Implements access to an Accessor object
+        *
+        * @since 1.9
+        *
+        * @param Accessor $accessor
+        *
+        * @return mixed
+        */
+       public function setAccessor( Accessor $accessor );
+
+       /**
+        * Returns an Accessor object
+        *
+        * @since 1.9
+        *
+        * @return Accessor
+        */
+       public function getAccessor();
+
+       /**
+        * Implements the extension of invoked objects
+        *
+        * @since 1.9
+        *
+        * @return true
+        */
+       public function extend();
+
+}
+
+/**
+ * Base class that allows to augment invoked objects through MW's
+ * hook interface
+ *
+ * @ingroup Extender
+ */
+abstract class HooksExtender implements Extender {
+
+       /** @var Settings */
+       protected $settings;
+
+       /** @var Accessor */
+       protected $accessor;
+
+       /** @var Store */
+       protected $store = null;
+
+       /** @var CacheHandler */
+       protected $cache = null;
+
+       /**
+        * Sets an Accessor object
+        *
+        * @since 1.9
+        *
+        * @param Accessor $accessor
+        *
+        * @return Extender
+        */
+       public function setAccessor( Accessor $accessor ) {
+               $this->accessor = $accessor;
+               return $this;
+       }
+
+       /**
+        * Returns an Accessor object
+        *
+        * @since 1.9
+        *
+        * @return Extender
+        */
+       public function getAccessor() {
+               return $this->accessor;
+       }
+
+       /**
+        * Set Settings
+        *
+        * @since 1.9
+        *
+        * @param Settings $settings
+        *
+        * @return Extender
+        */
+       public function setSettings( Settings $settings ) {
+               $this->settings = $settings;
+               return $this;
+       }
+
+       /**
+        * Set Store
+        *
+        * @since 1.9
+        *
+        * @param Store $store
+        *
+        * @return Extender
+        */
+       public function setStore( Store $store ) {
+               $this->store = $store;
+               return $this;
+       }
+
+       /**
+        * Returns invoked Settings object
+        *
+        * @since 1.9
+        *
+        * @return Settings
+        */
+       public function getSettings() {
+               return $this->settings;
+       }
+
+       /**
+        * Returns invoked Store object
+        *
+        * @since 1.9
+        *
+        * @return Store
+        */
+       public function getStore() {
+
+               if ( $this->store === null ) {
+                       $this->store = StoreFactory::getStore( 
$this->settings->get( 'smwgDefaultStore' ) );
+               }
+
+               return $this->store;
+
+       }
+
+       /**
+        * Returns a CacheHandler object
+        *
+        * @since 1.9
+        *
+        * @return CacheHandler
+        */
+       public function getCache() {
+
+               if ( $this->cache === null ) {
+                       $this->cache = CacheHandler::newFromId( 
$this->settings->get( 'smwgCacheType' ) );
+               }
+
+               return $this->cache;
+       }
+
+       /**
+        * Sub-class is responsible for implementing the extension
+        *
+        * @since 1.9
+        *
+        * @return true
+        */
+       public abstract function extend();
+}
diff --git a/includes/hooks/InternalParseBeforeLinks.php 
b/includes/hooks/InternalParseBeforeLinks.php
new file mode 100644
index 0000000..cd7abab
--- /dev/null
+++ b/includes/hooks/InternalParseBeforeLinks.php
@@ -0,0 +1,85 @@
+<?php
+
+namespace SMW;
+
+use Parser;
+
+/**
+ * Extends and complements InternalParseBeforeLinks hook
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ * @file
+ *
+ * @license GNU GPL v2+
+ * @since   1.9
+ *
+ * @author mwjames
+ */
+
+/**
+ * Hook: InternalParseBeforeLinks is used to process the expanded wiki
+ * code after <nowiki>, HTML-comments, and templates have been treated.
+ *
+ * This method will be called before an article is displayed or previewed.
+ * For display and preview we strip out the semantic properties and append them
+ * at the end of the article.
+ *
+ * @note MW 1.20+ see InternalParseBeforeSanitize
+ *
+ * @see http://www.mediawiki.org/wiki/Manual:Hooks/InternalParseBeforeLinks
+ *
+ * @since 1.9
+ *
+ * @ingroup Extender
+ */
+class InternalParseBeforeLinks extends HooksExtender {
+
+       /**
+        * @since 1.9
+        *
+        * @param Parser $parser
+        * @param string $text
+        */
+       public function __construct( Parser &$parser, &$text ) {
+               $this->parser = $parser;
+               $this->text = $text;
+       }
+
+       /**
+        * Augment invoked objects in order to allow parsing [[link::syntax]] 
and
+        * resolving of property annotations
+        *
+        * @since 1.9
+        *
+        * @return boolean
+        */
+       public function extend() {
+
+               if ( !$this->parser->getTitle()->isSpecialPage() ) {
+
+                       $processor = new ParserTextProcessor(
+                               new ParserData( $this->parser->getTitle(), 
$this->parser->getOutput() ),
+                               $this->getSettings()
+                       );
+
+                       $processor->parse( $this->text );
+               }
+
+               return true;
+       }
+
+}
diff --git a/tests/phpunit/MockObjectBuilder.php 
b/tests/phpunit/MockObjectBuilder.php
index 7479de6..f320aba 100644
--- a/tests/phpunit/MockObjectBuilder.php
+++ b/tests/phpunit/MockObjectBuilder.php
@@ -335,6 +335,14 @@
                        ->will( $this->returnValue( $this->set( 'exists' ) ) );
 
                $title->expects( $this->any() )
+                       ->method( 'isSpecialPage' )
+                       ->will( $this->returnValue( $this->set( 
'isSpecialPage', false ) ) );
+
+               $title->expects( $this->any() )
+                       ->method( 'getContentModel' )
+                       ->will( $this->returnValue( $this->set( 
'getContentModel', CONTENT_MODEL_WIKITEXT ) ) );
+
+               $title->expects( $this->any() )
                        ->method( 'getLatestRevID' )
                        ->will( $this->returnValue( rand( 10, 5000 ) ) );
 
@@ -349,4 +357,20 @@
                return $title;
        }
 
+       /**
+        * Helper method that returns a Skin object
+        *
+        * @since 1.9
+        *
+        * @return Skin
+        */
+       public function getMockSkin() {
+
+               $skin = $this->getMockBuilder( 'Skin' )
+               ->disableOriginalConstructor()
+               ->getMock();
+
+               return $skin;
+       }
+
 }
diff --git a/tests/phpunit/includes/HooksTest.php 
b/tests/phpunit/includes/HooksTest.php
index ffa14a6..f20fe7a 100644
--- a/tests/phpunit/includes/HooksTest.php
+++ b/tests/phpunit/includes/HooksTest.php
@@ -478,21 +478,6 @@
        }
 
        /**
-        * @test SMWHooks::onInternalParseBeforeLinks
-        * @dataProvider getTextDataProvider
-        *
-        * @since 1.9
-        *
-        * @param $text
-        */
-       public function testOnInternalParseBeforeLinks( $text ) {
-               $parser = $this->getParser();
-               $result = SMWHooks::onInternalParseBeforeLinks( $parser, $text 
);
-
-               $this->assertTrue( $result );
-       }
-
-       /**
         * @test SMWHooks::onGetPreferences
         *
         * @since 1.9
@@ -578,25 +563,6 @@
                } else {
                        $this->assertTrue( $skip );
                }
-       }
-
-       /**
-        * @test SMWHooks::onBeforePageDisplay
-        *
-        * @since 1.9
-        */
-       public function testOnBeforePageDisplay() {
-               $context = new \RequestContext();
-               $context->setTitle( $this->getTitle() );
-               $context->setLanguage( \Language::factory( 'en' ) );
-
-               $skin = new \SkinTemplate();
-               $skin->setContext( $context );
-
-               $outputPage = new \OutputPage( $context );
-
-               $result = SMWHooks::onBeforePageDisplay( $outputPage, $skin );
-               $this->assertTrue( $result );
        }
 
 }
diff --git a/tests/phpunit/includes/hooks/BeforePageDisplayTest.php 
b/tests/phpunit/includes/hooks/BeforePageDisplayTest.php
new file mode 100644
index 0000000..a8088c6
--- /dev/null
+++ b/tests/phpunit/includes/hooks/BeforePageDisplayTest.php
@@ -0,0 +1,114 @@
+<?php
+
+namespace SMW\Test;
+
+use SMW\BeforePageDisplay;
+
+use OutputPage;
+use Title;
+
+/**
+ * Tests for the BeforePageDisplay class
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ * @file
+ *
+ * @license GNU GPL v2+
+ * @since   1.9
+ *
+ * @author mwjames
+ */
+
+/**
+ * @covers \SMW\BeforePageDisplay
+ *
+ * @ingroup Test
+ *
+ * @group SMW
+ * @group SMWExtension
+ */
+class BeforePageDisplayTest extends SemanticMediaWikiTestCase {
+
+       /**
+        * Returns the name of the class to be tested
+        *
+        * @return string|false
+        */
+       public function getClass() {
+               return '\SMW\BeforePageDisplay';
+       }
+
+       /**
+        * Helper method that returns a OutputPage object
+        *
+        * @since 1.9
+        *
+        * @return OutputPage
+        */
+       private function getOutputPage() {
+
+               $context = $this->newContext();
+               $context->setTitle( $this->getTitle() );
+               $context->setLanguage( $this->getLanguage() );
+
+               return new OutputPage( $context );
+       }
+
+       /**
+        * Returns a BeforePageDisplay object
+        *
+        * @since 1.9
+        */
+       public function getInstance( OutputPage $outputPage ) {
+               $skin = $this->newMockObject()->getMockSkin();
+               return new BeforePageDisplay( $outputPage, $skin );
+       }
+
+       /**
+        * @test BeforePageDisplay::__construct
+        *
+        * @since 1.9
+        */
+       public function testConstructor() {
+               $this->assertInstanceOf( $this->getClass(), $this->getInstance( 
$this->getOutputPage() ) );
+       }
+
+       /**
+        * @test BeforePageDisplay::extend
+        *
+        * @since 1.9
+        */
+       public function testExtend() {
+
+               $outputPage = $this->getOutputPage();
+               $result     = $this->getInstance( $outputPage )->extend();
+
+               $this->assertInternalType( 'boolean', $result );
+               $this->assertTrue( $result );
+
+               // Check if content was added to the output object
+               $contains = false;
+               foreach (  $outputPage->getHeadLinksArray() as $key => $value ) 
{
+                       if ( strpos( $value, 'ExportRDF' ) ){
+                               $contains = true;
+                               break;
+                       };
+               }
+
+               $this->assertTrue( $contains );
+       }
+}
diff --git a/tests/phpunit/includes/hooks/InternalParseBeforeLinksTest.php 
b/tests/phpunit/includes/hooks/InternalParseBeforeLinksTest.php
new file mode 100644
index 0000000..8fd777a
--- /dev/null
+++ b/tests/phpunit/includes/hooks/InternalParseBeforeLinksTest.php
@@ -0,0 +1,110 @@
+<?php
+
+namespace SMW\Test;
+
+use SMW\InternalParseBeforeLinks;
+
+use Title;
+
+/**
+ * Tests for the InternalParseBeforeLinks class
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ * @file
+ *
+ * @license GNU GPL v2+
+ * @since   1.9
+ *
+ * @author mwjames
+ */
+
+/**
+ * @covers \SMW\InternalParseBeforeLinks
+ *
+ * @ingroup Test
+ *
+ * @group SMW
+ * @group SMWExtension
+ */
+class InternalParseBeforeLinksTest extends ParserTestCase {
+
+       /** @var array */
+       protected $parser;
+
+       /**
+        * Returns the name of the class to be tested
+        *
+        * @return string|false
+        */
+       public function getClass() {
+               return '\SMW\InternalParseBeforeLinks';
+       }
+
+       /**
+        * Returns a InternalParseBeforeLinks object
+        *
+        * @since 1.9
+        */
+       public function getInstance( Title $title = null, $text = '' ) {
+
+               $settings = array(
+                       'smwgNamespacesWithSemanticLinks' => array( NS_MAIN => 
true ),
+                       'smwgLinksInValues' => false,
+                       'smwgInlineErrors' => true,
+               );
+
+               $title  = $title === null ? $this->getTitle() : $title;
+               $parser = $this->getParser( $title, $this->getUser() );
+
+               $instance = new InternalParseBeforeLinks( $parser, $text );
+               $instance->setSettings( $this->getSettings( $settings ) );
+
+               return $instance;
+       }
+
+       /**
+        * @test InternalParseBeforeLinks::__construct
+        *
+        * @since 1.9
+        */
+       public function testConstructor() {
+               $this->assertInstanceOf( $this->getClass(), 
$this->getInstance() );
+       }
+
+       /**
+        * @test InternalParseBeforeLinks::extend
+        *
+        * @since 1.9
+        */
+       public function testExtend() {
+
+               $result = $this->getInstance()->extend();
+
+               $this->assertInternalType( 'boolean', $result );
+               $this->assertTrue( $result );
+
+               // Title is special page
+               $title  = $this->newMockObject( array(
+                       'isSpecialPage' => true
+               ) )->getMockTitle();
+               $result = $this->getInstance( $title )->extend();
+
+               $this->assertInternalType( 'boolean', $result );
+               $this->assertTrue( $result );
+
+       }
+}

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

Gerrit-MessageType: newchange
Gerrit-Change-Id: If5b07e693380423e08249d4fb2ad5f0b58885a16
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

Reply via email to