Merge "Respect $wgApiFrameOptions in formatted API output mode"
authorjenkins-bot <jenkins-bot@gerrit.wikimedia.org>
Thu, 23 Oct 2014 18:24:48 +0000 (18:24 +0000)
committerGerrit Code Review <gerrit@wikimedia.org>
Thu, 23 Oct 2014 18:24:48 +0000 (18:24 +0000)
13 files changed:
api.php
docs/hooks.txt
includes/PrefixSearch.php
includes/actions/InfoAction.php
includes/api/ApiMain.php
resources/src/mediawiki.ui/components/buttons.less
tests/phpunit/includes/TitleTest.php
tests/phpunit/includes/UserTest.php
tests/phpunit/includes/api/ApiOptionsTest.php
tests/phpunit/includes/api/query/ApiQueryTest.php
tests/phpunit/includes/cache/LocalisationCacheTest.php
tests/phpunit/includes/content/TextContentTest.php
tests/phpunit/structure/AutoLoaderTest.php

diff --git a/api.php b/api.php
index 2a6a095..7974f15 100644 (file)
--- a/api.php
+++ b/api.php
@@ -62,14 +62,14 @@ if ( !$wgEnableAPI ) {
 // In a perfect world this wouldn't be necessary
 $wgTitle = Title::makeTitle( NS_MAIN, 'API' );
 
-/* Construct an ApiMain with the arguments passed via the URL. What we get back
- * is some form of an ApiMain, possibly even one that produces an error message,
- * but we don't care here, as that is handled by the ctor.
- */
-$processor = new ApiMain( RequestContext::getMain(), $wgEnableWriteAPI );
-
-// Last chance hook before executing the API
 try {
+       /* Construct an ApiMain with the arguments passed via the URL. What we get back
+        * is some form of an ApiMain, possibly even one that produces an error message,
+        * but we don't care here, as that is handled by the ctor.
+        */
+       $processor = new ApiMain( RequestContext::getMain(), $wgEnableWriteAPI );
+
+       // Last chance hook before executing the API
        wfRunHooks( 'ApiBeforeMain', array( &$processor ) );
        if ( !$processor instanceof ApiMain ) {
                throw new MWException( 'ApiBeforMain hook set $processor to a non-ApiMain class' );
index 6fb10b1..b71c347 100644 (file)
@@ -2139,6 +2139,13 @@ $search : search term (not guaranteed to be conveniently normalized)
 $limit : maximum number of results to return
 &$results : out param: array of page names (strings)
 
+'PrefixSearchExtractNamespace': Called if core was not able to extract a
+namespace from the search string so that extensions can attempt it.
+$namespaces : array of int namespace keys to search in (change this if you can
+extract namespaces)
+$search : search term (replace this with term without the namespace if you can
+extract one)
+
 'PrefsEmailAudit': Called when user changes their email address.
 $user: User (object) changing his email address
 $oldaddr: old email address (string)
index 5df0ce7..839fedc 100644 (file)
@@ -60,10 +60,12 @@ abstract class PrefixSearch {
                $title = Title::newFromText( $search );
                if ( $title && !$title->isExternal() ) {
                        $ns = array( $title->getNamespace() );
+                       $search = $title->getText();
                        if ( $ns[0] == NS_MAIN ) {
                                $ns = $namespaces; // no explicit prefix, use default namespaces
+                               wfRunHooks( 'PrefixSearchExtractNamespace', array( &$ns, &$search ) );
                        }
-                       return $this->searchBackend( $ns, $title->getText(), $limit );
+                       return $this->searchBackend( $ns, $search, $limit );
                }
 
                // Is this a namespace prefix?
@@ -74,6 +76,8 @@ abstract class PrefixSearch {
                {
                        $namespaces = array( $title->getNamespace() );
                        $search = '';
+               } else {
+                       wfRunHooks( 'PrefixSearchExtractNamespace', array( &$namespaces, &$search ) );
                }
 
                return $this->searchBackend( $namespaces, $search, $limit );
index 12e845b..e7455f6 100644 (file)
@@ -290,7 +290,7 @@ class InfoAction extends FormlessAction {
 
                $pageInfo['header-basic'][] = array( $langDisp,
                        Language::fetchLanguageName( $pageLang, $lang->getCode() )
-                       . ' ' . $this->msg( 'parentheses', $pageLang ) );
+                       . ' ' . $this->msg( 'parentheses', $pageLang )->escaped() );
 
                // Content model of the page
                $pageInfo['header-basic'][] = array(
index c9e898c..bf26eee 100644 (file)
@@ -197,7 +197,8 @@ class ApiMain extends ApiBase {
                $this->getContext()->setLanguage( $code );
                if ( !$this->mInternalMode ) {
                        global $wgLang;
-                       $wgLang = RequestContext::getMain()->getLanguage();
+                       $wgLang = $this->getContext()->getLanguage();
+                       RequestContext::getMain()->setLanguage( $wgLang );
                }
 
                $config = $this->getConfig();
index 2512d49..6ba7bf7 100644 (file)
 
        // Destructive buttons
        //
-       // Use destructive buttons for actions which result in the destruction of data.
-       // e.g. deleting a page.
+       // Use destructive buttons for actions that remove or limit, such as deleting a page or blocking a user.
        // This should not be used for cancel buttons.
        //
        // Markup:
index fb58381..a4bc427 100644 (file)
@@ -428,14 +428,14 @@ class TitleTest extends MediaWikiTestCase {
        public function testGetPageViewLanguage( $expected, $titleText, $contLang,
                $lang, $variant, $msg = ''
        ) {
-               global $wgLanguageCode, $wgContLang, $wgLang, $wgDefaultLanguageVariant, $wgAllowUserJs;
-
                // Setup environnement for this test
-               $wgLanguageCode = $contLang;
-               $wgContLang = Language::factory( $contLang );
-               $wgLang = Language::factory( $lang );
-               $wgDefaultLanguageVariant = $variant;
-               $wgAllowUserJs = true;
+               $this->setMwGlobals( array(
+                       'wgLanguageCode' => $contLang,
+                       'wgContLang' => Language::factory( $contLang ),
+                       'wgLang' => Language::factory( $lang ),
+                       'wgDefaultLanguageVariant' => $variant,
+                       'wgAllowUserJs' => true,
+               ) );
 
                $title = Title::newFromText( $titleText );
                $this->assertInstanceOf( 'Title', $title,
index a0c20bb..f9ef317 100644 (file)
@@ -281,9 +281,7 @@ class UserTest extends MediaWikiTestCase {
         * @covers User::getPasswordExpired()
         */
        public function testPasswordExpire() {
-               global $wgPasswordExpireGrace;
-               $wgTemp = $wgPasswordExpireGrace;
-               $wgPasswordExpireGrace = 3600 * 24 * 7; // 7 days
+               $this->setMwGlobals( 'wgPasswordExpireGrace', 3600 * 24 * 7 ); // 7 days
 
                $user = User::newFromName( 'UnitTestUser' );
                $user->loadDefaults( 'UnitTestUser' );
@@ -296,8 +294,6 @@ class UserTest extends MediaWikiTestCase {
                $ts = time() - ( 3600 * 24 * 10 ); // 10 days ago
                $user->expirePassword( $ts );
                $this->assertEquals( 'hard', $user->getPasswordExpired() );
-
-               $wgPasswordExpireGrace = $wgTemp;
        }
 
        /**
index 5f955bb..bd34018 100644 (file)
@@ -17,8 +17,6 @@ class ApiOptionsTest extends MediaWikiLangTestCase {
        /** @var DerivativeContext */
        private $mContext;
 
-       private $mOldGetPreferencesHooks;
-
        private static $Success = array( 'options' => 'success' );
 
        protected function setUp() {
@@ -50,21 +48,11 @@ class ApiOptionsTest extends MediaWikiLangTestCase {
 
                $this->mTested = new ApiOptions( $main, 'options' );
 
-               global $wgHooks;
-               if ( !isset( $wgHooks['GetPreferences'] ) ) {
-                       $wgHooks['GetPreferences'] = array();
-               }
-               $this->mOldGetPreferencesHooks = $wgHooks['GetPreferences'];
-               $wgHooks['GetPreferences'][] = array( $this, 'hookGetPreferences' );
-       }
-
-       protected function tearDown() {
-               global $wgHooks;
-
-               $wgHooks['GetPreferences'] = $this->mOldGetPreferencesHooks;
-               $this->mOldGetPreferencesHooks = false;
-
-               parent::tearDown();
+               $this->mergeMwGlobalArrayValue( 'wgHooks', array(
+                       'GetPreferences' => array(
+                               array( $this, 'hookGetPreferences' )
+                       )
+               ) );
        }
 
        public function hookGetPreferences( $user, &$preferences ) {
index bba22c7..200027d 100644 (file)
@@ -7,32 +7,21 @@
  * @covers ApiQuery
  */
 class ApiQueryTest extends ApiTestCase {
-       /**
-        * @var array Storage for $wgHooks
-        */
-       protected $hooks;
-
        protected function setUp() {
-               global $wgHooks;
-
                parent::setUp();
                $this->doLogin();
 
-               // Setup en: as interwiki prefix
-               $this->hooks = $wgHooks;
-               $wgHooks['InterwikiLoadPrefix'][] = function ( $prefix, &$data ) {
-                       if ( $prefix == 'apiquerytestiw' ) {
-                               $data = array( 'iw_url' => 'wikipedia' );
-                       }
-                       return false;
-               };
-       }
-
-       protected function tearDown() {
-               global $wgHooks;
-               $wgHooks = $this->hooks;
-
-               parent::tearDown();
+               // Setup apiquerytestiw: as interwiki prefix
+               $this->setMwGlobals( 'wgHooks', array(
+                       'InterwikiLoadPrefix' => array(
+                               function ( $prefix, &$data ) {
+                                       if ( $prefix == 'apiquerytestiw' ) {
+                                               $data = array( 'iw_url' => 'wikipedia' );
+                                       }
+                                       return false;
+                               }
+                       )
+               ) );
        }
 
        public function testTitlesGetNormalized() {
index fc06a50..35ff919 100644 (file)
@@ -60,21 +60,23 @@ class LocalisationCacheTest extends MediaWikiTestCase {
        }
 
        public function testRecacheFallbacksWithHooks() {
-               global $wgHooks;
-
                // Use hook to provide updates for messages. This is what the
                // LocalisationUpdate extension does. See bug 68781.
-               $wgHooks['LocalisationCacheRecacheFallback'][] = function (
-                       LocalisationCache $lc,
-                       $code,
-                       array &$cache
-               ) {
-                       if ( $code === 'ru' ) {
-                               $cache['messages']['present-uk'] = 'ru-override';
-                               $cache['messages']['present-ru'] = 'ru-override';
-                               $cache['messages']['present-en'] = 'ru-override';
-                       }
-               };
+               $this->mergeMwGlobalArrayValue( 'wgHooks', array(
+                       'LocalisationCacheRecacheFallback' => array(
+                               function (
+                                       LocalisationCache $lc,
+                                       $code,
+                                       array &$cache
+                               ) {
+                                       if ( $code === 'ru' ) {
+                                               $cache['messages']['present-uk'] = 'ru-override';
+                                               $cache['messages']['present-ru'] = 'ru-override';
+                                               $cache['messages']['present-en'] = 'ru-override';
+                                       }
+                               }
+                       )
+               ) );
 
                $lc = new LocalisationCache( array( 'store' => 'detect' ) );
                $lc->recache( 'uk' );
index 2f81109..dd61f85 100644 (file)
@@ -7,11 +7,8 @@
  */
 class TextContentTest extends MediaWikiLangTestCase {
        protected $context;
-       protected $savedContentGetParserOutput;
 
        protected function setUp() {
-               global $wgHooks;
-
                parent::setUp();
 
                // Anon user
@@ -32,24 +29,8 @@ class TextContentTest extends MediaWikiLangTestCase {
                        'wgUseTidy' => false,
                        'wgAlwaysUseTidy' => false,
                        'wgCapitalLinks' => true,
+                       'wgHooks' => array(), // bypass hook ContentGetParserOutput that force custom rendering
                ) );
-
-               // bypass hooks that force custom rendering
-               if ( isset( $wgHooks['ContentGetParserOutput'] )  ) {
-                       $this->savedContentGetParserOutput = $wgHooks['ContentGetParserOutput'];
-                       unset( $wgHooks['ContentGetParserOutput'] );
-               }
-       }
-
-       public function teardown() {
-               global $wgHooks;
-
-               // restore hooks that force custom rendering
-               if ( $this->savedContentGetParserOutput !== null ) {
-                       $wgHooks['ContentGetParserOutput'] = $this->savedContentGetParserOutput;
-               }
-
-               parent::teardown();
        }
 
        public function newContent( $text ) {
index 2bdc9c9..2142061 100644 (file)
@@ -2,27 +2,22 @@
 
 class AutoLoaderTest extends MediaWikiTestCase {
        protected function setUp() {
-               global $wgAutoloadLocalClasses, $wgAutoloadClasses;
-
                parent::setUp();
 
                // Fancy dance to trigger a rebuild of AutoLoader::$autoloadLocalClassesLower
-               $this->testLocalClasses = array(
-                       'TestAutoloadedLocalClass' => __DIR__ . '/../data/autoloader/TestAutoloadedLocalClass.php',
-                       'TestAutoloadedCamlClass' => __DIR__ . '/../data/autoloader/TestAutoloadedCamlClass.php',
+               $this->mergeMwGlobalArrayValue( 'wgAutoloadLocalClasses', array(
+                       'TestAutoloadedLocalClass' =>
+                               __DIR__ . '/../data/autoloader/TestAutoloadedLocalClass.php',
+                       'TestAutoloadedCamlClass' =>
+                               __DIR__ . '/../data/autoloader/TestAutoloadedCamlClass.php',
                        'TestAutoloadedSerializedClass' =>
                                __DIR__ . '/../data/autoloader/TestAutoloadedSerializedClass.php',
-               );
-               $this->setMwGlobals(
-                       'wgAutoloadLocalClasses',
-                       $this->testLocalClasses + $wgAutoloadLocalClasses
-               );
+               ) );
                AutoLoader::resetAutoloadLocalClassesLower();
 
-               $this->testExtensionClasses = array(
+               $this->mergeMwGlobalArrayValue( 'wgAutoloadClasses', array(
                        'TestAutoloadedClass' => __DIR__ . '/../data/autoloader/TestAutoloadedClass.php',
-               );
-               $this->setMwGlobals( 'wgAutoloadClasses', $this->testExtensionClasses + $wgAutoloadClasses );
+               ) );
        }
 
        /**