From: jenkins-bot Date: Wed, 24 Jun 2015 13:03:58 +0000 (+0000) Subject: Merge "Add language Doteli (dty)" X-Git-Tag: 1.31.0-rc.0~10995 X-Git-Url: http://git.cyclocoop.org/%40spipnet%40?a=commitdiff_plain;h=d24b74ce2db24799dbaa2abe0277a48694ad2ebd;hp=d7d4a3b1edce621f71c1073e9d6aaf548e042bd8;p=lhc%2Fweb%2Fwiklou.git Merge "Add language Doteli (dty)" --- diff --git a/.gitattributes b/.gitattributes index 50ca329f24..69d7b1baab 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1 +1,2 @@ *.sh eol=lf +*.icc binary diff --git a/.jshintignore b/.jshintignore index 494890c00e..1882151c45 100644 --- a/.jshintignore +++ b/.jshintignore @@ -9,6 +9,3 @@ resources/src/jquery.tipsy/** resources/src/jquery/jquery.farbtastic.js resources/src/mediawiki.libs/** tests/frontend/node_modules/** - -# github.com/jshint/jshint/issues/729 -tests/qunit/suites/resources/mediawiki/mediawiki.jscompat.test.js diff --git a/.jshintrc b/.jshintrc index 4bb244030c..d72c31d66f 100644 --- a/.jshintrc +++ b/.jshintrc @@ -21,6 +21,7 @@ "globals": { "mediaWiki": true, "JSON": true, + "OO": true, "jQuery": false, "QUnit": false, "sinon": false diff --git a/.mailmap b/.mailmap index a1f0054213..12ff31db3a 100644 --- a/.mailmap +++ b/.mailmap @@ -22,6 +22,7 @@ ayush_garg Bahodir Mansurov Bartosz Dziewoński Bartosz Dziewoński +Bartosz Dziewoński Bene Brad Jorsch Brian Wolff diff --git a/CREDITS b/CREDITS index 772503455b..22dee7bdad 100644 --- a/CREDITS +++ b/CREDITS @@ -240,6 +240,7 @@ following names for their contribution to the product. * Van de Bugger * Ville Stadista * Vitaliy Filippov +* Vivek Ghaisas * Waldir Pimenta * William Demchick * Yusuke Matsubara diff --git a/Gemfile b/Gemfile index 6f9c0539e0..392558ce8f 100644 --- a/Gemfile +++ b/Gemfile @@ -3,5 +3,5 @@ source 'https://rubygems.org' -gem 'mediawiki_selenium', '~> 1.0.1' +gem 'mediawiki_selenium', '~> 1.2.1' gem 'rubocop', require: false diff --git a/Gemfile.lock b/Gemfile.lock index 0b360aedbe..7aa9daeb76 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -5,7 +5,7 @@ GEM astrolabe (1.3.0) parser (>= 2.2.0.pre.3, < 3.0) builder (3.2.2) - childprocess (0.5.5) + childprocess (0.5.6) ffi (~> 1.0, >= 1.0.11) cucumber (1.3.19) builder (>= 2.1.2) @@ -13,11 +13,11 @@ GEM gherkin (~> 2.12) multi_json (>= 1.7.5, < 2.0) multi_test (>= 0.1.2) - data_magic (0.20) + data_magic (0.21) faker (>= 1.1.2) yml_reader (>= 0.4) diff-lcs (1.2.5) - domain_name (0.5.23) + domain_name (0.5.24) unf (>= 0.0.5, < 1.0.0) faker (1.4.3) i18n (~> 0.5) @@ -26,18 +26,18 @@ GEM faraday-cookie_jar (0.0.6) faraday (>= 0.7.4) http-cookie (~> 1.0.0) - ffi (1.9.6) + ffi (1.9.8) gherkin (2.12.2) multi_json (~> 1.3) headless (1.0.2) http-cookie (1.0.2) domain_name (~> 0.5) i18n (0.7.0) - json (1.8.2) + json (1.8.3) mediawiki_api (0.3.1) faraday (~> 0.9, >= 0.9.0) faraday-cookie_jar (~> 0.0, >= 0.0.6) - mediawiki_selenium (1.0.1) + mediawiki_selenium (1.2.1) cucumber (~> 1.3, >= 1.3.10) headless (~> 1.0, >= 1.0.1) json (~> 1.8, >= 1.8.1) @@ -47,33 +47,34 @@ GEM rspec-expectations (~> 2.14, >= 2.14.4) syntax (~> 1.2, >= 1.2.0) thor (~> 0.19, >= 0.19.1) - mime-types (2.4.3) + mime-types (2.6.1) multi_json (1.11.0) multi_test (0.1.2) multipart-post (2.0.0) netrc (0.10.3) - page-object (1.0.3) + page-object (1.1.0) page_navigation (>= 0.9) selenium-webdriver (>= 2.44.0) watir-webdriver (>= 0.6.11) page_navigation (0.9) data_magic (>= 0.14) - parser (2.2.0.3) + parser (2.2.2.5) ast (>= 1.1, < 3.0) - powerpack (0.1.0) + powerpack (0.1.1) rainbow (2.0.0) - rest-client (1.7.3) + rest-client (1.8.0) + http-cookie (>= 1.0.2, < 2.0) mime-types (>= 1.16, < 3.0) netrc (~> 0.7) rspec-expectations (2.99.2) diff-lcs (>= 1.1.3, < 2.0) - rubocop (0.29.1) + rubocop (0.31.0) astrolabe (~> 1.3) - parser (>= 2.2.0.1, < 3.0) + parser (>= 2.2.2.1, < 3.0) powerpack (~> 0.1) rainbow (>= 1.99.1, < 3.0) ruby-progressbar (~> 1.4) - ruby-progressbar (1.7.1) + ruby-progressbar (1.7.5) rubyzip (1.1.7) selenium-webdriver (2.45.0) childprocess (~> 0.5) @@ -84,15 +85,15 @@ GEM thor (0.19.1) unf (0.1.4) unf_ext - unf_ext (0.0.6) + unf_ext (0.0.7.1) watir-webdriver (0.7.0) selenium-webdriver (>= 2.45) - websocket (1.2.1) + websocket (1.2.2) yml_reader (0.5) PLATFORMS ruby DEPENDENCIES - mediawiki_selenium (~> 1.0.1) + mediawiki_selenium (~> 1.2.1) rubocop diff --git a/RELEASE-NOTES-1.26 b/RELEASE-NOTES-1.26 index ad61110430..c2228ae81d 100644 --- a/RELEASE-NOTES-1.26 +++ b/RELEASE-NOTES-1.26 @@ -9,25 +9,55 @@ MediaWiki 1.26 is an alpha-quality branch and is not recommended for use in production. === Configuration changes in 1.26 === +* $wgEnableParserCache was deprecated, set $wgParserCacheType to CACHE_NONE + instead if you want to disable the parser cache. +* New-style continuation is now the default for API action=continue. Clients may + use the 'rawcontinue' parameter to receive raw query-continue data, but the + new style is encouraged as it's harder to implement incorrectly. === New features in 1.26 === * Change tags can now be hidden in the interface by disabling the associated "tag-" interface message. * ':' (colon) is now invalid in usernames for new accounts. Existing accounts are not affected. +* Added a new hook, 'LogException', to log exceptions in nonstandard ways. +* Revive the 'SpecialSearchResultsAppend' hook which occurs after the list of + search results are rendered. The initial use case is to append a "give us + feedback" link beneath the search results. +* Added a new hook, 'RejectParserCacheValue', which allows extensions to + reject an otherwise-successful parser cache lookup. The intent is to allow + extensions to manage the eviction of archaic HTML output from the cache. +* (T68699) The expiration of the UserID and Token login cookies + ($wgExtendedLoginCookieExpiration) can be configured independently of the + expiration of all other cookies ($wgCookieExpiration). ==== External libraries ==== +* Update es5-shim from v4.0.0 to v4.1.5. +* Update json2 from revision 2014-02-04 to 2015-05-03. +* Update Sinon.JS from 1.10.3 to 1.15.0. +* Upgrade jQuery Client from v1.0.0 to v2.0.0. +* Added mediawiki/at-ease 1.0.0 === Bug fixes in 1.26 === * (bug 51283) load.php sometimes sends 304 response without full headers +* (T65198) Talk page tabs now have a "rel=discussion" attribute === Action API changes in 1.26 === +* New-style continuation is now the default for action=continue. Clients may + use the 'rawcontinue' parameter to receive raw query-continue data, but the + new style is encouraged as it's harder to implement incorrectly. * API action=query&list=tags: The displayname can now be boolean false if the tag is meant to be hidden from user interfaces. * action=import no longer allows both the namespace= and rootpage= parameters to be set. If they are both set, the value of rootpage= will be ignored. * prop=revision output in enum mode is now sorted by timestamp rather than revision ID. This usually won't make any difference. +* (T102645) Namespace list from meta=siteinfo&siprop=namespaces is now an array + with formatversion=2. +* Various other output from meta=siteinfo will now always be arrays instead of + sometimes being numerically-indexed objects with formatversion=2. +* When errors about users being blocked are returned, they now include + information about the relevant block. === Action API internal changes in 1.26 === @@ -47,16 +77,41 @@ changes to languages because of Bugzilla reports. * Added PageHistoryPager::doBatchLookups hook. * Added ParserCacheSaveComplete to ParserCache * supportsDirectEditing and supportsDirectApiEditing methods added to -ContentHandler, to provide a way for ApiEditPage and EditPage to check -if direct editing of content is allowed. These methods return false, -by default for the ContentHandler base class and true for TextContentHandler -and it's derivative classes (everything in core). For Content types that -do not support direct editing, an alternative mechanism should be provided -for editing, such as action overrides or specific api modules. + ContentHandler, to provide a way for ApiEditPage and EditPage to check + if direct editing of content is allowed. These methods return false, + by default for the ContentHandler base class and true for TextContentHandler + and it's derivative classes (everything in core). For Content types that + do not support direct editing, an alternative mechanism should be provided + for editing, such as action overrides or specific api modules. * mediaWiki.confirmCloseWindow now returns an object of functions, instead of -one function. The callback can't be called directly any more. The callback function -is replaced with confirmCloseWindow.release(). + one function. The callback can't be called directly any more. The callback + function is replaced with confirmCloseWindow.release(). +* BREAKING CHANGE: Added an optional ResouceLoaderContext parameter to + ResourceLoaderModule::getDependencies(). Extension classes that override that + method should be updated. If they aren't updated, PHP Strict standards + warnings will appear when E_STRICT error reporting is enabled. Note: in the + near future, this parameter will probably become non-optional. * Removed maintenance script deleteImageMemcached.php. +* MWFunction::newObj() was removed (deprecated in 1.25). + ObjectFactory::getObjectFromSpec() should be used instead. +* The parser will no longer randomize the string it uses to mark the place of + items that were stripped during parsing. It will use a fixed string instead. + This causes the parser to re-use the regular expressions it uses to search + and replace markers rather than generate novel expressions on each parse. + Re-using regular expressions will improve performance on HHVM and the + forthcoming PHP 7. The interfaces changes accompanying this change are: + - Parser::getRandomString() and Parser::uniqPrefix() have been deprecated. + - The $uniq_prefix argument for Parser::extractTagsAndParams() and the + $prefix argument for StripState::_construct() are deprecated and their + value is ignored. +* wfSuppressWarnings() and wfRestoreWarnings() were split into a separate library, + mediawiki/at-ease, and are now deprecated. Callers should use + MediaWiki\suppressWarnings() and MediaWiki\restoreWarnings() directly. +* The Block class constructor now takes an associative array of parameters + instead of many optional positional arguments. Calling the constructor the old + way will issue a deprecation warning. +* The jquery.mwExtension module was deprecated. + == Compatibility == @@ -123,3 +178,4 @@ going to run a public MediaWiki, so you can be notified of security fixes. == IRC help == There's usually someone online in #mediawiki on irc.freenode.net. + diff --git a/api.php b/api.php index a9e56830f3..af7c452550 100644 --- a/api.php +++ b/api.php @@ -88,20 +88,9 @@ if ( $processor ) { $processor->execute(); } -if ( function_exists( 'fastcgi_finish_request' ) ) { - fastcgi_finish_request(); -} - -JobQueueGroup::pushLazyJobs(); - -// Execute any deferred updates -DeferredUpdates::doUpdates(); - // Log what the user did, for book-keeping purposes. $endtime = microtime( true ); -wfLogProfilingData(); - // Log the request if ( $wgAPIRequestLog ) { $items = array( @@ -130,7 +119,5 @@ if ( $wgAPIRequestLog ) { wfDebug( "Logged API request to $wgAPIRequestLog\n" ); } -// Shut down the database. foo()->bar() syntax is not supported in PHP4: we won't ever actually -// get here to worry about whether this should be = or =&, but the file has to parse properly. -$lb = wfGetLBFactory(); -$lb->shutdown(); +$mediawiki = new MediaWiki(); +$mediawiki->doPostOutputShutdown( 'fast' ); diff --git a/autoload.php b/autoload.php index 8749310318..504eaf22e2 100644 --- a/autoload.php +++ b/autoload.php @@ -311,9 +311,7 @@ $wgAutoloadLocalClasses = array( 'DeferredUpdates' => __DIR__ . '/includes/deferred/DeferredUpdates.php', 'DeleteAction' => __DIR__ . '/includes/actions/DeleteAction.php', 'DeleteArchivedFiles' => __DIR__ . '/maintenance/deleteArchivedFiles.php', - 'DeleteArchivedFilesImplementation' => __DIR__ . '/maintenance/deleteArchivedFiles.inc', 'DeleteArchivedRevisions' => __DIR__ . '/maintenance/deleteArchivedRevisions.php', - 'DeleteArchivedRevisionsImplementation' => __DIR__ . '/maintenance/deleteArchivedRevisions.inc', 'DeleteBatch' => __DIR__ . '/maintenance/deleteBatch.php', 'DeleteDefaultMessages' => __DIR__ . '/maintenance/deleteDefaultMessages.php', 'DeleteEqualMessages' => __DIR__ . '/maintenance/deleteEqualMessages.php', @@ -491,6 +489,7 @@ $wgAutoloadLocalClasses = array( 'HTMLFileCache' => __DIR__ . '/includes/cache/HTMLFileCache.php', 'HTMLFloatField' => __DIR__ . '/includes/htmlform/HTMLFloatField.php', 'HTMLForm' => __DIR__ . '/includes/htmlform/HTMLForm.php', + 'HTMLFormFieldWithButton' => __DIR__ . '/includes/htmlform/HTMLFormFieldWithButton.php', 'HTMLFormField' => __DIR__ . '/includes/htmlform/HTMLFormField.php', 'HTMLFormFieldCloner' => __DIR__ . '/includes/htmlform/HTMLFormFieldCloner.php', 'HTMLFormFieldRequiredOptionsException' => __DIR__ . '/includes/htmlform/HTMLFormFieldRequiredOptionsException.php', @@ -504,11 +503,13 @@ $wgAutoloadLocalClasses = array( 'HTMLSelectField' => __DIR__ . '/includes/htmlform/HTMLSelectField.php', 'HTMLSelectLimitField' => __DIR__ . '/includes/htmlform/HTMLSelectLimitField.php', 'HTMLSelectNamespace' => __DIR__ . '/includes/htmlform/HTMLSelectNamespace.php', + 'HTMLSelectNamespaceWithButton' => __DIR__ . '/includes/htmlform/HTMLSelectNamespaceWithButton.php', 'HTMLSelectOrOtherField' => __DIR__ . '/includes/htmlform/HTMLSelectOrOtherField.php', 'HTMLSubmitField' => __DIR__ . '/includes/htmlform/HTMLSubmitField.php', 'HTMLTagFilter' => __DIR__ . '/includes/htmlform/HTMLTagFilter.php', 'HTMLTextAreaField' => __DIR__ . '/includes/htmlform/HTMLTextAreaField.php', 'HTMLTextField' => __DIR__ . '/includes/htmlform/HTMLTextField.php', + 'HTMLTextFieldWithButton' => __DIR__ . '/includes/htmlform/HTMLTextFieldWithButton.php', 'HWLDFWordAccumulator' => __DIR__ . '/includes/diff/DairikiDiff.php', 'HashBagOStuff' => __DIR__ . '/includes/libs/objectcache/HashBagOStuff.php', 'HashConfig' => __DIR__ . '/includes/config/HashConfig.php', @@ -609,6 +610,7 @@ $wgAutoloadLocalClasses = array( 'LCStoreCDB' => __DIR__ . '/includes/cache/LocalisationCache.php', 'LCStoreDB' => __DIR__ . '/includes/cache/LocalisationCache.php', 'LCStoreNull' => __DIR__ . '/includes/cache/LocalisationCache.php', + 'LCStoreStaticArray' => __DIR__ . '/includes/cache/LCStoreStaticArray.php', 'LangMemUsage' => __DIR__ . '/maintenance/language/langmemusage.php', 'Language' => __DIR__ . '/languages/Language.php', 'LanguageAr' => __DIR__ . '/languages/classes/LanguageAr.php', @@ -708,7 +710,6 @@ $wgAutoloadLocalClasses = array( 'MWDocGen' => __DIR__ . '/maintenance/mwdocgen.php', 'MWException' => __DIR__ . '/includes/exception/MWException.php', 'MWExceptionHandler' => __DIR__ . '/includes/exception/MWExceptionHandler.php', - 'MWFunction' => __DIR__ . '/includes/utils/MWFunction.php', 'MWHookException' => __DIR__ . '/includes/Hooks.php', 'MWHttpRequest' => __DIR__ . '/includes/HttpFunctions.php', 'MWMemcached' => __DIR__ . '/includes/objectcache/MemcachedClient.php', @@ -814,6 +815,7 @@ $wgAutoloadLocalClasses = array( 'NullJob' => __DIR__ . '/includes/jobqueue/jobs/NullJob.php', 'NullLockManager' => __DIR__ . '/includes/filebackend/lockmanager/LockManager.php', 'NullRepo' => __DIR__ . '/includes/filerepo/NullRepo.php', + 'OOUIHTMLForm' => __DIR__ . '/includes/htmlform/OOUIHTMLForm.php', 'ORAField' => __DIR__ . '/includes/db/DatabaseOracle.php', 'ORAResult' => __DIR__ . '/includes/db/DatabaseOracle.php', 'ORMIterator' => __DIR__ . '/includes/db/ORMIterator.php', @@ -826,7 +828,6 @@ $wgAutoloadLocalClasses = array( 'ObjectFileCache' => __DIR__ . '/includes/cache/ObjectFileCache.php', 'OldChangesList' => __DIR__ . '/includes/changes/OldChangesList.php', 'OldLocalFile' => __DIR__ . '/includes/filerepo/file/OldLocalFile.php', - 'OOUIHTMLForm' => __DIR__ . '/includes/htmlform/OOUIHTMLForm.php', 'OracleInstaller' => __DIR__ . '/includes/installer/OracleInstaller.php', 'OracleUpdater' => __DIR__ . '/includes/installer/OracleUpdater.php', 'OrphanStats' => __DIR__ . '/maintenance/storage/orphanStats.php', @@ -877,6 +878,7 @@ $wgAutoloadLocalClasses = array( 'Password' => __DIR__ . '/includes/password/Password.php', 'PasswordError' => __DIR__ . '/includes/password/PasswordError.php', 'PasswordFactory' => __DIR__ . '/includes/password/PasswordFactory.php', + 'PasswordPolicyChecks' => __DIR__ . '/includes/password/PasswordPolicyChecks.php', 'PatchSql' => __DIR__ . '/maintenance/patchSql.php', 'PathRouter' => __DIR__ . '/includes/PathRouter.php', 'PathRouterPatternReplacer' => __DIR__ . '/includes/PathRouter.php', @@ -996,10 +998,11 @@ $wgAutoloadLocalClasses = array( 'ResourceLoaderFilePath' => __DIR__ . '/includes/resourceloader/ResourceLoaderFilePath.php', 'ResourceLoaderImage' => __DIR__ . '/includes/resourceloader/ResourceLoaderImage.php', 'ResourceLoaderImageModule' => __DIR__ . '/includes/resourceloader/ResourceLoaderImageModule.php', - 'ResourceLoaderJqueryMsgDataModule' => __DIR__ . '/includes/resourceloader/ResourceLoaderJqueryMsgDataModule.php', + 'ResourceLoaderJqueryMsgModule' => __DIR__ . '/includes/resourceloader/ResourceLoaderJqueryMsgModule.php', 'ResourceLoaderLanguageDataModule' => __DIR__ . '/includes/resourceloader/ResourceLoaderLanguageDataModule.php', 'ResourceLoaderLanguageNamesModule' => __DIR__ . '/includes/resourceloader/ResourceLoaderLanguageNamesModule.php', 'ResourceLoaderModule' => __DIR__ . '/includes/resourceloader/ResourceLoaderModule.php', + 'ResourceLoaderOOUIImageModule' => __DIR__ . '/includes/resourceloader/ResourceLoaderOOUIImageModule.php', 'ResourceLoaderRawFileModule' => __DIR__ . '/includes/resourceloader/ResourceLoaderRawFileModule.php', 'ResourceLoaderSiteModule' => __DIR__ . '/includes/resourceloader/ResourceLoaderSiteModule.php', 'ResourceLoaderSkinModule' => __DIR__ . '/includes/resourceloader/ResourceLoaderSkinModule.php', @@ -1297,6 +1300,7 @@ $wgAutoloadLocalClasses = array( 'UserMailer' => __DIR__ . '/includes/mail/UserMailer.php', 'UserNotLoggedIn' => __DIR__ . '/includes/exception/UserNotLoggedIn.php', 'UserOptions' => __DIR__ . '/maintenance/userOptions.inc', + 'UserPasswordPolicy' => __DIR__ . '/includes/password/UserPasswordPolicy.php', 'UserRightsProxy' => __DIR__ . '/includes/UserRightsProxy.php', 'UsercreateTemplate' => __DIR__ . '/includes/templates/Usercreate.php', 'UserloginTemplate' => __DIR__ . '/includes/templates/Userlogin.php', @@ -1367,7 +1371,7 @@ $wgAutoloadLocalClasses = array( 'Xml' => __DIR__ . '/includes/Xml.php', 'XmlDumpWriter' => __DIR__ . '/includes/Export.php', 'XmlJsCode' => __DIR__ . '/includes/Xml.php', - 'XmlSelect' => __DIR__ . '/includes/Xml.php', + 'XmlSelect' => __DIR__ . '/includes/XmlSelect.php', 'XmlTypeCheck' => __DIR__ . '/includes/libs/XmlTypeCheck.php', 'ZhConverter' => __DIR__ . '/languages/classes/LanguageZh.php', 'ZipDirectoryReader' => __DIR__ . '/includes/utils/ZipDirectoryReader.php', diff --git a/composer.json b/composer.json index 2f6cc42467..7419eb5b38 100644 --- a/composer.json +++ b/composer.json @@ -20,20 +20,21 @@ "ext-iconv": "*", "leafo/lessphp": "0.5.0", "liuggio/statsd-php-client": "1.0.12", - "oojs/oojs-ui": "0.11.3", + "mediawiki/at-ease": "1.0.0", + "oojs/oojs-ui": "0.11.6", "php": ">=5.3.3", "psr/log": "1.0.0", "wikimedia/cdb": "1.0.1", "wikimedia/assert": "0.2.2", - "wikimedia/composer-merge-plugin": "1.0.0", + "wikimedia/composer-merge-plugin": "1.1.0", "wikimedia/utfnormal": "1.0.2", "zordius/lightncandy": "0.21" }, "require-dev": { "jakub-onderka/php-parallel-lint": "~0.8", "justinrainbow/json-schema": "~1.3", - "phpunit/phpunit": "~4.5", - "mediawiki/mediawiki-codesniffer": "0.1.0" + "phpunit/phpunit": "3.7.37", + "mediawiki/mediawiki-codesniffer": "0.2.0" }, "suggest": { "ext-fileinfo": "*", @@ -50,7 +51,7 @@ }, "scripts": { "lint": "parallel-lint --exclude vendor", - "phpcs": "phpcs $PHPCS_ARGS -s --standard=vendor/mediawiki/mediawiki-codesniffer/MediaWiki --ignore=vendor --encoding=utf-8 --extensions=php,php5,inc,sample", + "phpcs": "phpcs $PHPCS_ARGS -s --standard=vendor/mediawiki/mediawiki-codesniffer/MediaWiki --ignore=vendor,node_modules --encoding=utf-8 --extensions=php,php5,inc,sample", "test": [ "composer lint", "composer phpcs" @@ -59,6 +60,7 @@ "pre-install-cmd": "ComposerHookHandler::onPreInstall" }, "config": { + "classmap-authoritative": true, "prepend-autoloader": false, "optimize-autoloader": true }, diff --git a/docs/doxygen_first_page.php b/docs/doxygen_first_page.php index 9949d13366..77ae1dcf36 100644 --- a/docs/doxygen_first_page.php +++ b/docs/doxygen_first_page.php @@ -1,5 +1,5 @@ tag if $resultArr was filled. -$editPage : the EditPage object -$text : the new text of the article (has yet to be saved) -&$resultArr : data in this array will be added to the API result +$editPage: the EditPage object +$text: the new text of the article (has yet to be saved) +&$resultArr: data in this array will be added to the API result 'ApiFeedContributions::feedItem': Called to convert the result of ContribsPager into a FeedItem instance that ApiFeedContributions can consume. Implementors of this hook may cancel the hook to signal that the item is not viewable in the provided context. -$row: A row of data from ContribsPager. The set of data returned by ContribsPager - can be adjusted by handling the ContribsPager::reallyDoQuery hook. +$row: A row of data from ContribsPager. The set of data returned by + ContribsPager can be adjusted by handling the ContribsPager::reallyDoQuery + hook. $context: An IContextSource implementation. -&$feedItem: Set this to a FeedItem instance if the callback can handle the provided - row. This is provided to the hook as a null, if it is non null then another callback - has already handled the hook. +&$feedItem: Set this to a FeedItem instance if the callback can handle the + provided row. This is provided to the hook as a null, if it is non null then + another callback has already handled the hook. 'ApiFormatHighlight': Use to syntax-highlight API pretty-printed output. When highlighting, add output to $context->getOutput() and return false. @@ -407,12 +407,14 @@ Use this hook to modify a module's description. $module: ApiBase Module object &$msg: Array of Message objects -'APIGetParamDescription': DEPRECATED! Use APIGetParamDescriptionMessages instead. +'APIGetParamDescription': DEPRECATED! Use APIGetParamDescriptionMessages +instead. Use this hook to modify a module's parameter descriptions. &$module: ApiBase Module object &$desc: Array of parameter descriptions -'APIGetParamDescriptionMessages': Use this hook to modify a module's parameter descriptions. +'APIGetParamDescriptionMessages': Use this hook to modify a module's parameter +descriptions. $module: ApiBase Module object &$msg: Array of arrays of Message objects @@ -421,24 +423,29 @@ $module: ApiBase Module object &$help: Array of HTML strings to be joined for the output. $options: Array Options passed to ApiHelp::getHelp &$tocData: Array If a TOC is being generated, this array has keys as anchors in -the page and values as for Linker::generateTOC(). + the page and values as for Linker::generateTOC(). 'ApiMain::moduleManager': Called when ApiMain has finished initializing its module manager. Can be used to conditionally register API modules. $moduleManager: ApiModuleManager Module manager instance +'ApiMain::onException': Called by ApiMain::executeActionWithErrorHandling() when +an exception is thrown during API action execution. +$apiMain: Calling ApiMain instance. +$e: Exception object. + 'ApiOpenSearchSuggest': Called when constructing the OpenSearch results. Hooks can alter or append to the array. &$results: array with integer keys to associative arrays. Keys in associative -array: - - title: Title object. - - redirect from: Title or null. - - extract: Description for this result. - - extract trimmed: If truthy, the extract will not be trimmed to - $wgOpenSearchDescriptionLength. - - image: Thumbnail for this result. Value is an array with subkeys 'source' - (url), 'width', 'height', 'alt', 'align'. - - url: Url for the given title. + array: + - title: Title object. + - redirect from: Title or null. + - extract: Description for this result. + - extract trimmed: If truthy, the extract will not be trimmed to + $wgOpenSearchDescriptionLength. + - image: Thumbnail for this result. Value is an array with subkeys 'source' + (url), 'width', 'height', 'alt', 'align'. + - url: Url for the given title. 'ApiQuery::moduleManager': Called when ApiQuery has finished initializing its module manager. Can be used to conditionally register API query modules. @@ -464,6 +471,19 @@ just add your callback to the $tokenFunctions array and return true (returning false makes no sense). $tokenFunctions: array(action => callback) +'APIQueryRecentChangesTokens': DEPRECATED! Use ApiQueryTokensRegisterTypes +instead. +Use this hook to add custom tokens to list=recentchanges. Every token has an +action, which will be used in the rctoken parameter and in the output +(actiontoken="..."), and a callback function which should return the token, or +false if the user isn't allowed to obtain it. The prototype of the callback +function is func($pageid, $title, $rc), where $pageid is the page ID of the +page associated to the revision the token is requested for, $title the +associated Title object and $rc the associated RecentChange object. In the +hook, just add your callback to the $tokenFunctions array and return true +(returning false makes no sense). +$tokenFunctions: array(action => callback) + 'APIQueryRevisionsTokens': DEPRECATED! Use ApiQueryTokensRegisterTypes instead. Use this hook to add custom tokens to prop=revisions. Every token has an action, which will be used in the rvtoken parameter and in the output @@ -476,18 +496,6 @@ just add your callback to the $tokenFunctions array and return true (returning false makes no sense). $tokenFunctions: array(action => callback) -'APIQueryRecentChangesTokens': DEPRECATED! Use ApiQueryTokensRegisterTypes instead. -Use this hook to add custom tokens to list=recentchanges. Every token has an -action, which will be used in the rctoken parameter and in the output -(actiontoken="..."), and a callback function which should return the token, or -false if the user isn't allowed to obtain it. The prototype of the callback -function is func($pageid, $title, $rc), where $pageid is the page ID of the -page associated to the revision the token is requested for, $title the -associated Title object and $rc the associated RecentChange object. In the -hook, just add your callback to the $tokenFunctions array and return true -(returning false makes no sense). -$tokenFunctions: array(action => callback) - 'APIQuerySiteInfoGeneralInfo': Use this hook to add extra information to the sites general information. $module: the current ApiQuerySiteInfo module @@ -512,11 +520,6 @@ your callback to the $tokenFunctions array and return true (returning false makes no sense). $tokenFunctions: array(action => callback) -'ApiMain::onException': Called by ApiMain::executeActionWithErrorHandling() when -an exception is thrown during API action execution. -$apiMain: Calling ApiMain instance. -$e: Exception object. - 'ApiRsdServiceApis': Add or remove APIs from the RSD services list. Each service should have its own entry in the $apis array and have a unique name, passed as key for the array that represents the service data. In this data array, the @@ -526,17 +529,18 @@ key-value-pair identified by the apiLink key is required. 'ApiTokensGetTokenTypes': DEPRECATED! Use ApiQueryTokensRegisterTypes instead. Use this hook to extend action=tokens with new token types. &$tokenTypes: supported token types in format 'type' => callback function -used to retrieve this type of tokens. + used to retrieve this type of tokens. 'Article::MissingArticleConditions': Before fetching deletion & move log entries to display a message of a non-existing page being deleted/moved, give extensions a chance to hide their (unrelated) log entries. &$conds: Array of query conditions (all of which have to be met; conditions will -AND in the final query) + AND in the final query) $logTypes: Array of log types being queried -'ArticleAfterFetchContent': After fetching content of an article from the -database. DEPRECATED, use ArticleAfterFetchContentObject instead. +'ArticleAfterFetchContent': DEPRECATED! Use ArticleAfterFetchContentObject +instead. +After fetching content of an article from the database. $article: the article (object) being loaded from the database &$content: the content (string) of the article @@ -556,6 +560,13 @@ this to change the content in this area or how it is loaded. $diffEngine: the DifferenceEngine $output: the OutputPage object +'ArticleContentViewCustom': Allows to output the text of the article in a +different format than wikitext. Note that it is preferable to implement proper +handing for a custom data type using the ContentHandler facility. +$content: content of the page, as a Content object +$title: title of the page +$output: reference to $wgOut + 'ArticleDelete': Before an article is deleted. $wikiPage: the WikiPage (object) being deleted $user: the user (object) deleting the article @@ -586,7 +597,7 @@ $recipient: User (object) who's talk page was edited article has been changed. $wikiPage: the WikiPage (object) $editInfo: data holder that includes the parser output ($editInfo->output) for -that page after the change + that page after the change $changed: bool for if the page was changed 'ArticleEditUpdatesDeleteFromRecentchanges': Before deleting old entries from @@ -599,8 +610,8 @@ $title: Title (object) used to create the article object $article: Article (object) that will be returned $context: IContextSource (object) -'ArticleInsertComplete': After a new article is created. DEPRECATED, use -PageContentInsertComplete. +'ArticleInsertComplete': DEPRECATED! Use PageContentInsertComplete. +After a new article is created. $wikiPage: WikiPage created $user: User creating the article $text: New content @@ -644,23 +655,23 @@ $moveonly: boolean whether it was for move only or not 'ArticlePurge': Before executing "&action=purge". $wikiPage: WikiPage (object) to purge -'ArticleRevisionVisibilitySet': Called when changing visibility of one or more -revisions of an article. -&$title: Title object of the article - 'ArticleRevisionUndeleted': After an article revision is restored. $title: the article title $revision: the revision $oldPageID: the page ID of the revision when archived (may be null) +'ArticleRevisionVisibilitySet': Called when changing visibility of one or more +revisions of an article. +&$title: Title object of the article + 'ArticleRollbackComplete': After an article rollback is completed. $wikiPage: the WikiPage that was edited $user: the user who did the rollback $revision: the revision the page was reverted back to $current: the reverted revision -'ArticleSave': Before an article is saved. DEPRECATED, use PageContentSave -instead. +'ArticleSave': DEPRECATED! Use PageContentSave instead. +Before an article is saved. $wikiPage: the WikiPage (object) being saved $user: the user (object) saving the article $text: the new article text @@ -669,8 +680,8 @@ $isminor: minor flag $iswatch: watch flag $section: section # -'ArticleSaveComplete': After an article has been updated. DEPRECATED, use -PageContentSaveComplete instead. +'ArticleSaveComplete': DEPRECATED! Use PageContentSaveComplete instead. +After an article has been updated. $wikiPage: WikiPage modified $user: User performing the modification $text: New content @@ -701,6 +712,14 @@ the user is redirected back to the page. &$sectionanchor: The section anchor link (e.g. "#overview" ) &$extraq: Extra query parameters which can be added via hooked functions +'ArticleViewCustom': DEPRECATED! Use ArticleContentViewCustom instead. +Allows to output the text of the article in a different format than wikitext. +Note that it is preferable to implement proper handing for a custom data type +using the ContentHandler facility. +$text: text of the page +$title: title of the page +$output: reference to $wgOut + 'ArticleViewFooter': After showing the footer section of an ordinary page view $article: Article object $patrolFooterShown: boolean whether patrol footer is shown @@ -709,28 +728,14 @@ $patrolFooterShown: boolean whether patrol footer is shown viewing. &$article: the article &$pcache: whether to try the parser cache or not -&$outputDone: whether the output for this page finished or not. Set to a ParserOutput -object to both indicate that the output is done and what parser output was used. +&$outputDone: whether the output for this page finished or not. Set to + a ParserOutput object to both indicate that the output is done and what + parser output was used. 'ArticleViewRedirect': Before setting "Redirected from ..." subtitle when a redirect was followed. $article: target article (object) -'ArticleViewCustom': Allows to output the text of the article in a different -format than wikitext. DEPRECATED, use ArticleContentViewCustom instead. Note -that it is preferable to implement proper handing for a custom data type using -the ContentHandler facility. -$text: text of the page -$title: title of the page -$output: reference to $wgOut - -'ArticleContentViewCustom': Allows to output the text of the article in a -different format than wikitext. Note that it is preferable to implement proper -handing for a custom data type using the ContentHandler facility. -$content: content of the page, as a Content object -$title: title of the page -$output: reference to $wgOut - 'AuthPluginAutoCreate': Called when creating a local account for an user logged in from an external authentication method. $user: User object created locally @@ -745,16 +750,16 @@ $args: arguments $user: user $result: result of checking autopromote condition -'BacklinkCacheGetPrefix': Allows to set prefix for a specific link table. -$table: table name -&$prefix: prefix - 'BacklinkCacheGetConditions': Allows to set conditions for query when links to certain title are fetched. $table: table name $title: title of the page to which backlinks are sought &$conds: query conditions +'BacklinkCacheGetPrefix': Allows to set prefix for a specific link table. +$table: table name +&$prefix: prefix + 'BadImage': When checking against the bad image list. Change $bad and return false to override. If an image is "bad", it is not rendered inline in wiki pages or galleries in category pages. @@ -767,10 +772,27 @@ $template BaseTemplate $portlet: string portlet name &$html: string +'BaseTemplateToolbox': Called by BaseTemplate when building the $toolbox array +and returning it for the skin to output. You can add items to the toolbox while +still letting the skin make final decisions on skin-specific markup conventions +using this hook. +&$sk: The BaseTemplate base skin template +&$toolbox: An array of toolbox items, see BaseTemplate::getToolbox and + BaseTemplate::makeListItem for details on the format of individual items + inside of this array. + 'BeforeDisplayNoArticleText': Before displaying message key "noarticletext" or "noarticletext-nopermission" at Article::showMissingArticle(). $article: article object +'BeforeHttpsRedirect': Prior to forcing HTTP->HTTPS redirect. Gives a chance to +override how the redirect is output by modifying, or by returning false, and +letting standard HTTP rendering take place. +ATTENTION: This hook is likely to be removed soon due to overall design of the +system. +$context: IContextSource object +&$redirect: string URL, modifiable + 'BeforeInitialize': Before anything is initialized in MediaWiki::performRequest(). &$title: Title being used for request @@ -784,13 +806,6 @@ $mediaWiki: Mediawiki object &$out: OutputPage object &$skin: Skin object -'BeforeHttpsRedirect': Prior to forcing HTTP->HTTPS redirect. Gives a chance to -override how the redirect is output by modifying, or by returning false, and -letting standard HTTP rendering take place. -ATTENTION: This hook is likely to be removed soon due to overall design of the system. -$context: IContextSource object -&$redirect: string URL, modifiable - 'BeforePageRedirect': Prior to sending an HTTP redirect. Gives a chance to override how the redirect is output by modifying, or by returning false and taking over the output. @@ -822,13 +837,6 @@ newly created user. &$injected_html: Any HTML to inject after the "logged in" message of a newly created user account -'BitmapHandlerTransform': before a file is transformed, gives extension the -possibility to transform it themselves -$handler: BitmapHandler -$image: File -&$scalerParams: Array with scaler parameters -&$mto: null, set to a MediaTransformOutput - 'BitmapHandlerCheckImageArea': By BitmapHandler::normaliseParams, after all normalizations have been performed, except for the $wgMaxImageArea check. $image: File @@ -836,10 +844,12 @@ $image: File &$checkImageAreaHookResult: null, set to true or false to override the $wgMaxImageArea check result. -'PerformRetroactiveAutoblock': Called before a retroactive autoblock is applied -to a user. -$block: Block object (which is set to be autoblocking) -&$blockIds: Array of block IDs of the autoblock +'BitmapHandlerTransform': before a file is transformed, gives extension the +possibility to transform it themselves +$handler: BitmapHandler +$image: File +&$scalerParams: Array with scaler parameters +&$mto: null, set to a MediaTransformOutput 'BlockIp': Before an IP address or user is blocked. $block: the Block object about to be saved @@ -858,7 +868,7 @@ $output: OutputPage object in use to be able to access the wiki via HTTPS. $ip: The IP address in human-readable form &$canDo: This reference should be set to false if the client may not be able -to use HTTPS + to use HTTPS 'CanonicalNamespaces': For extensions adding their own namespaces or altering the defaults. @@ -895,13 +905,18 @@ $type: The category type. Either 'page', 'img' or 'subcat' $title: Title object for the categorized page $html: Requested html content of anchor &$link: Returned value. When set to a non-null value by a hook subscriber -this value will be used as the anchor instead of Linker::link + this value will be used as the anchor instead of Linker::link 'ChangePasswordForm': For extensions that need to add a field to the ChangePassword form via the Preferences form. &$extraFields: An array of arrays that hold fields like would be passed to the pretty function. +'ChangesListInitRows': Batch process change list rows prior to rendering. +$changesList: ChangesList instance +$rows: The data that will be rendered. May be a ResultWrapper instance or + an array. + 'ChangesListInsertArticleLink': Override or augment link to article in RC list. &$changesList: ChangesList instance. &$articlelink: HTML of link to article (already filled-in). @@ -910,18 +925,17 @@ ChangePassword form via the Preferences form. $unpatrolled: Whether or not we are showing unpatrolled changes. $watched: Whether or not the change is watched by the user. -'ChangesListInitRows': Batch process change list rows prior to rendering. -$changesList: ChangesList instance -$rows: The data that will be rendered. May be a ResultWrapper instance or - an array. - -'ChangesListSpecialPageFilters': Called after building form options on pages inheriting from ChangesListSpecialPage (in core: RecentChanges, RecentChangesLinked and Watchlist). +'ChangesListSpecialPageFilters': Called after building form options on pages +inheriting from ChangesListSpecialPage (in core: RecentChanges, +RecentChangesLinked and Watchlist). $special: ChangesListSpecialPage instance &$filters: associative array of filter definitions. The keys are the HTML name/URL parameters. Each key maps to an associative array with a 'msg' (message key) and a 'default' value. -'ChangesListSpecialPageQuery': Called when building SQL query on pages inheriting from ChangesListSpecialPage (in core: RecentChanges, RecentChangesLinked and Watchlist). +'ChangesListSpecialPageQuery': Called when building SQL query on pages +inheriting from ChangesListSpecialPage (in core: RecentChanges, +RecentChangesLinked and Watchlist). $name: name of the special page, e.g. 'Watchlist' &$tables: array of tables to be queried &$fields: array of columns to select @@ -962,14 +976,6 @@ $user: user initiating the action uses are in active use. &$tags: list of all active tags. Append to this array. -'LoginUserMigrated': Called during login to allow extensions the opportunity to -inform a user that their username doesn't exist for a specific reason, instead -of letting the login form give the generic error message that the account does -not exist. For example, when the account has been renamed or deleted. -$user: the User object being authenticated against. -&$msg: the message identifier for abort reason, or an array to pass a message - key and parameters. - 'Collation::factory': Called if $wgCategoryCollation is an unknown collation. $collationName: Name of the collation in question &$collationObject: Null. Replace with a subclass of the Collation class that @@ -979,24 +985,14 @@ $collationName: Name of the collation in question successfully. $user: user (object) whose email is being confirmed -'ContentHandlerDefaultModelFor': Called when the default content model is determined -for a given title. May be used to assign a different model for that title. -$title: the Title in question -&$model: the model name. Use with CONTENT_MODEL_XXX constants. - -'ContentHandlerForModelID': Called when a ContentHandler is requested for a given -content model name, but no entry for that model exists in $wgContentHandlers. -$modeName: the requested content model name -&$handler: set this to a ContentHandler object, if desired. - -'ContentModelCanBeUsedOn': Called to determine whether that content model can -be used on a given page. This is especially useful to prevent some content models -to be used in some special location. -$contentModel: ID of the content model in question -$title: the Title in question. -&$ok: Output parameter, whether it is OK to use $contentModel on $title. -Handler functions that modify $ok should generally return false to prevent further -hooks from further modifying $ok. +'ContentAlterParserOutput': Modify parser output for a given content object. +Called by Content::getParserOutput after parsing has finished. Can be used +for changes that depend on the result of the parsing but have to be done +before LinksUpdate is called (such as adding tracking categories based on +the rendered HTML). +$content: The Content to render +$title: Title of the page, as context +$parserOutput: ParserOutput to manipulate 'ContentGetParserOutput': Customize parser output for a given content object, called by AbstractContent::getParserOutput. May be used to override the normal @@ -1005,36 +1001,40 @@ $content: The Content to render $title: Title of the page, as context $revId: The revision ID, as context $options: ParserOptions for rendering. To avoid confusing the parser cache, -the output can only depend on parameters provided to this hook function, not on global state. -$generateHtml: boolean, indicating whether full HTML should be generated. If false, -generation of HTML may be skipped, but other information should still be present in the -ParserOutput object. + the output can only depend on parameters provided to this hook function, not + on global state. +$generateHtml: boolean, indicating whether full HTML should be generated. If + false, generation of HTML may be skipped, but other information should still + be present in the ParserOutput object. &$output: ParserOutput, to manipulate or replace -'ContentAlterParserOutput': Modify parser output for a given content object. -Called by Content::getParserOutput after parsing has finished. Can be used -for changes that depend on the result of the parsing but have to be done -before LinksUpdate is called (such as adding tracking categories based on -the rendered HTML). -$content: The Content to render -$title: Title of the page, as context -$parserOutput: ParserOutput to manipulate +'ContentHandlerDefaultModelFor': Called when the default content model is +determined for a given title. May be used to assign a different model for that +title. +$title: the Title in question +&$model: the model name. Use with CONTENT_MODEL_XXX constants. -'ConvertContent': Called by AbstractContent::convert when a conversion to another -content model is requested. -$content: The Content object to be converted. -$toModel: The ID of the content model to convert to. -$lossy: boolean indicating whether lossy conversion is allowed. -&$result: Output parameter, in case the handler function wants to provide a -converted Content object. Note that $result->getContentModel() must return $toModel. -Handler functions that modify $result should generally return false to further -attempts at conversion. +'ContentHandlerForModelID': Called when a ContentHandler is requested for +a given content model name, but no entry for that model exists in +$wgContentHandlers. +$modeName: the requested content model name +&$handler: set this to a ContentHandler object, if desired. + +'ContentModelCanBeUsedOn': Called to determine whether that content model can +be used on a given page. This is especially useful to prevent some content +models to be used in some special location. +$contentModel: ID of the content model in question +$title: the Title in question. +&$ok: Output parameter, whether it is OK to use $contentModel on $title. + Handler functions that modify $ok should generally return false to prevent + further hooks from further modifying $ok. 'ContribsPager::getQueryInfo': Before the contributions query is about to run &$pager: Pager object for contributions &$queryInfo: The query for the contribs Pager -'ContribsPager::reallyDoQuery': Called before really executing the query for My Contributions +'ContribsPager::reallyDoQuery': Called before really executing the query for My +Contributions &$data: an array of results of all contribs queries $pager: The ContribsPager object hooked into $offset: Index offset, inclusive @@ -1052,18 +1052,28 @@ $id: User identifier $title: User page title &$tools: Array of tool links +'ConvertContent': Called by AbstractContent::convert when a conversion to +another content model is requested. +Handler functions that modify $result should generally return false to disable +further attempts at conversion. +$content: The Content object to be converted. +$toModel: The ID of the content model to convert to. +$lossy: boolean indicating whether lossy conversion is allowed. +&$result: Output parameter, in case the handler function wants to provide a + converted Content object. Note that $result->getContentModel() must return + $toModel. + 'CustomEditor': When invoking the page editor +Return true to allow the normal editor to be used, or false if implementing +a custom editor, e.g. for a special namespace, etc. $article: Article being edited $user: User performing the edit -Return true to allow the normal editor to be used, or false -if implementing a custom editor, e.g. for a special namespace, -etc. - 'DatabaseOraclePostInit': Called after initialising an Oracle database &$db: the DatabaseOracle object -'DeletedContribsPager::reallyDoQuery': Called before really executing the query for Special:DeletedContributions +'DeletedContribsPager::reallyDoQuery': Called before really executing the query +for Special:DeletedContributions Similar to ContribsPager::reallyDoQuery &$data: an array of results of all contribs queries $pager: The DeletedContribsPager object hooked into @@ -1071,29 +1081,14 @@ $offset: Index offset, inclusive $limit: Exact query limit $descending: Query direction, false for ascending, true for descending -'DeletedContributionsLineEnding': Called before a DeletedContributions HTML line is finished. +'DeletedContributionsLineEnding': Called before a DeletedContributions HTML line +is finished. Similar to ContributionsLineEnding $page: SpecialPage object for DeletedContributions &$ret: the HTML line $row: the DB row for this line &$classes: the classes to add to the surrounding
  • -'NewDifferenceEngine': Called when a new DifferenceEngine object is made -$title: the diff page title (nullable) -&$oldId: the actual old Id to use in the diff -&$newId: the actual new Id to use in the diff (0 means current) -$old: the ?old= param value from the url -$new: the ?new= param value from the url - -'GetDifferenceEngine': Called when getting a new difference engine interface object -Return false for valid object in $differenceEngine or true for the default difference engine -$context: IContextSource context to be used for diff -$old: Revision ID to show and diff with -$new: Either a revision ID or one of the strings 'cur', 'prev' or 'next' -$refreshCache: If set, refreshes the diff cache -$unhide: If set, allow viewing deleted revs -&$differenceEngine: output parameter, difference engine object to be used for diff - 'DiffRevisionTools': Override or extend the revision tools available from the diff view, i.e. undo, etc. $newRev: Revision object of the "new" revision @@ -1110,8 +1105,8 @@ an article $article: article (object) being viewed $oldid: oldid (int) being viewed -'DoEditSectionLink': Override the HTML generated for section edit links -* Deprecated in favour of SkinEditSectionLinks hook * +'DoEditSectionLink': DEPRECATED! Use SkinEditSectionLinks instead. +Override the HTML generated for section edit links $skin: Skin object rendering the UI $title: Title object for the title being linked to (may not be the same as the page title, if the section is included from a template) @@ -1130,20 +1125,21 @@ $section: Section being edited &$error: Error message to return $summary: Edit summary for page -'EditFilterMerged': Post-section-merge edit filter. -DEPRECATED, use EditFilterMergedContent instead. +'EditFilterMerged': DEPRECATED! Use EditFilterMergedContent instead. +Post-section-merge edit filter. $editor: EditPage instance (object) $text: content of the edit box &$error: error message to return $summary: Edit summary for page 'EditFilterMergedContent': Post-section-merge edit filter. -This may be triggered by the EditPage or any other facility that modifies page content. -Use the $status object to indicate whether the edit should be allowed, and to provide -a reason for disallowing it. Return false to abort the edit, and true to continue. -Returning true if $status->isOK() returns false means "don't save but continue user -interaction", e.g. show the edit form. $status->apiHookResult can be set to an array -to be returned by api.php action=edit. This is used to deliver captchas. +This may be triggered by the EditPage or any other facility that modifies page +content. Use the $status object to indicate whether the edit should be allowed, +and to provide a reason for disallowing it. Return false to abort the edit, and +true to continue. Returning true if $status->isOK() returns false means "don't +save but continue user interaction", e.g. show the edit form. +$status->apiHookResult can be set to an array to be returned by api.php +action=edit. This is used to deliver captchas. $context: object implementing the IContextSource interface. $content: content of the edit box, as a Content object. $status: Status object to represent errors, etc. @@ -1151,15 +1147,15 @@ $summary: Edit summary for page $user: the User object representing the user whois performing the edit. $minoredit: whether the edit was marked as minor by the user. +'EditFormInitialText': Allows modifying the edit form when editing existing +pages +$editPage: EditPage object + 'EditFormPreloadText': Allows population of the edit form when creating new pages &$text: Text to preload with &$title: Title object representing the page being created -'EditFormInitialText': Allows modifying the edit form when editing existing -pages -$editPage: EditPage object - 'EditPage::attemptSave': Called before an article is saved, that is before WikiPage::doEditContent() is called $editpage_Obj: the current EditPage object @@ -1176,31 +1172,30 @@ $request: Webrequest return value is ignored (should always return true) 'EditPage::showEditForm:fields': allows injection of form field into edit form +Return value is ignored (should always return true) $editor: the EditPage instance for reference $out: an OutputPage instance to write to -return value is ignored (should always return true) 'EditPage::showEditForm:initial': before showing the edit form -$editor: EditPage instance (object) -$out: an OutputPage instance to write to - Return false to halt editing; you'll need to handle error messages, etc. yourself. Alternatively, modifying $error and returning true will cause the contents of $error to be echoed at the top of the edit form as wikitext. Return true without altering $error to allow the edit to proceed. +$editor: EditPage instance (object) +$out: an OutputPage instance to write to 'EditPage::showReadOnlyForm:initial': similar to EditPage::showEditForm:initial but for the read-only 'view source' variant of the edit form. +Return value is ignored (should always return true) $editor: EditPage instance (object) &$out: an OutputPage instance to write to -return value is ignored (should always return true) 'EditPage::showStandardInputs:options': allows injection of form fields into the editOptions area +Return value is ignored (should always be true) $editor: EditPage instance (object) $out: an OutputPage instance to write to &$tabindex: HTML tabindex of the last edit check/button -return value is ignored (should always be true) 'EditPageBeforeConflictDiff': allows modifying the EditPage object and output when there's an edit conflict. Return false to halt normal diff output; in @@ -1232,25 +1227,18 @@ $title: title of page being edited &$msg: localization message name, overridable. Default is either 'copyrightwarning' or 'copyrightwarning2'. -'EditPageGetDiffText': DEPRECATED. Use EditPageGetDiffContent instead. Allow -modifying the wikitext that will be used in "Show changes". Note that it is -preferable to implement diff handling for different data types using the -ContentHandler facility. -$editPage: EditPage object -&$newtext: wikitext that will be used as "your version" - 'EditPageGetDiffContent': Allow modifying the wikitext that will be used in "Show changes". Note that it is preferable to implement diff handling for different data types using the ContentHandler facility. $editPage: EditPage object &$newtext: wikitext that will be used as "your version" -'EditPageGetPreviewText': DEPRECATED. Use EditPageGetPreviewContent instead. -Allow modifying the wikitext that will be previewed. Note that it is preferable -to implement previews for different data types using the ContentHandler -facility. +'EditPageGetDiffText': DEPRECATED! Use EditPageGetDiffContent instead. +Allow modifying the wikitext that will be used in "Show changes". Note that it +is preferable to implement diff handling for different data types using the +ContentHandler facility. $editPage: EditPage object -&$toparse: wikitext that will be parsed +&$newtext: wikitext that will be used as "your version" 'EditPageGetPreviewContent': Allow modifying the wikitext that will be previewed. Note that it is preferable to implement previews for different data @@ -1258,7 +1246,15 @@ types using the ContentHandler facility. $editPage: EditPage object &$content: Content object to be previewed (may be replaced by hook function) -'EditPageNoSuchSection': When a section edit request is given for an non-existent section +'EditPageGetPreviewText': DEPRECATED! Use EditPageGetPreviewContent instead. +Allow modifying the wikitext that will be previewed. Note that it is preferable +to implement previews for different data types using the ContentHandler +facility. +$editPage: EditPage object +&$toparse: wikitext that will be parsed + +'EditPageNoSuchSection': When a section edit request is given for an +non-existent section &$editpage: The current EditPage object &$res: the HTML of the error text @@ -1269,10 +1265,10 @@ $title: title of page being edited &$msg: localization message name, overridable. Default is 'editpage-tos-summary' 'EmailConfirmed': When checking that the user's email address is "confirmed". -$user: User being checked -$confirmed: Whether or not the email address is confirmed This runs before the other checks, such as anonymity and the real check; return true to allow those checks to occur, and false if checking is done. +$user: User being checked +$confirmed: Whether or not the email address is confirmed 'EmailUser': Before sending email from one user to another. $to: address of receiving user @@ -1316,11 +1312,12 @@ $ip: The ip address of the user change the tables headers. &$extTypes: associative array of extensions types -'ExtractThumbParameters': Called when extracting thumbnail parameters from a -thumbnail file name. -DEPRECATED: Media handler should override MediaHandler::parseParamString instead. +'ExtractThumbParameters': DEPRECATED! Media handler should override +MediaHandler::parseParamString instead. +Called when extracting thumbnail parameters from a thumbnail file name. $thumbname: the base name of the thumbnail file -&$params: the currently extracted params (has source name, temp or archived zone) +&$params: the currently extracted params (has source name, temp or archived +zone) 'FetchChangesList': When fetching the ChangesList derivative for a particular user. @@ -1343,6 +1340,12 @@ $thumb: the MediaTransformOutput object $tmpThumbPath: The temporary file system path of the transformed file $thumbPath: The permanent storage path of the transformed file +'FileUndeleteComplete': When a file is undeleted +$title: title object to the file +$fileVersions: array of undeleted versions. Empty if all versions were restored +$user: user who performed the undeletion +$reason: reason + 'FileUpload': When a file upload occurs. $file : Image object representing the file that was uploaded $reupload : Boolean indicating if there was a previously another image there or @@ -1350,26 +1353,20 @@ $reupload : Boolean indicating if there was a previously another image there or $hasDescription : Boolean indicating that there was already a description page and a new one from the comment wasn't created (since 1.17) -'FileUndeleteComplete': When a file is undeleted -$title: title object to the file -$fileVersions: array of undeleted versions. Empty if all versions were restored -$user: user who performed the undeletion -$reason: reason - 'FormatAutocomments': When an autocomment is formatted by the Linker. - &$comment: Reference to the accumulated comment. Initially null, when set the - default code will be skipped. - $pre: Boolean, true if there is text before this autocomment - $auto: The extracted part of the parsed comment before the call to the hook. - $post: Boolean, true if there is text after this autocomment - $title: An optional title object used to links to sections. Can be null. - $local: Boolean indicating whether section links should refer to local page. +&$comment: Reference to the accumulated comment. Initially null, when set the + default code will be skipped. +$pre: Boolean, true if there is text before this autocomment +$auto: The extracted part of the parsed comment before the call to the hook. +$post: Boolean, true if there is text after this autocomment +$title: An optional title object used to links to sections. Can be null. +$local: Boolean indicating whether section links should refer to local page. 'GalleryGetModes': Get list of classes that can render different modes of a - gallery +gallery. &$modeArray: An associative array mapping mode names to classes that implement - that mode. It is expected all registered classes are a subclass of - ImageGalleryBase. + that mode. It is expected all registered classes are a subclass of + ImageGalleryBase. 'GetAutoPromoteGroups': When determining which autopromote groups a user is entitled to be in. @@ -1394,18 +1391,32 @@ $query: query options passed to Title::getCanonicalURL() $title: Title object that we need to get a sortkey for &$sortkey: Sortkey to use. -'GetDoubleUnderscoreIDs': Modify the list of behavior switch (double -underscore) magic words. Called by MagicWord. +'GetDifferenceEngine': Called when getting a new difference engine interface +object Return false for valid object in $differenceEngine or true for the +default difference engine. +$context: IContextSource context to be used for diff +$old: Revision ID to show and diff with +$new: Either a revision ID or one of the strings 'cur', 'prev' or 'next' +$refreshCache: If set, refreshes the diff cache +$unhide: If set, allow viewing deleted revs +&$differenceEngine: output parameter, difference engine object to be used for + diff + +'GetDoubleUnderscoreIDs': Modify the list of behavior switch (double +underscore) magic words. Called by MagicWord. &$doubleUnderscoreIDs: array of strings 'GetExtendedMetadata': Get extended file metadata for the API -&$combinedMeta: Array of the form: 'MetadataPropName' => array( -'value' => prop value, 'source' => 'name of hook' ). +&$combinedMeta: Array of the form: + 'MetadataPropName' => array( + value' => prop value, + 'source' => 'name of hook' + ). $file: File object of file in question $context: RequestContext (including language to use) $single: Only extract the current language; if false, the prop value should -be in the metadata multi-language array format: -mediawiki.org/wiki/Manual:File_metadata_handling#Multi-language_array_format + be in the metadata multi-language array format: + mediawiki.org/wiki/Manual:File_metadata_handling#Multi-language_array_format &$maxCacheTime: how long the results can be cached 'GetFullURL': Modify fully-qualified URLs used in redirects/export/offsite data. @@ -1413,9 +1424,9 @@ $title: Title object of page $url: string value as output (out parameter, can modify) $query: query options passed to Title::getFullURL() -'GetHumanTimestamp': Pre-emptively override the human-readable timestamp generated -by MWTimestamp::getHumanTimestamp(). Return false in this hook to use the custom -output. +'GetHumanTimestamp': Pre-emptively override the human-readable timestamp +generated by MWTimestamp::getHumanTimestamp(). Return false in this hook to use +the custom output. &$output: string for the output timestamp $timestamp: MWTimestamp object of the current (user-adjusted) timestamp $relativeTo: MWTimestamp object of the relative (user-adjusted) timestamp @@ -1432,7 +1443,7 @@ $query: query options passed to Title::getInternalURL() 'GetLinkColours': modify the CSS class of an array of page links. $linkcolour_ids: array of prefixed DB keys of the pages linked to, - indexed by page_id. + indexed by page_id. &$colours: (output) array of CSS classes, indexed by prefixed DB keys 'GetLocalURL': Modify local URLs as output into page links. Note that if you are @@ -1444,15 +1455,15 @@ $title: Title object of page &$url: string value as output (out parameter, can modify) $query: query options passed to Title::getLocalURL() -'GetLocalURL::Internal': Modify local URLs to internal pages. +'GetLocalURL::Article': Modify local URLs specifically pointing to article paths +without any fancy queries or variants. $title: Title object of page &$url: string value as output (out parameter, can modify) -$query: query options passed to Title::getLocalURL() -'GetLocalURL::Article': Modify local URLs specifically pointing to article paths -without any fancy queries or variants. +'GetLocalURL::Internal': Modify local URLs to internal pages. $title: Title object of page &$url: string value as output (out parameter, can modify) +$query: query options passed to Title::getLocalURL() 'GetLogTypesOnUser': Add log types where the target is a userpage &$types: Array of log types @@ -1467,9 +1478,10 @@ the media handler metadata output. 'GetNewMessagesAlert': Disable or modify the new messages alert &$newMessagesAlert: An empty string by default. If the user has new talk page -messages, this should be populated with an alert message to that effect -$newtalks: An empty array if the user has no new messages or an array containing -links and revisions if there are new messages (See User::getNewMessageLinks) + messages, this should be populated with an alert message to that effect +$newtalks: An empty array if the user has no new messages or an array + containing links and revisions if there are new messages (See + User::getNewMessageLinks) $user: The user object of the user who is loading the page $out: OutputPage object (to check what type of page the user is on) @@ -1478,8 +1490,8 @@ $user: User whose preferences are being modified. &$preferences: Preferences description array, to be fed to an HTMLForm object 'GetRelativeTimestamp': Pre-emptively override the relative timestamp generated -by MWTimestamp::getRelativeTimestamp(). Return false in this hook to use the custom -output. +by MWTimestamp::getRelativeTimestamp(). Return false in this hook to use the +custom output. &$output: string for the output timestamp &$diff: DateInterval representing the difference between the timestamps $timestamp: MWTimestamp object of the current (user-adjusted) timestamp @@ -1495,7 +1507,7 @@ should be plain text with no special coloring, bolding, etc. to show that they're errors; presenting them properly to the user as errors is done by the caller. $title: Title object being checked against -$user : Current user object +$user: Current user object $action: Action being checked $result: User permissions error to add. If none, return true. @@ -1506,9 +1518,8 @@ populate $result with the reason in the form of array( messagename, param1, param2, ... ). For consistency, error messages should be plain text with no special coloring, bolding, etc. to show that they're errors; presenting them properly to the user as errors is done by the caller. - $title: Title object being checked against -$user : Current user object +$user: Current user object $action: Action being checked $result: User permissions error to add. If none, return true. @@ -1523,7 +1534,8 @@ $rev: Revision object 'HTMLFileCache::useFileCache': Override whether a page should be cached in file cache. -$context: An IContextSource object with information about the request being served. +$context: An IContextSource object with information about the request being + served. 'ImageBeforeProduceHTML': Called before producing the HTML created by a wiki image insertion. You can skip the default logic entirely by returning false, or @@ -1538,7 +1550,6 @@ just modify a few things using call-by-reference. &$time: Timestamp of file in 'YYYYMMDDHHIISS' string form, or false for current &$res: Final HTML output, used if you return false - 'ImageOpenShowImageInlineBefore': Call potential extension just before showing the image on an image page. $imagePage: ImagePage object ($this) @@ -1578,29 +1589,29 @@ using img_auth.php. header message cannot receive/use parameters. 'ImportHandleLogItemXMLTag': When parsing a XML tag in a log item. +Return false to stop further processing of the tag $reader: XMLReader object $logInfo: Array of information -Return false to stop further processing of the tag 'ImportHandlePageXMLTag': When parsing a XML tag in a page. +Return false to stop further processing of the tag $reader: XMLReader object $pageInfo: Array of information -Return false to stop further processing of the tag 'ImportHandleRevisionXMLTag': When parsing a XML tag in a page revision. +Return false to stop further processing of the tag $reader: XMLReader object $pageInfo: Array of page information $revisionInfo: Array of revision information -Return false to stop further processing of the tag 'ImportHandleToplevelXMLTag': When parsing a top level XML tag. -$reader: XMLReader object Return false to stop further processing of the tag +$reader: XMLReader object 'ImportHandleUploadXMLTag': When parsing a XML tag in a file upload. +Return false to stop further processing of the tag $reader: XMLReader object $revisionInfo: Array of information -Return false to stop further processing of the tag 'InfoAction': When building information to display on the action=info page. $context: IContextSource object @@ -1613,11 +1624,11 @@ $ignoreRedirect: boolean to skip redirect check $target: Title/string of redirect target $article: Article object -'InterwikiLoadPrefix': When resolving if a given prefix is an interwiki or not. -Return true without providing an interwiki to continue interwiki search. -$prefix: interwiki prefix we are looking for. -&$iwData: output array describing the interwiki with keys iw_url, iw_local, - iw_trans and optionally iw_api and iw_wikiid. +'InternalParseBeforeLinks': during Parser's internalParse method before links +but after nowiki/noinclude/includeonly/onlyinclude and other processings. +&$parser: Parser object +&$text: string containing partially parsed text +&$stripState: Parser's internal StripState object 'InternalParseBeforeSanitize': during Parser's internalParse method just before the parser removes unwanted/dangerous HTML tags and after nowiki/noinclude/ @@ -1627,11 +1638,11 @@ template/parser function execution which respect nowiki and HTML-comments. &$text: string containing partially parsed text &$stripState: Parser's internal StripState object -'InternalParseBeforeLinks': during Parser's internalParse method before links -but after nowiki/noinclude/includeonly/onlyinclude and other processings. -&$parser: Parser object -&$text: string containing partially parsed text -&$stripState: Parser's internal StripState object +'InterwikiLoadPrefix': When resolving if a given prefix is an interwiki or not. +Return true without providing an interwiki to continue interwiki search. +$prefix: interwiki prefix we are looking for. +&$iwData: output array describing the interwiki with keys iw_url, iw_local, + iw_trans and optionally iw_api and iw_wikiid. 'InvalidateEmailComplete': Called after a user's email has been invalidated successfully. @@ -1668,18 +1679,18 @@ $user: User the password is being validated for $code: The language code or the language we're looking for a messages file for &$file: The messages file path, you can override this to change the location. -'LanguageGetNamespaces': Provide custom ordering for namespaces or -remove namespaces. Do not use this hook to add namespaces. Use -CanonicalNamespaces for that. -&$namespaces: Array of namespaces indexed by their numbers - -'LanguageGetMagic': DEPRECATED, use $magicWords in a file listed in +'LanguageGetMagic': DEPRECATED! Use $magicWords in a file listed in $wgExtensionMessagesFiles instead. Use this to define synonyms of magic words depending of the language $magicExtensions: associative array of magic words synonyms $lang: language code (string) -'LanguageGetSpecialPageAliases': DEPRECATED, use $specialPageAliases in a file +'LanguageGetNamespaces': Provide custom ordering for namespaces or +remove namespaces. Do not use this hook to add namespaces. Use +CanonicalNamespaces for that. +&$namespaces: Array of namespaces indexed by their numbers + +'LanguageGetSpecialPageAliases': DEPRECATED! Use $specialPageAliases in a file listed in $wgExtensionMessagesFiles instead. Use to define aliases of special pages names depending of the language $specialPageAliases: associative array of magic words synonyms @@ -1687,7 +1698,7 @@ $lang: language code (string) 'LanguageGetTranslatedLanguageNames': Provide translated language names. &$names: array of language code => language name -$code language of the preferred translations +$code: language of the preferred translations 'LanguageLinks': Manipulate a page's language links. This is called in various places to allow extensions to define the effective language @@ -1712,8 +1723,9 @@ $target: the Title that the link is pointing to &$html: the contents that the tag should have (raw HTML); null means "default". &$customAttribs: the HTML attributes that the tag should have, in -associative array form, with keys and values unescaped. Should be merged with -default values, with a value of false meaning to suppress the attribute. + associative array form, with keys and values unescaped. Should be merged + with default values, with a value of false meaning to suppress the + attribute. &$query: the query string to add to the generated URL (the bit after the "?"), in associative array form, with keys and values unescaped. &$options: array of options. Can include 'known', 'broken', 'noclasses'. @@ -1775,7 +1787,7 @@ including delete and insert, has completed for all link tables &$tags: The list of tags. 'LoadExtensionSchemaUpdates': Called during database installation and updates. -&updater: A DatabaseUpdater subclass +&$updater: A DatabaseUpdater subclass 'LocalFile::getHistory': Called before file history query performed. $file: the File object @@ -1794,7 +1806,8 @@ cache. $cache: The LocalisationCache object $code: language code &$alldata: The localisation data from core and extensions -&purgeBlobs: whether to purge/update the message blobs via MessageBlobStore::clear() +&$purgeBlobs: whether to purge/update the message blobs via + MessageBlobStore::clear() 'LocalisationCacheRecacheFallback': Called for each language when merging fallback data into the cache. @@ -1810,16 +1823,15 @@ localisation checks. 'LocalisationIgnoredOptionalMessages': When fetching the list of ignored and optional localisation messages -&$ignored Array of ignored message keys -&$optional Array of optional message keys +&$ignored: Array of ignored message keys +&$optional: Array of optional message keys -'LogEventsListGetExtraInputs': When getting extra inputs to display on Special:Log -for a specific log type +'LogEventsListGetExtraInputs': When getting extra inputs to display on +Special:Log for a specific log type $type: String of log type being displayed $logEventsList: LogEventsList object for context and access to the WebRequest &$input: string HTML of an input element - 'LogEventsListShowLogExtract': Called before the string is added to OutputPage. Returning false will prevent the string from being added to the OutputPage. &$s: html string to show for the log extract @@ -1842,6 +1854,13 @@ $param: Associative Array with the following additional options: "<div ...>$1</div>"). - flags Integer display flags (NO_ACTION_LINK,NO_EXTRA_USER_LINKS) +'LogException': Called before an exception (or PHP error) is logged. This is +meant for integration with external error aggregation services; returning false +will NOT prevent logging. +$e: The exception (in case of a plain old PHP error, a wrapping ErrorException) +$suppressed: true if the error was suppressed via + error_reporting()/wfSuppressWarnings() + 'LoginAuthenticateAudit': A login attempt for a valid user account either succeeded or failed. No return data is accepted; this hook is for auditing only. $user: the User object being authenticated against @@ -1849,11 +1868,26 @@ $password: the password being submitted and found wanting $retval: a LoginForm class constant with authenticateUserData() return value (SUCCESS, WRONG_PASS, etc.). -'LoginPasswordResetMessage': User is being requested to reset their password on login. -Use this hook to change the Message that will be output on Special:ChangePassword. +'LoginFormValidErrorMessages': Called in LoginForm when a function gets valid +error messages. Allows to add additional error messages (except messages already +in LoginForm::$validErrorMessages). +&$messages: Already added messages (inclusive messages from + LoginForm::$validErrorMessages) + +'LoginPasswordResetMessage': User is being requested to reset their password on +login. Use this hook to change the Message that will be output on +Special:ChangePassword. &$msg: Message object that will be shown to the user $username: Username of the user who's password was expired. +'LoginUserMigrated': Called during login to allow extensions the opportunity to +inform a user that their username doesn't exist for a specific reason, instead +of letting the login form give the generic error message that the account does +not exist. For example, when the account has been renamed or deleted. +$user: the User object being authenticated against. +&$msg: the message identifier for abort reason, or an array to pass a message + key and parameters. + 'LogLine': Processes a single log entry on Special:Log. $log_type: string for the type of log entry (e.g. 'move'). Corresponds to logging.log_type database field. @@ -1874,13 +1908,13 @@ Special:LonelyPages. &$conds: conditions for the query &$joinConds: join conditions for the query +'MagicWordwgVariableIDs': When defining new magic words IDs. +$variableIDs: array of strings + 'MaintenanceRefreshLinksInit': before executing the refreshLinks.php maintenance script. $refreshLinks: RefreshLinks object -'MagicWordwgVariableIDs': When defining new magic words IDs. -$variableIDs: array of strings - 'MakeGlobalVariablesScript': Called at end of OutputPage::getJSVars. Ideally, this hook should only be used to add variables that depend on the current page/request; static configuration should be added through @@ -1911,10 +1945,6 @@ $user: $wgUser $request: $wgRequest $mediaWiki: The $mediawiki object -'MessagesPreLoad': When loading a message from the database. -$title: title of the message (string) -$message: value (string), change it to the message you want to define - 'MessageCache::get': When fetching a message. Can be used to override the key for customisations. Given and returned message key must be in special format: 1) first letter must be in lower case according to the content language. @@ -1926,15 +1956,17 @@ caches. $title: name of the page changed. $text: new contents of the page. -'MimeMagicInit': Before processing the list mapping MIME types to media types -and the list mapping MIME types to file extensions. -As an extension author, you are encouraged to submit patches to MediaWiki's -core to add new MIME types to mime.types. +'MessagesPreLoad': When loading a message from the database. +$title: title of the message (string) +$message: value (string), change it to the message you want to define + +'MimeMagicGuessFromContent': Allows MW extensions guess the MIME by content. $mimeMagic: Instance of MimeMagic. - Use $mimeMagic->addExtraInfo( $stringOfInfo ); - for adding new MIME info to the list. - Use $mimeMagic->addExtraTypes( $stringOfTypes ); - for adding new MIME types to the list. +&$head: First 1024 bytes of the file in a string (in - Do not alter!). +&$tail: More or equal than last 65558 bytes of the file in a string + (in - Do not alter!). +$file: File path. +&$mime: MIME type (out). 'MimeMagicImproveFromExtension': Allows MW extensions to further improve the MIME type detected by considering the file extension. @@ -1942,13 +1974,15 @@ $mimeMagic: Instance of MimeMagic. $ext: File extension. &$mime: MIME type (in/out). -'MimeMagicGuessFromContent': Allows MW extensions guess the MIME by content. +'MimeMagicInit': Before processing the list mapping MIME types to media types +and the list mapping MIME types to file extensions. +As an extension author, you are encouraged to submit patches to MediaWiki's +core to add new MIME types to mime.types. $mimeMagic: Instance of MimeMagic. -&$head: First 1024 bytes of the file in a string (in - Do not alter!). -&$tail: More or equal than last 65558 bytes of the file in a string - (in - Do not alter!). -$file: File path. -&$mime: MIME type (out). + Use $mimeMagic->addExtraInfo( $stringOfInfo ); + for adding new MIME info to the list. + Use $mimeMagic->addExtraTypes( $stringOfTypes ); + for adding new MIME types to the list. 'ModifyExportQuery': Modify the query used by the exporter. $db: The database object to be queried. @@ -1957,27 +1991,20 @@ $db: The database object to be queried. &$opts: Options for the query. &$join_conds: Join conditions for the query. -'MovePageCheckPermissions': Specify whether the user is allowed to move the page. +'MovePageCheckPermissions': Specify whether the user is allowed to move the +page. $oldTitle: Title object of the current (old) location $newTitle: Title object of the new location $user: User making the move $reason: string of the reason provided by the user $status: Status object to pass error messages to -'MovePageIsValidMove': Specify whether a page can be moved for technical reasons. +'MovePageIsValidMove': Specify whether a page can be moved for technical +reasons. $oldTitle: Title object of the current (old) location $newTitle: Title object of the new location $status: Status object to pass error messages to -'BaseTemplateToolbox': Called by BaseTemplate when building the $toolbox array -and returning it for the skin to output. You can add items to the toolbox while -still letting the skin make final decisions on skin-specific markup conventions -using this hook. -&$sk: The BaseTemplate base skin template -&$toolbox: An array of toolbox items, see BaseTemplate::getToolbox and - BaseTemplate::makeListItem for details on the format of individual items - inside of this array. - 'NamespaceIsMovable': Called when determining if it is possible to pages in a namespace. $index: Integer; the index of the namespace being checked. @@ -1985,6 +2012,13 @@ $result: Boolean; whether MediaWiki currently thinks that pages in this namespace are movable. Hooks may change this value to override the return value of MWNamespace::isMovable(). +'NewDifferenceEngine': Called when a new DifferenceEngine object is made +$title: the diff page title (nullable) +&$oldId: the actual old Id to use in the diff +&$newId: the actual new Id to use in the diff (0 means current) +$old: the ?old= param value from the url +$new: the ?new= param value from the url + 'NewRevisionFromEditComplete': Called when a revision was inserted due to an edit. $wikiPage: the WikiPage edited @@ -2046,11 +2080,7 @@ $sk: The Skin that called OutputPage::headElement 'OutputPageCheckLastModified': when checking if the page has been modified since the last visit. &$modifiedTimes: array of timestamps. - The following keys are set: page, user, epoch - -'OutputPageParserOutput': after adding a parserOutput to $wgOut -$out: OutputPage instance (object) -$parserOutput: parserOutput instance being added in $out + The following keys are set: page, user, epoch 'OutputPageMakeCategoryLinks': Links are about to be generated for the page's categories. Implementations should return false if they generate the category @@ -2061,6 +2091,10 @@ $categories: associative array, keys are category names, values are category $links: array, intended to hold the result. Must be an associative array with category types as keys and arrays of HTML links as values. +'OutputPageParserOutput': after adding a parserOutput to $wgOut +$out: OutputPage instance (object) +$parserOutput: parserOutput instance being added in $out + 'PageContentInsertComplete': After a new article is created. $wikiPage: WikiPage created $user: User creating the article @@ -2096,7 +2130,8 @@ $isMinor: Whether or not the edit was marked as minor $isWatch: (No longer used) $section: (No longer used) $flags: Flags passed to WikiPage::doEditContent() -$revision: New Revision of the article (can be null for edits that change nothing) +$revision: New Revision of the article (can be null for edits that change + nothing) $status: Status object about to be returned by doEditContent() $baseRevId: the rev ID (or false) this edit was based on @@ -2109,11 +2144,6 @@ $row: the revision row for this line $s: the string representing this parsed line $classes: array containing the
  • element classes -'PageHistoryPager::getQueryInfo': when a history pager query parameter set is -constructed. -$pager: the pager -$queryInfo: the query parameters - 'PageHistoryPager::doBatchLookups': Called after the pager query was run, before any output is generated, to allow batch lookups for prefetching information needed for display. If the hook handler returns false, the regular behavior of @@ -2121,6 +2151,11 @@ doBatchLookups() is skipped. $pager: the PageHistoryPager $result: a ResultWrapper representing the query result +'PageHistoryPager::getQueryInfo': when a history pager query parameter set is +constructed. +$pager: the pager +$queryInfo: the query parameters + 'PageRenderingHash': Alter the parser cache option hash key. A parser extension which depends on user options should install this hook and append its values to the key. @@ -2149,7 +2184,8 @@ $stripState: stripState used (object) $parser: Parser object being used $text: text that will be returned -'ParserAfterUnstrip': Called after the first unstripGeneral() in Parser::internalParseHalfParsed() +'ParserAfterUnstrip': Called after the first unstripGeneral() in +Parser::internalParseHalfParsed() $parser: Parser object being used $text: text that will be returned @@ -2168,6 +2204,14 @@ $stripState: stripState used (object) $parser: Parser object being used $text: actual text +'ParserCacheSaveComplete': Called after a ParserOutput has been committed to +the parser cache. +$parserCache: ParserCache object $parserOutput was stored in +$parserOutput: ParserOutput object that was stored +$title: Title of the page that was parsed to generate $parserOutput +$popts: ParserOptions used for generating $parserOutput +$revId: ID of the revision that was parsed to create $parserOutput + 'ParserClearState': Called at the end of Parser::clearState(). $parser: Parser object being cleared @@ -2181,7 +2225,7 @@ $parser: Newly-cloned Parser object custom magic word $parser: Parser object $varCache: array to store the value in case of multiples calls of the - same magic word + same magic word $index: index (string) of the magic $ret: value of the magic word (the hook should set it) $frame: PPFrame object to use for expanding any template variables @@ -2196,7 +2240,7 @@ cache or return false to not use it. $parser: Parser object $varCache: variable cache (array) -'ParserLimitReport': DEPRECATED, use ParserLimitReportPrepare and +'ParserLimitReport': DEPRECATED! Use ParserLimitReportPrepare and ParserLimitReportFormat instead. Called at the end of Parser:parse() when the parser will include comments about size of the text parsed. @@ -2211,11 +2255,11 @@ $key: Key for the limit report item (string) &$value: Value of the limit report item &$report: String onto which to append the data $isHTML: If true, $report is an HTML table with two columns; if false, it's - text intended for display in a monospaced font. + text intended for display in a monospaced font. $localize: If false, $report should be output in English. -'ParserLimitReportPrepare': Called at the end of Parser:parse() when the parser will -include comments about size of the text parsed. Hooks should use +'ParserLimitReportPrepare': Called at the end of Parser:parse() when the parser +will include comments about size of the text parsed. Hooks should use $output->setLimitReportData() to populate data. Functions for this hook should not use $wgLang; do that in ParserLimitReportFormat instead. $parser: Parser object @@ -2238,47 +2282,49 @@ $section: the section number, zero-based, but section 0 is usually empty &$sectionContent: ref to the content of the section. modify this. $showEditLinks: boolean describing whether this section has an edit link -'ParserCacheSaveComplete': Called after a ParserOutput has been committed to -the parser cache. -$parserCache: ParserCache object $parserOutput was stored in -$parserOutput: ParserOutput object that was stored -$title: Title of the page that was parsed to generate $parserOutput -$popts: ParserOptions used for generating $parserOutput -$revId: ID of the revision that was parsed to create $parserOutput +'ParserTestGlobals': Allows to define globals for parser tests. +&$globals: Array with all the globals which should be set for parser tests. + The arrays keys serve as the globals names, its values are the globals values. 'ParserTestParser': Called when creating a new instance of Parser in tests/parser/parserTest.inc. $parser: Parser object created -'ParserTestGlobals': Allows to define globals for parser tests. -&$globals: Array with all the globals which should be set for parser tests. - The arrays keys serve as the globals names, its values are the globals values. - 'ParserTestTables': Alter the list of tables to duplicate when parser tests are run. Use when page save hooks require the presence of custom tables to ensure that tests continue to run properly. &$tables: array of table names +'PasswordPoliciesForUser': Alter the effective password policy for a user. +$user: User object whose policy you are modifying +&$effectivePolicy: Array of policy statements that apply to this user + +'PerformRetroactiveAutoblock': Called before a retroactive autoblock is applied +to a user. +$block: Block object (which is set to be autoblocking) +&$blockIds: Array of block IDs of the autoblock + 'PersonalUrls': Alter the user-specific navigation links (e.g. "my page, my talk page, my contributions" etc). &$personal_urls: Array of link specifiers (see SkinTemplate.php) &$title: Title object representing the current page -$skin: SkinTemplate object providing context (e.g. to check if the user is logged in, etc.) +$skin: SkinTemplate object providing context (e.g. to check if the user is + logged in, etc.) 'PingLimiter': Allows extensions to override the results of User::pingLimiter(). -&$user : User performing the action -$action : Action being performed -&$result : Whether or not the action should be prevented -Change $result and return false to give a definitive answer, otherwise -the built-in rate limiting checks are used, if enabled. +&$user: User performing the action +$action: Action being performed +&$result: Whether or not the action should be prevented + Change $result and return false to give a definitive answer, otherwise + the built-in rate limiting checks are used, if enabled. $incrBy: Amount to increment counter by 'PlaceNewSection': Override placement of new sections. Return false and put the merged text into $text to override the default behavior. -$wikipage : WikiPage object -$oldtext : the text of the article before editing -$subject : subject of the new section -&$text : text of the new section +$wikipage: WikiPage object +$oldtext: the text of the article before editing +$subject: subject of the new section +&$text: text of the new section 'PostLoginRedirect': Modify the post login redirect behavior. Occurs after signing up or logging in, allows for interception of redirect. @@ -2290,32 +2336,33 @@ Occurs after signing up or logging in, allows for interception of redirect. success: display a return to link using $wgRedirectOnLogin if needed successredirect: send an HTTP redirect using $wgRedirectOnLogin if needed +'PreferencesFormPreSave': Override preferences being saved +$formData: array of user submitted data +$form: PreferencesForm object, also a ContextSource +$user: User object with preferences to be saved set +&$result: boolean indicating success + 'PreferencesGetLegend': Override the text used for the of a preferences section. $form: the PreferencesForm object. This is a ContextSource as well $key: the section name -&$legend: the legend text. Defaults to wfMessage( "prefs-$key" )->text() but may be overridden - -'PreferencesFormPreSave': Override preferences being saved - $formData: array of user submitted data - $form: PreferencesForm object, also a ContextSource - $user: User object with preferences to be saved set - &$result: boolean indicating success +&$legend: the legend text. Defaults to wfMessage( "prefs-$key" )->text() but may + be overridden 'PrefixSearchBackend': Override the title prefix search used for OpenSearch and AJAX search suggestions. Put results into &$results outparam and return false. -$ns : array of int namespace keys to search in -$search : search term (not guaranteed to be conveniently normalized) -$limit : maximum number of results to return -&$results : out param: array of page names (strings) -$offset : number of results to offset from the beginning +$ns: array of int namespace keys to search in +$search: search term (not guaranteed to be conveniently normalized) +$limit: maximum number of results to return +&$results: out param: array of page names (strings) +$offset: number of results to offset from the beginning '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) +$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 @@ -2355,10 +2402,16 @@ names such as "oldid" that are preserved when using redirecting special pages such as Special:MyPage and Special:MyTalk. &$redirectParams: An array of parameters preserved by redirecting special pages. +'RejectParserCacheValue': Return false to reject an otherwise usable +cached value from the Parser cache. +$parserOutput: ParserOutput value. +$wikiPage: WikiPage object. +$parserOptions: ParserOptions object. + 'RequestContextCreateSkin': Called when RequestContext::getSkin creates a skin instance. Can be used by an extension override what skin is used in certain contexts. -IContextSource $context: The RequestContext the skin is being created for. +$context: (IContextSource) The RequestContext the skin is being created for. &$skin: A variable reference you may set a Skin instance or string key on to override the skin that will be used for the context. @@ -2376,8 +2429,9 @@ configuration variables to JavaScript. Things that depend on the current page or request state must be added through MakeGlobalVariablesScript instead. &$vars: array( variable name => value ) -'ResourceLoaderGetLessVars': Called in ResourceLoader::getLessVars after variables -from $wgResourceLoaderLESSVars are added. Can be used to add context-based variables. +'ResourceLoaderGetLessVars': Called in ResourceLoader::getLessVars after +variables from $wgResourceLoaderLESSVars are added. Can be used to add +context-based variables. &$lessVars: array of variables already added 'ResourceLoaderRegisterModules': Right before modules information is required, @@ -2387,17 +2441,16 @@ loader request or generating HTML output. 'ResourceLoaderTestModules': Let you add new JavaScript testing modules. This is called after the addition of 'qunit' and MediaWiki testing resources. -&testModules: array of JavaScript testing modules. The 'qunit' framework, +&$testModules: array of JavaScript testing modules. The 'qunit' framework, included in core, is fed using tests/qunit/QUnitTestResources.php. -&ResourceLoader object - -To add a new qunit module named 'myext.tests': -testModules['qunit']['myext.tests'] = array( - 'script' => 'extension/myext/tests.js', - 'dependencies' => -); -For QUnit framework, the mediawiki.tests.qunit.testrunner dependency will be -added to any module. + To add a new qunit module named 'myext.tests': + $testModules['qunit']['myext.tests'] = array( + 'script' => 'extension/myext/tests.js', + 'dependencies' => + ); + For QUnit framework, the mediawiki.tests.qunit.testrunner dependency will be + added to any module. +&$ResourceLoader: object 'RevisionInsertComplete': Called after a revision is inserted into the database. &$revision: the Revision @@ -2408,35 +2461,35 @@ $data: the data stored in old_text. The meaning depends on $flags: if external $flags: a comma-delimited list of strings representing the options used. May include: utf8 (this will always be set for new revisions); gzip; external. -'SearchGetNearMatchBefore': Perform exact-title-matches in "go" searches before -the normal operations. -$allSearchTerms : Array of the search terms in all content languages -&$titleResult : Outparam; the value to return. A Title object or null. +'SearchableNamespaces': An option to modify which namespaces are searchable. +&$arr: Array of namespaces ($nsId => $name) which will be used. 'SearchAfterNoDirectMatch': If there was no match for the exact result. This runs before lettercase variants are attempted, whereas 'SearchGetNearMatch' runs after. -$term : Search term string -&$title : Outparam; set to $title object and return false for a match +$term: Search term string +&$title: Outparam; set to $title object and return false for a match 'SearchGetNearMatch': An extra chance for exact-title-matches in "go" searches if nothing was found. -$term : Search term string -&$title : Outparam; set to $title object and return false for a match +$term: Search term string +&$title: Outparam; set to $title object and return false for a match + +'SearchGetNearMatchBefore': Perform exact-title-matches in "go" searches before +the normal operations. +$allSearchTerms: Array of the search terms in all content languages +&$titleResult: Outparam; the value to return. A Title object or null. 'SearchGetNearMatchComplete': A chance to modify exact-title-matches in "go" searches. -$term : Search term string -&$title : Current Title object that is being returned (null if none found). +$term: Search term string +&$title: Current Title object that is being returned (null if none found). 'SearchResultInitFromTitle': Set the revision used when displaying a page in search results. -$title : Current Title object being displayed in search results. +$title: Current Title object being displayed in search results. &$id: Revision ID (default is false, for latest) -'SearchableNamespaces': An option to modify which namespaces are searchable. -&$arr : Array of namespaces ($nsId => $name) which will be used. - 'SecondaryDataUpdates': Allows modification of the list of DataUpdates to perform when page content is modified. Currently called by AbstractContent::getSecondaryDataUpdates. @@ -2457,24 +2510,23 @@ $nt: the Title object &$prefix: optional text to display after $html &$ret: the value to return if your hook returns false +'SendWatchlistEmailNotification': Return true to send watchlist email +notification +$targetUser: the user whom to send watchlist email notification +$title: the page title +$enotif: EmailNotification object + 'SetupAfterCache': Called in Setup.php, after cache objects are set 'ShowMissingArticle': Called when generating the output for a non-existent page. $article: The article object corresponding to the page -'ShowRawCssJs': Customise the output of raw CSS and JavaScript in page views. -DEPRECATED, use the ContentGetParserOutput hook instead! +'ShowRawCssJs': DEPRECATED! Use the ContentGetParserOutput hook instead. +Customise the output of raw CSS and JavaScript in page views. $text: Text being shown $title: Title of the custom script/stylesheet page $output: Current OutputPage object -'ShowSearchHitTitle': Customise display of search hit title/link. -&$title: Title to link to -&$text: Text to use for the link -$result: The search result -$terms: The search terms entered -$page: The SpecialSearch object. - 'ShowSearchHit': Customize display of search hit. $searchPage: The SpecialSearch instance. $result: The SearchResult to show @@ -2491,17 +2543,31 @@ $terms: Search terms, for highlighting hit. Must include the
  • ...
  • tags. Will only be used if the hook function returned false. -'SiteNoticeBefore': Before the sitenotice/anonnotice is composed. Return true to -allow the normal method of notice selection/rendering to work, or change the -value of $siteNotice and return false to alter it. -&$siteNotice: HTML returned as the sitenotice +'ShowSearchHitTitle': Customise display of search hit title/link. +&$title: Title to link to +&$text: Text to use for the link +$result: The search result +$terms: The search terms entered +$page: The SpecialSearch object. + +'SidebarBeforeOutput': Allows to edit sidebar just before it is output by skins. +Warning: This hook is run on each display. You should consider to use +'SkinBuildSidebar' that is aggressively cached. $skin: Skin object +&$bar: Sidebar content + Modify $bar to add or modify sidebar portlets. 'SiteNoticeAfter': After the sitenotice/anonnotice is composed. &$siteNotice: HTML sitenotice. Alter the contents of $siteNotice to add to/alter the sitenotice/anonnotice. $skin: Skin object +'SiteNoticeBefore': Before the sitenotice/anonnotice is composed. Return true to +allow the normal method of notice selection/rendering to work, or change the +value of $siteNotice and return false to alter it. +&$siteNotice: HTML returned as the sitenotice +$skin: Skin object + 'SkinAfterBottomScripts': At the end of Skin::bottomScripts(). $skin: Skin object &$text: bottomScripts Text. Append to $text to add additional text/scripts after @@ -2518,12 +2584,6 @@ $skin: Skin object &$bar: Sidebar contents Modify $bar to add or modify sidebar portlets. -'SidebarBeforeOutput': Allows to edit sidebar just before its output by skins. -$skin Skin object -&$bar: Sidebar content -Modify $bar to add or modify sidebar portlets. -Warning: This hook is run on each display. You should consider to use 'SkinBuildSidebar' that is aggressively cached. - 'SkinCopyrightFooter': Allow for site and per-namespace customization of copyright notice. $title: displayed page title @@ -2531,8 +2591,8 @@ $type: 'normal' or 'history' for old/diff views &$msg: overridable message; usually 'copyright' or 'history_copyright'. This message must be in HTML format, not wikitext! &$link: overridable HTML link to be passed into the message as $1 -&$forContent: overridable flag if copyright footer is shown in content language. - This parameter is deprecated. +&$forContent: DEPRECATED! overridable flag if copyright footer is shown in + content language. 'SkinEditSectionLinks': Modify the section edit links $skin: Skin object rendering the UI @@ -2542,18 +2602,18 @@ $section: The designation of the section being pointed to, to be included in the link, like "§ion=$section" $tooltip: The default tooltip. Escape before using. By default, this is wrapped in the 'editsectionhint' message. -&$result: Array containing all link detail arrays. Each link detail array should contain - the following keys: - * targetTitle - Target Title object - * text - String for the text - * attribs - Array of attributes - * query - Array of query parameters to add to the URL - * options - Array of options for Linker::link +&$result: Array containing all link detail arrays. Each link detail array should + contain the following keys: + - targetTitle - Target Title object + - text - String for the text + - attribs - Array of attributes + - query - Array of query parameters to add to the URL + - options - Array of options for Linker::link $lang: The language code to use for the link in the wfMessage function 'SkinGetPoweredBy': TODO &$text: additional 'powered by' icons in HTML. Note: Modern skin does not use -the MediaWiki icon but plain text instead. + the MediaWiki icon but plain text instead. $skin: Skin object 'SkinPreloadExistence': Supply titles that should be added to link existence @@ -2562,13 +2622,13 @@ cache before the page is rendered. $skin: Skin object 'SkinSubPageSubtitle': At the beginning of Skin::subPageSubtitle(). -&$subpages: Subpage links HTML -$skin: Skin object -$out: OutputPage object If false is returned $subpages will be used instead of the HTML subPageSubtitle() generates. If true is returned, $subpages will be ignored and the rest of subPageSubtitle() will run. +&$subpages: Subpage links HTML +$skin: Skin object +$out: OutputPage object 'SkinTemplateBuildNavUrlsNav_urlsAfterPermalink': After creating the "permanent link" tab. @@ -2583,13 +2643,18 @@ $languageLinkTitle: Title object belonging to the external language link. $title: Title object of the page the link belongs to. $outputPage: The OutputPage object the links are built from. -To alter the structured navigation links in SkinTemplates, there are three -hooks called in different spots: - 'SkinTemplateNavigation': Called on content pages after the tabs have been added, but before variants have been added. +&$sktemplate: SkinTemplate object +&$links: Structured navigation links. This is used to alter the navigation for + skins which use buildNavigationUrls such as Vector. + 'SkinTemplateNavigation::SpecialPage': Called on special pages after the special tab is added but before variants have been added. +&$sktemplate: SkinTemplate object +&$links: Structured navigation links. This is used to alter the navigation for + skins which use buildNavigationUrls such as Vector. + 'SkinTemplateNavigation::Universal': Called on both content and special pages after variants have been added. &$sktemplate: SkinTemplate object @@ -2631,10 +2696,6 @@ software. $software: The array of software in format 'name' => 'version'. See SpecialVersion::softwareInformation(). -'SpecialPageBeforeFormDisplay': Before executing the HTMLForm object. -$name: name of the special page -&$form: HTMLForm object - 'SpecialBlockModifyFormFields': Add more fields to Special:Block $sp: SpecialPage object, for context &$fields: Current HTMLForm fields @@ -2684,7 +2745,7 @@ Special:NewPages. &$special: NewPagesPager object (subclass of ReverseChronologicalPager) $opts: FormOptions object containing special page options &$conds: array of WHERE conditionals for query -&tables: array of tables to be queried +&$tables: array of tables to be queried &$fields: array of columns to select &$join_conds: join conditions for the tables @@ -2694,8 +2755,8 @@ $special: the special page object name/URL parameters. Each key maps to an associative array with a 'msg' (message key) and a 'default' value. -'SpecialPage_initList': Called when setting up SpecialPageFactory::$list, use this -hook to remove a core special page or conditionally register special pages. +'SpecialPage_initList': Called when setting up SpecialPageFactory::$list, use +this hook to remove a core special page or conditionally register special pages. $list: list (array) of core special pages 'SpecialPageAfterExecute': Called after SpecialPage::execute. @@ -2706,6 +2767,10 @@ $subPage: the subpage string or null if no subpage was specified $special: the SpecialPage object $subPage: the subpage string or null if no subpage was specified +'SpecialPageBeforeFormDisplay': Before executing the HTMLForm object. +$name: name of the special page +&$form: HTMLForm object + 'SpecialPasswordResetOnSubmit': When executing a form submission on Special:PasswordReset. $users: array of User objects. @@ -2723,8 +2788,9 @@ use this to change some selection criteria or substitute a different title. &$title: If the hook returns false, a Title object to use instead of the result from the normal query -'SpecialRecentChangesFilters': Called after building form options at -RecentChanges. Deprecated, use ChangesListSpecialPageFilters instead. +'SpecialRecentChangesFilters': DEPRECATED! Use ChangesListSpecialPageFilters +instead. +Called after building form options at RecentChanges. $special: the special page object &$filters: associative array of filter definitions. The keys are the HTML name/URL parameters. Each key maps to an associative array with a 'msg' @@ -2735,9 +2801,10 @@ SpecialRecentChanges. &$extraOpts: array of added items, to which can be added $opts: FormOptions for this request -'SpecialRecentChangesQuery': Called when building SQL query for -SpecialRecentChanges and SpecialRecentChangesLinked. Deprecated, use -ChangesListSpecialPageQuery instead. +'SpecialRecentChangesQuery': DEPRECATED! Use ChangesListSpecialPageQuery +instead. +Called when building SQL query for SpecialRecentChanges and +SpecialRecentChangesLinked. &$conds: array of WHERE conditionals for query &$tables: array of tables to be queried &$join_conds: join conditions for the tables @@ -2748,7 +2815,10 @@ $opts: FormOptions for this request 'SpecialResetTokensTokens': Called when building token list for SpecialResetTokens. &$tokens: array of token information arrays in the format of - array( 'preference' => '', 'label-message' => '' ) + array( + 'preference' => '', + 'label-message' => '', + ) 'SpecialSearchCreateLink': Called when making the message to create a page or go to the existing page. @@ -2765,9 +2835,6 @@ the advanced form, a.k.a. power search box. $term: the search term (not a title object) $opts: an array of hidden options (containing 'redirs' and 'profile') -'SpecialSearchProfiles': Allows modification of search profiles. -&$profiles: profiles, which can be modified. - 'SpecialSearchProfileForm': Allows modification of search profile forms. $search: special page object &$form: String: form html @@ -2775,10 +2842,13 @@ $profile: String: current search profile $term: String: search term $opts: Array: key => value of hidden options for inclusion in custom forms -'SpecialSearchSetupEngine': Allows passing custom data to search engine. -$search: SpecialSearch special page object -$profile: String: current search profile -$engine: the search engine +'SpecialSearchProfiles': Allows modification of search profiles. +&$profiles: profiles, which can be modified. + +'SpecialSearchResults': Called before search result display +$term: string of search term +&$titleMatches: empty or SearchResultSet object +&$textMatches: empty or SearchResultSet object 'SpecialSearchResultsPrepend': Called immediately before returning HTML on the search results page. Useful for including an external search @@ -2788,19 +2858,24 @@ $specialSearch: SpecialSearch object ($this) $output: $wgOut $term: Search term specified by the user -'SpecialSearchResults': Called before search result display -$term: string of search term -&$titleMatches: empty or SearchResultSet object -&$textMatches: empty or SearchResultSet object +'SpecialSearchResultsAppend': Called immediately before returning HTML +on the search results page. Useful for including a feedback link. +$specialSearch: SpecialSearch object ($this) +$output: $wgOut + +'SpecialSearchSetupEngine': Allows passing custom data to search engine. +$search: SpecialSearch special page object +$profile: String: current search profile +$engine: the search engine 'SpecialStatsAddExtra': Add extra statistic at the end of Special:Statistics. &$extraStats: Array to save the new stats - ( $extraStats[''] => ; - can be an array with the keys "name" and "number": - "name" is the HTML to be displayed in the name column - "number" is the number to be displayed. - or, can be the number to be displayed and is the - message key to use in the name column, + $extraStats[''] => ; + can be an array with the keys "name" and "number": + "name" is the HTML to be displayed in the name column + "number" is the number to be displayed. + or, can be the number to be displayed and is the + message key to use in the name column, $context: IContextSource object 'SpecialUploadComplete': Called after successfully uploading a file from @@ -2811,26 +2886,27 @@ $form: The SpecialUpload object $wgVersion: Current $wgVersion for you to use &$versionUrl: Raw url to link to (eg: release notes) -'SpecialWatchlistFilters': Called after building form options at Watchlist. -Deprecated, use ChangesListSpecialPageFilters instead. +'SpecialWatchlistFilters': DEPRECATED! Use ChangesListSpecialPageFilters +instead. +Called after building form options at Watchlist. $special: the special page object &$filters: associative array of filter definitions. The keys are the HTML name/URL parameters. Each key maps to an associative array with a 'msg' (message key) and a 'default' value. -'SpecialWatchlistQuery': Called when building sql query for SpecialWatchlist. -Deprecated, use ChangesListSpecialPageQuery instead. +'SpecialWatchlistGetNonRevisionTypes': Called when building sql query for +SpecialWatchlist. Allows extensions to register custom values they have +inserted to rc_type so they can be returned as part of the watchlist. +&$nonRevisionTypes: array of values in the rc_type field of recentchanges table + +'SpecialWatchlistQuery': DEPRECATED! Use ChangesListSpecialPageQuery instead. +Called when building sql query for SpecialWatchlist. &$conds: array of WHERE conditionals for query &$tables: array of tables to be queried &$join_conds: join conditions for the tables &$fields: array of query fields $opts: A FormOptions object with watchlist options for the current request -'SpecialWatchlistGetNonRevisionTypes': Called when building sql query for -SpecialWatchlist. Allows extensions to register custom values they have -inserted to rc_type so they can be returned as part of the watchlist. -&$nonRevisionTypes: array of values in the rc_type field of recentchanges table - 'TestCanonicalRedirect': Called when about to force a redirect to a canonical URL for a title when we have no other parameters on the URL. Gives a chance for extensions that alter page view behavior radically to abort that redirect or @@ -2854,32 +2930,17 @@ $res: database result used to create the object $title: The title being tested. &$exists: Whether the title exists. -'TitleQuickPermissions': Called from Title::checkQuickPermissions to add to -or override the quick permissions check. -$title: The Title object being accessed -$user: The User performing the action -$action: Action being performed -&$errors: Array of errors -$doExpensiveQueries: Whether to do expensive DB queries -$short: Whether to return immediately on first error - 'TitleGetEditNotices': Allows extensions to add edit notices $title: The Title object for the page the edit notices are for $oldid: Revision ID that the edit notices are for (or 0 for latest) -&$notices: Array of notices. Keys are i18n message keys, values are parseAsBlock()ed messages. +&$notices: Array of notices. Keys are i18n message keys, values are +parseAsBlock()ed messages. 'TitleGetRestrictionTypes': Allows extensions to modify the types of protection that can be applied. $title: The title in question. &$types: The types of protection available. -'TitleIsCssOrJsPage': DEPRECATED! Use ContentHandlerDefaultModelFor instead. -Called when determining if a page is a CSS or JS page. -$title: Title object that is being checked -$result: Boolean; whether MediaWiki currently thinks this is a CSS/JS page. - Hooks may change this value to override the return value of - Title::isCssOrJsPage(). - 'TitleIsAlwaysKnown': Called when determining if a page exists. Allows overriding default behavior for determining if a page exists. If $isKnown is kept as null, regular checks happen. If it's a boolean, this value is returned @@ -2887,6 +2948,13 @@ by the isKnown method. $title: Title object that is being checked &$isKnown: Boolean|null; whether MediaWiki currently thinks this page is known +'TitleIsCssOrJsPage': DEPRECATED! Use ContentHandlerDefaultModelFor instead. +Called when determining if a page is a CSS or JS page. +$title: Title object that is being checked +$result: Boolean; whether MediaWiki currently thinks this is a CSS/JS page. + Hooks may change this value to override the return value of + Title::isCssOrJsPage(). + 'TitleIsMovable': Called when determining if it is possible to move a page. Note that this hook is not called for interwiki pages or pages in immovable namespaces: for these, isMovable() always returns false. @@ -2916,6 +2984,15 @@ $pageid: database ID of the page that's been moved $redirid: database ID of the created redirect $reason: reason for the move +'TitleQuickPermissions': Called from Title::checkQuickPermissions to add to +or override the quick permissions check. +$title: The Title object being accessed +$user: The User performing the action +$action: Action being performed +&$errors: Array of errors +$doExpensiveQueries: Whether to do expensive DB queries +$short: Whether to return immediately on first error + 'TitleReadWhitelist': Called at the end of read permissions checks, just before adding the default error message if nothing allows the user to read the page. If a handler wants a title to *not* be whitelisted, it should also return false. @@ -2948,16 +3025,16 @@ $title: Title object of the page that we're about to undelete $title: title object related to the revision $rev: revision (object) that will be viewed -'UnknownAction': An unknown "action" has occurred (useful for defining your own -actions). -$action: action name -$article: article "acted on" - 'UnitTestsList': Called when building a list of paths containing PHPUnit tests. Since 1.24: Paths pointing to a directory will be recursively scanned for test case files matching the suffix "Test.php". &$paths: list of test cases and directories to search. +'UnknownAction': An unknown "action" has occurred (useful for defining your own +actions). +$action: action name +$article: article "acted on" + 'UnwatchArticle': Before a watch is removed from an article. $user: user watching $page: WikiPage object to be removed @@ -2970,10 +3047,13 @@ $page: WikiPage object that was watched 'UpdateUserMailerFormattedPageStatus': Before notification email gets sent. $formattedPageStatus: list of valid page states -'UploadForm:initial': Before the upload form is generated. You might set the -member-variables $uploadFormTextTop and $uploadFormTextAfterSummary to inject -text (HTML) either before or after the editform. -$form: UploadForm object +'UploadComplete': Upon completion of a file upload. +$uploadBase: UploadBase (or subclass) object. File can be accessed by + $uploadBase->getLocalFile(). + +'UploadCreateFromRequest': When UploadBase::createFromRequest has been called. +$type: (string) the requested upload type +&$className: the class name of the Upload instance to be created 'UploadForm:BeforeProcessing': At the beginning of processUpload(). Lets you poke at member variables like $mUploadDescription before the file is saved. Do @@ -2982,12 +3062,10 @@ blank form with no error message; use UploadVerification and UploadVerifyFile instead. $form: UploadForm object -'UploadCreateFromRequest': When UploadBase::createFromRequest has been called. -$type: (string) the requested upload type -&$className: the class name of the Upload instance to be created - -'UploadComplete': when Upload completes an upload. -&$upload: an UploadBase child instance +'UploadForm:initial': Before the upload form is generated. You might set the +member-variables $uploadFormTextTop and $uploadFormTextAfterSummary to inject +text (HTML) either before or after the editform. +$form: UploadForm object 'UploadFormInitDescriptor': After the descriptor for the upload form as been assembled. @@ -2999,25 +3077,21 @@ $descriptor: (array) the HTMLForm descriptor 'UploadVerification': Additional chances to reject an uploaded file. Consider using UploadVerifyFile instead. -string $saveName: destination file name -string $tempName: filesystem path to the temporary file for checks -string &$error: output: message key for message to show if upload canceled by +$saveName: (string) destination file name +$tempName: (string) filesystem path to the temporary file for checks +&$error: (string) output: message key for message to show if upload canceled by returning false. May also be an array, where the first element is the message key and the remaining elements are used as parameters to the message. 'UploadVerifyFile': extra file verification, based on MIME type, etc. Preferred in most cases over UploadVerification. -object $upload: an instance of UploadBase, with all info about the upload -string $mime: The uploaded file's MIME type, as detected by MediaWiki. Handlers - will typically only apply for specific MIME types. -object &$error: output: true if the file is valid. Otherwise, an indexed array +$upload: (object) an instance of UploadBase, with all info about the upload +$mime: (string) The uploaded file's MIME type, as detected by MediaWiki. + Handlers will typically only apply for specific MIME types. +&$error: (object) output: true if the file is valid. Otherwise, an indexed array representing the problem with the file, where the first element is the message key and the remaining elements are used as parameters to the message. -'UploadComplete': Upon completion of a file upload. -$uploadBase: UploadBase (or subclass) object. File can be accessed by - $uploadBase->getLocalFile(). - 'User::mailPasswordInternal': before creation and mailing of a user's new temporary password $user: the user who sent the message out @@ -3037,7 +3111,7 @@ $res: database result used to create the object 'userCan': To interrupt/advise the "user can do X to Y article" check. If you want to display an error message, try getUserPermissionsErrors. $title: Title object being checked against -$user : Current user object +$user: Current user object $action: Action being checked $result: Pointer to result returned if hook returns false. If null is returned, userCan checks are continued by internal code. @@ -3078,7 +3152,8 @@ $user: User object &$timestamp: timestamp, change this to override local email authentication timestamp -'UserGetImplicitGroups': DEPRECATED, called in User::getImplicitGroups(). +'UserGetImplicitGroups': DEPRECATED! +Called in User::getImplicitGroups(). &$groups: List of implicit (automatically-assigned) groups 'UserGetLanguageObject': Called when getting user's interface language object. @@ -3148,16 +3223,16 @@ $user: the user object _after_ logout (won't have name, ID, etc.) $inject_html: Any HTML to inject after the "logged out" message. $oldName: name of the user before logout (string) +'UserMailerChangeReturnPath': Called to generate a VERP return address +when UserMailer sends an email, with a bounce handling extension. +$to: Array of MailAddress objects for the recipients +&$returnPath: The return address string + 'UserRemoveGroup': Called when removing a group; return false to override stock group removal. $user: the user object that is to have a group removed &$group: the group to be removed, can be modified -'UserRights': After a user's group memberships are changed. -$user : User object that was changed -$add : Array of strings corresponding to groups added -$remove: Array of strings corresponding to groups removed - 'UserRequiresHTTPS': Called to determine whether a user needs to be switched to HTTPS. $user: User in question. @@ -3178,13 +3253,18 @@ message(s). $user: user retrieving new talks messages $talks: array of new talks page(s) -'UserSaveSettings': Called when saving user settings. -$user: User object +'UserRights': After a user's group memberships are changed. +$user: User object that was changed +$add: Array of strings corresponding to groups added +$remove: Array of strings corresponding to groups removed 'UserSaveOptions': Called just before saving user preferences/options. $user: User object &$options: Options, modifiable +'UserSaveSettings': Called when saving user settings. +$user: User object + 'UserSetCookies': Called when setting user cookies. $user: User object &$session: session array, will be added to $_SESSION @@ -3212,16 +3292,6 @@ invalidated and GetExtendedMetadata hook called again). $timestamp: The timestamp metadata was generated $file: The file the metadata is for -'UserMailerChangeReturnPath': Called to generate a VERP return address -when UserMailer sends an email, with a bounce handling extension. -$to: Array of MailAddress objects for the recipients -&$returnPath: The return address string - -'LoginFormValidErrorMessages': Called in LoginForm when a function gets valid error -messages. Allows to add additional error messages (except messages already in -LoginForm::$validErrorMessages). -&$messages Already added messages (inclusive messages from LoginForm::$validErrorMessages) - 'WantedPages::getQueryInfo': Called in WantedPagesPage::getQueryInfo(), can be used to alter the SQL query which gets the list of wanted pages. &$wantedPages: WantedPagesPage object @@ -3260,6 +3330,17 @@ Return false to prevent setting of the cookie. &$expire: Cookie expiration, as for PHP's setcookie() $options: Options passed to WebResponse::setcookie() +'wfShellWikiCmd': Called when generating a shell-escaped command line string to +run a MediaWiki cli script. +&$script: MediaWiki cli script path +&$parameters: Array of arguments and options to the script +&$options: Associative array of options, may contain the 'php' and 'wrapper' + keys + +'wgQueryPages': Called when initialising list of QueryPage subclasses, use this +to add new query pages to be updated with maintenance/updateSpecialPages.php. +$qp: The list of QueryPages + 'WhatLinksHereProps': Allows annotations to be added to WhatLinksHere $row: The DB row of the entry. $title: The Title of the page where the link comes FROM @@ -3280,17 +3361,6 @@ $page: the WikiPage $content: the Content to generate updates for &$updates: the array of DataUpdate objects. Hook function may want to add to it. -'wfShellWikiCmd': Called when generating a shell-escaped command line string to -run a MediaWiki cli script. -&$script: MediaWiki cli script path -&$parameters: Array of arguments and options to the script -&$options: Associative array of options, may contain the 'php' and 'wrapper' - keys - -'wgQueryPages': Called when initialising list of QueryPage subclasses, use this -to add new query pages to be updated with maintenance/updateSpecialPages.php. -$qp: The list of QueryPages - 'XmlDumpWriterOpenPage': Called at the end of XmlDumpWriter::openPage, to allow extra metadata to be added. $obj: The XmlDumpWriter object. diff --git a/docs/linkcache.txt b/docs/linkcache.txt index 266f200d48..13b6961356 100644 --- a/docs/linkcache.txt +++ b/docs/linkcache.txt @@ -21,4 +21,4 @@ foreach( $pages as $page ){ } $batch = new LinkBatch( $titles ); -$batch->execute(); \ No newline at end of file +$batch->execute(); diff --git a/docs/memcached.txt b/docs/memcached.txt index d18b199e26..ad2307fda0 100644 --- a/docs/memcached.txt +++ b/docs/memcached.txt @@ -152,7 +152,6 @@ Newtalk: Parser Cache: stored in: $parserMemc - controlled by: $wgEnableParserCache key: $wgDBname:pcache:idhash:$pageid-$renderkey!$hash $pageid: id of the page $renderkey: 1 if action=render, 0 otherwise diff --git a/docs/scripts.txt b/docs/scripts.txt index 178bb157bb..53dff36e42 100644 --- a/docs/scripts.txt +++ b/docs/scripts.txt @@ -49,7 +49,4 @@ Primary scripts: There is also a file with a .php5 extension for each script. They can be used if the web server needs a .php5 to run the file with the PHP 5 engine and runs .php -scripts with PHP 4. To use these files, you have to modify $wgScriptExtension to -'.php5' is LocalSettings.php but it is already done by the config script if you -used mw-config/index.php5 for installation. - +scripts with PHP 4. You should not use them anymore. diff --git a/docs/sitelist.txt b/docs/sitelist.txt index 48c7ce522a..24e1b9a7f5 100644 --- a/docs/sitelist.txt +++ b/docs/sitelist.txt @@ -44,4 +44,4 @@ The XML elements are used as follows: ** link: Generic URL template, often the document root. ** page_path: (for mediawiki sites) URL template for wiki pages (corresponds to the target wiki's $wgArticlePath setting) ** file_path: (for mediawiki sites) URL pattern for application entry points and resources (corresponds to the target wiki's $wgScriptPath setting). -* forward: Whether using a prefix defined by a localid tag in the URL will cause the request to be redirected to the corresponding page on the target wiki (currently unused). E.g. whether http://wiki.acme.com/wiki/foo:Buzz should be forwarded to http://wiki.foo.com/read/Buzz. (CAVEAT: not yet implement, can be specified but has no effect) \ No newline at end of file +* forward: Whether using a prefix defined by a localid tag in the URL will cause the request to be redirected to the corresponding page on the target wiki (currently unused). E.g. whether http://wiki.acme.com/wiki/foo:Buzz should be forwarded to http://wiki.foo.com/read/Buzz. (CAVEAT: not yet implement, can be specified but has no effect) diff --git a/img_auth.php b/img_auth.php index 22fd401452..885914171c 100644 --- a/img_auth.php +++ b/img_auth.php @@ -46,11 +46,9 @@ $wgArticlePath = false; # Don't let a "/*" article path clober our action path $wgActionPaths = array( "$wgUploadPath/" ); wfImageAuthMain(); -wfLogProfilingData(); -// Commit and close up! -$factory = wfGetLBFactory(); -$factory->commitMasterChanges(); -$factory->shutdown(); + +$mediawiki = new MediaWiki(); +$mediawiki->doPostOutputShutdown( 'fast' ); function wfImageAuthMain() { global $wgImgAuthUrlPathMap; @@ -197,7 +195,7 @@ function wfForbidden( $msg1, $msg2 ) { wfMessage( $msg2, $args )->inLanguage( 'en' )->text() ); - header( 'HTTP/1.0 403 Forbidden' ); + HttpStatus::header( 403 ); header( 'Cache-Control: no-cache' ); header( 'Content-Type: text/html; charset=utf-8' ); echo <<func_name, $this->args ); if ( $result === false || $result === null ) { - wfDebug( __METHOD__ . ' ERROR while dispatching ' - . $this->func_name . "(" . var_export( $this->args, true ) . "): " - . "no data returned\n" ); + wfDebug( __METHOD__ . ' ERROR while dispatching ' . + $this->func_name . "(" . var_export( $this->args, true ) . "): " . + "no data returned\n" ); wfHttpError( 500, 'Internal Error', "{$this->func_name} returned no data" ); @@ -141,9 +141,9 @@ class AjaxDispatcher { wfDebug( __METHOD__ . ' dispatch complete for ' . $this->func_name . "\n" ); } } catch ( Exception $e ) { - wfDebug( __METHOD__ . ' ERROR while dispatching ' - . $this->func_name . "(" . var_export( $this->args, true ) . "): " - . get_class( $e ) . ": " . $e->getMessage() . "\n" ); + wfDebug( __METHOD__ . ' ERROR while dispatching ' . + $this->func_name . "(" . var_export( $this->args, true ) . "): " . + get_class( $e ) . ": " . $e->getMessage() . "\n" ); if ( !headers_sent() ) { wfHttpError( 500, 'Internal Error', diff --git a/includes/AjaxResponse.php b/includes/AjaxResponse.php index 8e9f490fa2..6c2efc296a 100644 --- a/includes/AjaxResponse.php +++ b/includes/AjaxResponse.php @@ -86,7 +86,7 @@ class AjaxResponse { $this->mDisabled = false; $this->mText = ''; - $this->mResponseCode = '200 OK'; + $this->mResponseCode = 200; $this->mLastModified = false; $this->mContentType = 'application/x-wiki'; @@ -158,16 +158,20 @@ class AjaxResponse { */ function sendHeaders() { if ( $this->mResponseCode ) { - $n = preg_replace( '/^ *(\d+)/', '\1', $this->mResponseCode ); - header( "Status: " . $this->mResponseCode, true, (int)$n ); + // For back-compat, it is supported that mResponseCode be a string like " 200 OK" + // (with leading space and the status message after). Cast response code to an integer + // to take advantage of PHP's conversion rules which will turn " 200 OK" into 200. + // http://php.net/string#language.types.string.conversion + $n = intval( trim( $this->mResponseCode ) ); + HttpStatus::header( $n ); } - header ( "Content-Type: " . $this->mContentType ); + header( "Content-Type: " . $this->mContentType ); if ( $this->mLastModified ) { - header ( "Last-Modified: " . $this->mLastModified ); + header( "Last-Modified: " . $this->mLastModified ); } else { - header ( "Last-Modified: " . gmdate( "D, d M Y H:i:s" ) . " GMT" ); + header( "Last-Modified: " . gmdate( "D, d M Y H:i:s" ) . " GMT" ); } if ( $this->mCacheDuration ) { @@ -189,20 +193,20 @@ class AjaxResponse { } else { # Let the client do the caching. Cache is not purged. - header ( "Expires: " . gmdate( "D, d M Y H:i:s", time() + $this->mCacheDuration ) . " GMT" ); - header ( "Cache-Control: s-maxage={$this->mCacheDuration}," . + header( "Expires: " . gmdate( "D, d M Y H:i:s", time() + $this->mCacheDuration ) . " GMT" ); + header( "Cache-Control: s-maxage={$this->mCacheDuration}," . "public,max-age={$this->mCacheDuration}" ); } } else { # always expired, always modified - header ( "Expires: Mon, 26 Jul 1997 05:00:00 GMT" ); // Date in the past - header ( "Cache-Control: no-cache, must-revalidate" ); // HTTP/1.1 - header ( "Pragma: no-cache" ); // HTTP/1.0 + header( "Expires: Mon, 26 Jul 1997 05:00:00 GMT" ); // Date in the past + header( "Cache-Control: no-cache, must-revalidate" ); // HTTP/1.1 + header( "Pragma: no-cache" ); // HTTP/1.0 } if ( $this->mVary ) { - header ( "Vary: " . $this->mVary ); + header( "Vary: " . $this->mVary ); } } @@ -246,7 +250,7 @@ class AjaxResponse { $ismodsince >= $wgCacheEpoch ) { ini_set( 'zlib.output_compression', 0 ); - $this->setResponseCode( "304 Not Modified" ); + $this->setResponseCode( 304 ); $this->disable(); $this->mLastModified = $lastmod; diff --git a/includes/Block.php b/includes/Block.php index d58220144a..c5a16fcea6 100644 --- a/includes/Block.php +++ b/includes/Block.php @@ -23,15 +23,16 @@ class Block { /** @var string */ public $mReason; - /** @var bool|string */ + /** @var string */ public $mTimestamp; - /** @var int */ + /** @var bool */ public $mAuto; - /** @var bool|string */ + /** @var string */ public $mExpiry; + /** @var bool */ public $mHideName; /** @var int */ @@ -65,10 +66,10 @@ class Block { protected $blocker; /** @var bool */ - protected $isHardblock = true; + protected $isHardblock; /** @var bool */ - protected $isAutoblocking = true; + protected $isAutoblocking; # TYPE constants const TYPE_USER = 1; @@ -78,55 +79,84 @@ class Block { const TYPE_ID = 5; /** - * @todo FIXME: Don't know what the best format to have for this constructor - * is, but fourteen optional parameters certainly isn't it. - * @param string $address - * @param int $user - * @param int $by - * @param string $reason - * @param mixed $timestamp - * @param int $auto - * @param string $expiry - * @param int $anonOnly - * @param int $createAccount - * @param int $enableAutoblock - * @param int $hideName - * @param int $blockEmail - * @param int $allowUsertalk - * @param string $byText + * Create a new block with specified parameters on a user, IP or IP range. + * + * @param array $options Parameters of the block: + * address string|User Target user name, User object, IP address or IP range + * user int Override target user ID (for foreign users) + * by int User ID of the blocker + * reason string Reason of the block + * timestamp string The time at which the block comes into effect + * auto bool Is this an automatic block? + * expiry string Timestamp of expiration of the block or 'infinity' + * anonOnly bool Only disallow anonymous actions + * createAccount bool Disallow creation of new accounts + * enableAutoblock bool Enable automatic blocking + * hideName bool Hide the target user name + * blockEmail bool Disallow sending emails + * allowUsertalk bool Allow the target to edit its own talk page + * byText string Username of the blocker (for foreign users) + * + * @since 1.26 accepts $options array instead of individual parameters; order + * of parameters above reflects the original order */ - function __construct( $address = '', $user = 0, $by = 0, $reason = '', - $timestamp = 0, $auto = 0, $expiry = '', $anonOnly = 0, $createAccount = 0, $enableAutoblock = 0, - $hideName = 0, $blockEmail = 0, $allowUsertalk = 0, $byText = '' - ) { - if ( $timestamp === 0 ) { - $timestamp = wfTimestampNow(); - } + function __construct( $options = array() ) { + $defaults = array( + 'address' => '', + 'user' => null, + 'by' => null, + 'reason' => '', + 'timestamp' => '', + 'auto' => false, + 'expiry' => '', + 'anonOnly' => false, + 'createAccount' => false, + 'enableAutoblock' => false, + 'hideName' => false, + 'blockEmail' => false, + 'allowUsertalk' => false, + 'byText' => '', + ); - if ( count( func_get_args() ) > 0 ) { - # Soon... :D - # wfDeprecated( __METHOD__ . " with arguments" ); + if ( func_num_args() > 1 || !is_array( $options ) ) { + $options = array_combine( + array_slice( array_keys( $defaults ), 0, func_num_args() ), + func_get_args() + ); + wfDeprecated( __METHOD__ . ' with multiple arguments', '1.26' ); } - $this->setTarget( $address ); - if ( $this->target instanceof User && $user ) { - $this->forcedTargetID = $user; // needed for foreign users + $options += $defaults; + + $this->setTarget( $options['address'] ); + + if ( $this->target instanceof User && $options['user'] ) { + # Needed for foreign users + $this->forcedTargetID = $options['user']; } - if ( $by ) { // local user - $this->setBlocker( User::newFromId( $by ) ); - } else { // foreign user - $this->setBlocker( $byText ); + + if ( $options['by'] ) { + # Local user + $this->setBlocker( User::newFromID( $options['by'] ) ); + } else { + # Foreign user + $this->setBlocker( $options['byText'] ); } - $this->mReason = $reason; - $this->mTimestamp = wfTimestamp( TS_MW, $timestamp ); - $this->mAuto = $auto; - $this->isHardblock( !$anonOnly ); - $this->prevents( 'createaccount', $createAccount ); - $this->mExpiry = wfGetDB( DB_SLAVE )->decodeExpiry( $expiry ); - $this->isAutoblocking( $enableAutoblock ); - $this->mHideName = $hideName; - $this->prevents( 'sendemail', $blockEmail ); - $this->prevents( 'editownusertalk', !$allowUsertalk ); + + $this->mReason = $options['reason']; + $this->mTimestamp = wfTimestamp( TS_MW, $options['timestamp'] ); + $this->mExpiry = wfGetDB( DB_SLAVE )->decodeExpiry( $options['expiry'] ); + + # Boolean settings + $this->mAuto = (bool)$options['auto']; + $this->mHideName = (bool)$options['hideName']; + $this->isHardblock( !$options['anonOnly'] ); + $this->isAutoblocking( (bool)$options['enableAutoblock'] ); + + # Prevention measures + $this->prevents( 'sendemail', (bool)$options['blockEmail'] ); + $this->prevents( 'editownusertalk', !$options['allowUsertalk'] ); + $this->prevents( 'createaccount', (bool)$options['createAccount'] ); $this->mFromMaster = false; } @@ -1109,7 +1139,7 @@ class Block { $blocks = array(); foreach ( $rows as $row ) { $block = self::newFromRow( $row ); - if ( !$block->deleteIfExpired() ) { + if ( !$block->deleteIfExpired() ) { $blocks[] = $block; } } diff --git a/includes/CategoryViewer.php b/includes/CategoryViewer.php index 66079c0179..e2c31a66ff 100644 --- a/includes/CategoryViewer.php +++ b/includes/CategoryViewer.php @@ -329,7 +329,7 @@ class CategoryViewer extends ContextSource { 'category' => array( 'LEFT JOIN', array( 'cat_title = page_title', 'page_namespace' => NS_CATEGORY - )) + ) ) ) ); diff --git a/includes/Collation.php b/includes/Collation.php index 481d8e7034..c1f0b3881a 100644 --- a/includes/Collation.php +++ b/includes/Collation.php @@ -320,16 +320,16 @@ class IcuCollation extends Collation { // intl extension produces non null-terminated // strings. Appending '' fixes it so that it doesn't generate // a warning on each access in debug php. - wfSuppressWarnings(); + MediaWiki\suppressWarnings(); $key = $this->mainCollator->getSortKey( $string ) . ''; - wfRestoreWarnings(); + MediaWiki\restoreWarnings(); return $key; } function getPrimarySortKey( $string ) { - wfSuppressWarnings(); + MediaWiki\suppressWarnings(); $key = $this->primaryCollator->getSortKey( $string ) . ''; - wfRestoreWarnings(); + MediaWiki\restoreWarnings(); return $key; } diff --git a/includes/DefaultSettings.php b/includes/DefaultSettings.php index 2ea8b294b6..45102ee245 100644 --- a/includes/DefaultSettings.php +++ b/includes/DefaultSettings.php @@ -82,6 +82,14 @@ $wgVersion = '1.26alpha'; */ $wgSitename = 'MediaWiki'; +/** + * When the wiki is running behind a proxy and this is set to true, assumes that the proxy exposes + * the wiki on the standard ports (443 for https and 80 for http). + * @var bool + * @since 1.26 + */ +$wgAssumeProxiesUseDefaultProtocolPorts = true; + /** * URL of the server. * @@ -472,13 +480,13 @@ $wgImgAuthUrlPathMap = array(); * * These settings describe a foreign MediaWiki installation. They are optional, and will be ignored * for local repositories: - * - descBaseUrl URL of image description pages, e.g. http://en.wikipedia.org/wiki/File: + * - descBaseUrl URL of image description pages, e.g. https://en.wikipedia.org/wiki/File: * - scriptDirUrl URL of the MediaWiki installation, equivalent to $wgScriptPath, e.g. - * http://en.wikipedia.org/w + * https://en.wikipedia.org/w * - scriptExtension Script extension of the MediaWiki installation, equivalent to * $wgScriptExtension, e.g. .php5 defaults to .php * - * - articleUrl Equivalent to $wgArticlePath, e.g. http://en.wikipedia.org/wiki/$1 + * - articleUrl Equivalent to $wgArticlePath, e.g. https://en.wikipedia.org/wiki/$1 * - fetchDescription Fetch the text of the remote file description page. Equivalent to * $wgFetchCommonsDescriptions. * - abbrvThreshold File names over this size will use the short form of thumbnail names. @@ -709,7 +717,7 @@ $wgMaxUploadSize = 1024 * 1024 * 100; # 100MB * * @par Example: * @code - * $wgUploadNavigationUrl = 'http://commons.wikimedia.org/wiki/Special:Upload'; + * $wgUploadNavigationUrl = 'https://commons.wikimedia.org/wiki/Special:Upload'; * @endcode */ $wgUploadNavigationUrl = false; @@ -769,7 +777,7 @@ $wgHashedSharedUploadDirectory = true; * * Please specify the namespace, as in the example below. */ -$wgRepositoryBaseUrl = "http://commons.wikimedia.org/wiki/File:"; +$wgRepositoryBaseUrl = "https://commons.wikimedia.org/wiki/File:"; /** * This is the list of preferred extensions for uploading files. Uploading files @@ -970,6 +978,14 @@ $wgJpegTran = '/usr/bin/jpegtran'; */ $wgExiv2Command = '/usr/bin/exiv2'; + +/** + * Path to exiftool binary. Used for lossless ICC profile swapping. + * + * @since 1.26 + */ +$wgExiftool = '/usr/bin/exiftool'; + /** * Scalable Vector Graphics (SVG) may be uploaded as images. * Since SVG support is not yet standard in browsers, it is @@ -1322,6 +1338,14 @@ $wgUploadThumbnailRenderHttpCustomHost = false; */ $wgUploadThumbnailRenderHttpCustomDomain = false; +/** + * When this variable is true and JPGs use the sRGB ICC profile, swaps it for the more lightweight + * (and free) TinyRGB profile when generating thumbnails. + * + * @since 1.26 + */ +$wgUseTinyRGBForJPGThumbnails = false; + /** * Default parameters for the "" tag */ @@ -2297,11 +2321,13 @@ $wgAdaptiveMessageCache = false; * Localisation cache configuration. Associative array with keys: * class: The class to use. May be overridden by extensions. * - * store: The location to store cache data. May be 'files', 'db' or + * store: The location to store cache data. May be 'files', 'array', 'db' or * 'detect'. If set to "files", data will be in CDB files. If set * to "db", data will be stored to the database. If set to * "detect", files will be used if $wgCacheDirectory is set, * otherwise the database will be used. + * "array" is an experimental option that uses PHP files that + * store static arrays. * * storeClass: The class name for the underlying storage. If set to a class * name, it overrides the "store" setting. @@ -2369,13 +2395,8 @@ $wgUseFileCache = false; $wgFileCacheDepth = 2; /** - * Keep parsed pages in a cache (objectcache table or memcached) - * to speed up output of the same page viewed by another user with the - * same options. - * - * This can provide a significant speedup for medium to large pages, - * so you probably want to keep it on. Extensions that conflict with the - * parser cache should disable the cache on a per-page basis instead. + * Kept for extension compatibility; see $wgParserCacheType + * @deprecated 1.26 */ $wgEnableParserCache = true; @@ -2800,14 +2821,14 @@ $wgBrowserBlackList = array( * - Mozilla/4.0 (compatible; MSIE 5.23; Mac_PowerPC) * - [...] * - * @link http://en.wikipedia.org/w/index.php?diff=12356041&oldid=12355864 - * @link http://en.wikipedia.org/wiki/Template%3AOS9 + * @link https://en.wikipedia.org/w/index.php?diff=12356041&oldid=12355864 + * @link https://en.wikipedia.org/wiki/Template%3AOS9 */ '/^Mozilla\/4\.0 \(compatible; MSIE \d+\.\d+; Mac_PowerPC\)/', /** * Google wireless transcoder, seems to eat a lot of chars alive - * http://it.wikipedia.org/w/index.php?title=Luciano_Ligabue&diff=prev&oldid=8857361 + * https://it.wikipedia.org/w/index.php?title=Luciano_Ligabue&diff=prev&oldid=8857361 */ '/^Mozilla\/4\.0 \(compatible; MSIE 6.0; Windows NT 5.0; Google Wireless Transcoder;\)/' ); @@ -4255,6 +4276,59 @@ $wgActiveUserDays = 30; * @{ */ +/** + * Password policy for local wiki users. A user's effective policy + * is the superset of all policy statements from the policies for the + * groups where the user is a member. If more than one group policy + * include the same policy statement, the value is the max() of the + * values. Note true > false. The 'default' policy group is required, + * and serves as the minimum policy for all users. New statements can + * be added by appending to $wgPasswordPolicy['checks']. + * Statements: + * - MinimalPasswordLength - minimum length a user can set + * - MinimumPasswordLengthToLogin - passwords shorter than this will + * not be allowed to login, regardless if it is correct. + * - MaximalPasswordLength - maximum length password a user is allowed + * to attempt. Prevents DoS attacks with pbkdf2. + * - PasswordCannotMatchUsername - Password cannot match username to + * - PasswordCannotMatchBlacklist - Username/password combination cannot + * match a specific, hardcoded blacklist. + * @since 1.26 + */ +$wgPasswordPolicy = array( + 'policies' => array( + 'bureaucrat' => array( + 'MinimalPasswordLength' => 8, + 'MinimumPasswordLengthToLogin' => 1, + 'PasswordCannotMatchUsername' => true, + ), + 'sysop' => array( + 'MinimalPasswordLength' => 8, + 'MinimumPasswordLengthToLogin' => 1, + 'PasswordCannotMatchUsername' => true, + ), + 'bot' => array( + 'MinimalPasswordLength' => 8, + 'MinimumPasswordLengthToLogin' => 1, + 'PasswordCannotMatchUsername' => true, + ), + 'default' => array( + 'MinimalPasswordLength' => 1, + 'PasswordCannotMatchUsername' => true, + 'PasswordCannotMatchBlacklist' => true, + 'MaximalPasswordLength' => 4096, + ), + ), + 'checks' => array( + 'MinimalPasswordLength' => 'PasswordPolicyChecks::checkMinimalPasswordLength', + 'MinimumPasswordLengthToLogin' => 'PasswordPolicyChecks::checkMinimumPasswordLengthToLogin', + 'PasswordCannotMatchUsername' => 'PasswordPolicyChecks::checkPasswordCannotMatchUsername', + 'PasswordCannotMatchBlacklist' => 'PasswordPolicyChecks::checkPasswordCannotMatchBlacklist', + 'MaximalPasswordLength' => 'PasswordPolicyChecks::checkMaximalPasswordLength', + ), +); + + /** * For compatibility with old installations set to false * @deprecated since 1.24 will be removed in future @@ -4264,8 +4338,9 @@ $wgPasswordSalt = true; /** * Specifies the minimal length of a user password. If set to 0, empty pass- * words are allowed. + * @deprecated since 1.26, use $wgPasswordPolicy's MinimalPasswordLength. */ -$wgMinimalPasswordLength = 1; +$wgMinimalPasswordLength = false; /** * Specifies the maximal length of a user password (T64685). @@ -4276,8 +4351,9 @@ $wgMinimalPasswordLength = 1; * * @warning Unlike other password settings, user with passwords greater than * the maximum will not be able to log in. + * @deprecated since 1.26, use $wgPasswordPolicy's MaximalPasswordLength. */ -$wgMaximalPasswordLength = 4096; +$wgMaximalPasswordLength = false; /** * Specifies if users should be sent to a password-reset form on login, if their @@ -4472,7 +4548,7 @@ $wgUserrightsInterwikiDelimiter = '@'; /** * This is to let user authenticate using https when they come from http. * Based on an idea by George Herbert on wikitech-l: - * http://lists.wikimedia.org/pipermail/wikitech-l/2010-October/050039.html + * https://lists.wikimedia.org/pipermail/wikitech-l/2010-October/050039.html * @since 1.17 */ $wgSecureLogin = false; @@ -4999,7 +5075,7 @@ $wgAccountCreationThrottle = 0; * There's no administrator override on-wiki, so be careful what you set. :) * May be an array of regexes or a single string for backwards compatibility. * - * @see http://en.wikipedia.org/wiki/Regular_expression + * @see https://en.wikipedia.org/wiki/Regular_expression * * @note Each regex needs a beginning/end delimiter, eg: # or / */ @@ -5197,6 +5273,22 @@ $wgProxyList = array(); */ $wgCookieExpiration = 180 * 86400; +/** + * The identifiers of the login cookies that can have their lifetimes + * extended independently of all other login cookies. + * + * @var string[] + */ +$wgExtendedLoginCookies = array( 'UserID', 'Token' ); + +/** + * Default login cookie lifetime, in seconds. Setting + * $wgExtendLoginCookieExpiration to null will use $wgCookieExpiration to + * calculate the cookie lifetime. As with $wgCookieExpiration, 0 will make + * login cookies session-only. + */ +$wgExtendedLoginCookieExpiration = null; + /** * Set to set an explicit domain on the login cookies eg, "justthis.domain.org" * or ".any.subdomain.net" @@ -5530,7 +5622,7 @@ $wgProfilePerHost = null; * * The host should be running a daemon which can be obtained from MediaWiki * Git at: - * http://git.wikimedia.org/tree/operations%2Fsoftware.git/master/udpprofile + * https://git.wikimedia.org/tree/operations%2Fsoftware.git/master/udpprofile * * @deprecated set $wgProfiler['udphost'] instead */ diff --git a/includes/EditPage.php b/includes/EditPage.php index e88baafe56..3600fb221a 100644 --- a/includes/EditPage.php +++ b/includes/EditPage.php @@ -167,6 +167,12 @@ class EditPage { */ const AS_PARSE_ERROR = 240; + /** + * Status: when changing the content model is disallowed due to + * $wgContentHandlerUseDB being false + */ + const AS_CANNOT_USE_CUSTOM_MODEL = 241; + /** * HTML id and name for the beginning of the edit form. */ @@ -1037,7 +1043,6 @@ class EditPage { $undo = $wgRequest->getInt( 'undo' ); if ( $undo > 0 && $undoafter > 0 ) { - $undorev = Revision::newFromId( $undo ); $oldrev = Revision::newFromId( $undoafter ); @@ -1046,8 +1051,8 @@ class EditPage { # Otherwise, $content will be left as-is. if ( !is_null( $undorev ) && !is_null( $oldrev ) && !$undorev->isDeleted( Revision::DELETED_TEXT ) && - !$oldrev->isDeleted( Revision::DELETED_TEXT ) ) { - + !$oldrev->isDeleted( Revision::DELETED_TEXT ) + ) { $content = $this->mArticle->getUndoContent( $undorev, $oldrev ); if ( $content === false ) { @@ -1242,9 +1247,9 @@ class EditPage { if ( !$converted ) { //TODO: somehow show a warning to the user! - wfDebug( "Attempt to preload incompatible content: " - . "can't convert " . $content->getModel() - . " to " . $handler->getModelID() ); + wfDebug( "Attempt to preload incompatible content: " . + "can't convert " . $content->getModel() . + " to " . $handler->getModelID() ); return $handler->makeEmptyContent(); } @@ -1362,6 +1367,7 @@ class EditPage { case self::AS_HOOK_ERROR: return false; + case self::AS_CANNOT_USE_CUSTOM_MODEL: case self::AS_PARSE_ERROR: $wgOut->addWikiText( '
    ' . $status->getWikiText() . '
    ' ); return true; @@ -1544,6 +1550,7 @@ class EditPage { */ function internalAttemptSave( &$result, $bot = false ) { global $wgUser, $wgRequest, $wgParser, $wgMaxArticleSize; + global $wgContentHandlerUseDB; $status = Status::newGood(); @@ -1664,11 +1671,15 @@ class EditPage { } } - if ( $this->contentModel !== $this->mTitle->getContentModel() - && !$wgUser->isAllowed( 'editcontentmodel' ) - ) { - $status->setResult( false, self::AS_NO_CHANGE_CONTENT_MODEL ); - return $status; + if ( $this->contentModel !== $this->mTitle->getContentModel() ) { + if ( !$wgContentHandlerUseDB ) { + $status->fatal( 'editpage-cannot-use-custom-model' ); + $status->value = self::AS_CANNOT_USE_CUSTOM_MODEL; + return $status; + } elseif ( !$wgUser->isAllowed( 'editcontentmodel' ) ) { + $status->setResult( false, self::AS_NO_CHANGE_CONTENT_MODEL ); + return $status; + } } if ( $this->changeTags ) { @@ -3464,6 +3475,8 @@ HTML global $wgOut, $wgUser, $wgRawHtml, $wgLang; global $wgAllowUserCss, $wgAllowUserJs; + $stats = $wgOut->getContext()->getStats(); + if ( $wgRawHtml && !$this->mTokenOk ) { // Could be an offsite preview attempt. This is very unsafe if // HTML is enabled, as it could be an attack. @@ -3475,6 +3488,7 @@ HTML $parsedNote = $wgOut->parse( "
    " . wfMessage( 'session_fail_preview_html' )->text() . "
    ", true, /* interface */true ); } + $stats->increment( 'edit.failures.session_loss' ); return $parsedNote; } @@ -3498,11 +3512,16 @@ HTML if ( $this->mTriedSave && !$this->mTokenOk ) { if ( $this->mTokenOkExceptSuffix ) { $note = wfMessage( 'token_suffix_mismatch' )->plain(); + $stats->increment( 'edit.failures.bad_token' ); } else { $note = wfMessage( 'session_fail_preview' )->plain(); + $stats->increment( 'edit.failures.session_loss' ); } } elseif ( $this->incompleteForm ) { $note = wfMessage( 'edit_form_incomplete' )->plain(); + if ( $this->mTriedSave ) { + $stats->increment( 'edit.failures.incomplete_form' ); + } } else { $note = wfMessage( 'previewnote' )->plain() . ' ' . $continueEditing; } diff --git a/includes/Export.php b/includes/Export.php index 4600feb5ad..0d55d7dbc1 100644 --- a/includes/Export.php +++ b/includes/Export.php @@ -1191,7 +1191,7 @@ class Dump7ZipOutput extends DumpPipeOutput { * @return string */ function setup7zCommand( $file ) { - $command = "7za a -bd -si " . wfEscapeShellArg( $file ); + $command = "7za a -bd -si -mx=4 " . wfEscapeShellArg( $file ); // Suppress annoying useless crap from p7zip // Unfortunately this could suppress real error messages too $command .= ' >' . wfGetNull() . ' 2>&1'; diff --git a/includes/FileDeleteForm.php b/includes/FileDeleteForm.php index 6d74af2da1..bcd6db2026 100644 --- a/includes/FileDeleteForm.php +++ b/includes/FileDeleteForm.php @@ -297,7 +297,7 @@ class FileDeleteForm { if ( $wgUser->isAllowed( 'editinterface' ) ) { $title = wfMessage( 'filedelete-reason-dropdown' )->inContentLanguage()->getTitle(); - $link = Linker::link( + $link = Linker::linkKnown( $title, wfMessage( 'filedelete-edit-reasonlist' )->escaped(), array(), diff --git a/includes/GitInfo.php b/includes/GitInfo.php index fb298cfeed..7f05bb0fd7 100644 --- a/includes/GitInfo.php +++ b/includes/GitInfo.php @@ -281,9 +281,9 @@ class GitInfo { $config = "{$this->basedir}/config"; $url = false; if ( is_readable( $config ) ) { - wfSuppressWarnings(); + MediaWiki\suppressWarnings(); $configArray = parse_ini_file( $config, true ); - wfRestoreWarnings(); + MediaWiki\restoreWarnings(); $remote = false; // Use the "origin" remote repo if available or any other repo if not. diff --git a/includes/GlobalFunctions.php b/includes/GlobalFunctions.php index 8b3b959a36..c6184261e7 100644 --- a/includes/GlobalFunctions.php +++ b/includes/GlobalFunctions.php @@ -860,9 +860,9 @@ function wfParseUrl( $url ) { if ( $wasRelative ) { $url = "http:$url"; } - wfSuppressWarnings(); + MediaWiki\suppressWarnings(); $bits = parse_url( $url ); - wfRestoreWarnings(); + MediaWiki\restoreWarnings(); // parse_url() returns an array without scheme for some invalid URLs, e.g. // parse_url("%0Ahttp://example.com") == array( 'host' => '%0Ahttp', 'path' => 'example.com' ) if ( !$bits || !isset( $bits['scheme'] ) ) { @@ -1756,7 +1756,7 @@ function wfMsgExt( $key, $options ) { } if ( in_array( 'escape', $options, true ) ) { - $string = htmlspecialchars ( $string ); + $string = htmlspecialchars( $string ); } elseif ( in_array( 'escapenoentities', $options, true ) ) { $string = Sanitizer::escapeHtmlAllowEntities( $string ); } @@ -2129,15 +2129,14 @@ function wfVarDump( $var ) { */ function wfHttpError( $code, $label, $desc ) { global $wgOut; - header( "HTTP/1.0 $code $label" ); - header( "Status: $code $label" ); + HttpStatus::header( $code ); if ( $wgOut ) { $wgOut->disable(); $wgOut->sendCacheControl(); } header( 'Content-type: text/html; charset=utf-8' ); - print "" . + print '' . '' . htmlspecialchars( $label ) . '

    ' . @@ -2323,40 +2322,19 @@ function wfNegotiateType( $cprefs, $sprefs ) { /** * Reference-counted warning suppression * + * @deprecated since 1.26, use MediaWiki\suppressWarnings() directly * @param bool $end */ function wfSuppressWarnings( $end = false ) { - static $suppressCount = 0; - static $originalLevel = false; - - if ( $end ) { - if ( $suppressCount ) { - --$suppressCount; - if ( !$suppressCount ) { - error_reporting( $originalLevel ); - } - } - } else { - if ( !$suppressCount ) { - $originalLevel = error_reporting( E_ALL & ~( - E_WARNING | - E_NOTICE | - E_USER_WARNING | - E_USER_NOTICE | - E_DEPRECATED | - E_USER_DEPRECATED | - E_STRICT - ) ); - } - ++$suppressCount; - } + MediaWiki\suppressWarnings( $end ); } /** + * @deprecated since 1.26, use MediaWiki\restoreWarnings() directly * Restore error level to previous value */ function wfRestoreWarnings() { - wfSuppressWarnings( true ); + MediaWiki\suppressWarnings( true ); } # Autodetect, convert and provide timestamps of various types @@ -2537,9 +2515,9 @@ function wfMkdirParents( $dir, $mode = null, $caller = null ) { } // Turn off the normal warning, we're doing our own below - wfSuppressWarnings(); + MediaWiki\suppressWarnings(); $ok = mkdir( $dir, $mode, true ); // PHP5 <3 - wfRestoreWarnings(); + MediaWiki\restoreWarnings(); if ( !$ok ) { //directory may have been created on another request since we last checked @@ -2780,7 +2758,7 @@ function wfShellExec( $cmd, &$retval = null, $environ = array(), $useLogPipe = false; if ( is_executable( '/bin/bash' ) ) { - $time = intval ( isset( $limits['time'] ) ? $limits['time'] : $wgMaxShellTime ); + $time = intval( isset( $limits['time'] ) ? $limits['time'] : $wgMaxShellTime ); if ( isset( $limits['walltime'] ) ) { $wallTime = intval( $limits['walltime'] ); } elseif ( isset( $limits['time'] ) ) { @@ -2788,8 +2766,8 @@ function wfShellExec( $cmd, &$retval = null, $environ = array(), } else { $wallTime = intval( $wgMaxShellWallClockTime ); } - $mem = intval ( isset( $limits['memory'] ) ? $limits['memory'] : $wgMaxShellMemory ); - $filesize = intval ( isset( $limits['filesize'] ) ? $limits['filesize'] : $wgMaxShellFileSize ); + $mem = intval( isset( $limits['memory'] ) ? $limits['memory'] : $wgMaxShellMemory ); + $filesize = intval( isset( $limits['filesize'] ) ? $limits['filesize'] : $wgMaxShellFileSize ); if ( $time > 0 || $mem > 0 || $filesize > 0 || $wallTime > 0 ) { $cmd = '/bin/bash ' . escapeshellarg( "$IP/includes/limit.sh" ) . ' ' . @@ -3034,9 +3012,9 @@ function wfMerge( $old, $mine, $yours, &$result ) { # This check may also protect against code injection in # case of broken installations. - wfSuppressWarnings(); + MediaWiki\suppressWarnings(); $haveDiff3 = $wgDiff3 && file_exists( $wgDiff3 ); - wfRestoreWarnings(); + MediaWiki\restoreWarnings(); if ( !$haveDiff3 ) { wfDebug( "diff3 not found\n" ); @@ -3113,9 +3091,9 @@ function wfDiff( $before, $after, $params = '-u' ) { } global $wgDiff; - wfSuppressWarnings(); + MediaWiki\suppressWarnings(); $haveDiff = $wgDiff && file_exists( $wgDiff ); - wfRestoreWarnings(); + MediaWiki\restoreWarnings(); # This check may also protect against code injection in # case of broken installations. @@ -3492,9 +3470,9 @@ function wfSetupSession( $sessionId = false ) { } else { wfFixSessionID(); } - wfSuppressWarnings(); + MediaWiki\suppressWarnings(); session_start(); - wfRestoreWarnings(); + MediaWiki\restoreWarnings(); } /** @@ -3517,7 +3495,7 @@ function wfGetPrecompiledData( $name ) { } /** - * Get a cache key + * Make a cache key for the local wiki. * * @param string $args,... * @return string @@ -3532,7 +3510,9 @@ function wfMemcKey( /*...*/ ) { } /** - * Get a cache key for a foreign DB + * Make a cache key for a foreign DB. + * + * Must match what wfMemcKey() would produce in context of the foreign wiki. * * @param string $db * @param string $prefix @@ -3542,6 +3522,7 @@ function wfMemcKey( /*...*/ ) { function wfForeignMemcKey( $db, $prefix /*...*/ ) { $args = array_slice( func_get_args(), 2 ); if ( $prefix ) { + // Match wfWikiID() logic $key = "$db-$prefix:" . implode( ':', $args ); } else { $key = $db . ':' . implode( ':', $args ); @@ -3549,6 +3530,24 @@ function wfForeignMemcKey( $db, $prefix /*...*/ ) { return str_replace( ' ', '_', $key ); } +/** + * Make a cache key with database-agnostic prefix. + * + * Doesn't have a wiki-specific namespace. Uses a generic 'global' prefix + * instead. Must have a prefix as otherwise keys that use a database name + * in the first segment will clash with wfMemcKey/wfForeignMemcKey. + * + * @since 1.26 + * @param string $args,... + * @return string + */ +function wfGlobalCacheKey( /*...*/ ) { + $args = func_get_args(); + $key = 'global:' . implode( ':', $args ); + $key = str_replace( ' ', '_', $key ); + return $key; +} + /** * Get an ASCII string identifying this wiki * This is used as a prefix in memcached keys @@ -3847,15 +3846,15 @@ function wfMemoryLimit() { $conflimit = wfShorthandToInteger( $wgMemoryLimit ); if ( $conflimit == -1 ) { wfDebug( "Removing PHP's memory limit\n" ); - wfSuppressWarnings(); + MediaWiki\suppressWarnings(); ini_set( 'memory_limit', $conflimit ); - wfRestoreWarnings(); + MediaWiki\restoreWarnings(); return $conflimit; } elseif ( $conflimit > $memlimit ) { wfDebug( "Raising PHP's memory limit to $conflimit bytes\n" ); - wfSuppressWarnings(); + MediaWiki\suppressWarnings(); ini_set( 'memory_limit', $conflimit ); - wfRestoreWarnings(); + MediaWiki\restoreWarnings(); return $conflimit; } } @@ -4000,9 +3999,9 @@ function wfUnpack( $format, $data, $length = false ) { } } - wfSuppressWarnings(); + MediaWiki\suppressWarnings(); $result = unpack( $format, $data ); - wfRestoreWarnings(); + MediaWiki\restoreWarnings(); if ( $result === false ) { // If it cannot extract the packed data. diff --git a/includes/HistoryBlob.php b/includes/HistoryBlob.php index 69f1120d43..494cbfaf8f 100644 --- a/includes/HistoryBlob.php +++ b/includes/HistoryBlob.php @@ -522,9 +522,9 @@ class DiffHistoryBlob implements HistoryBlob { function diff( $t1, $t2 ) { # Need to do a null concatenation with warnings off, due to bugs in the current version of xdiff # "String is not zero-terminated" - wfSuppressWarnings(); + MediaWiki\suppressWarnings(); $diff = xdiff_string_rabdiff( $t1, $t2 ) . ''; - wfRestoreWarnings(); + MediaWiki\restoreWarnings(); return $diff; } @@ -535,9 +535,9 @@ class DiffHistoryBlob implements HistoryBlob { */ function patch( $base, $diff ) { if ( function_exists( 'xdiff_string_bpatch' ) ) { - wfSuppressWarnings(); + MediaWiki\suppressWarnings(); $text = xdiff_string_bpatch( $base, $diff ) . ''; - wfRestoreWarnings(); + MediaWiki\restoreWarnings(); return $text; } diff --git a/includes/Hooks.php b/includes/Hooks.php index dffc7bcfe8..036d65c71e 100644 --- a/includes/Hooks.php +++ b/includes/Hooks.php @@ -135,9 +135,6 @@ class Hooks { * returning null) is equivalent to returning true. */ public static function run( $event, array $args = array(), $deprecatedVersion = null ) { - $profiler = Profiler::instance(); - $eventPS = $profiler->scopedProfileIn( 'hook: ' . $event ); - foreach ( self::getHandlers( $event ) as $hook ) { // Turn non-array values into an array. (Can't use casting because of objects.) if ( !is_array( $hook ) ) { @@ -196,8 +193,6 @@ class Hooks { $badhookmsg = null; $hook_args = array_merge( $hook, $args ); - // Profile first in case the Profiler causes errors - $funcPS = $profiler->scopedProfileIn( $func ); set_error_handler( 'Hooks::hookErrorHandler' ); // mark hook as deprecated, if deprecation version is specified @@ -215,7 +210,6 @@ class Hooks { } restore_error_handler(); - $profiler->scopedProfileOut( $funcPS ); // Process the return value. if ( is_string( $retval ) ) { diff --git a/includes/Html.php b/includes/Html.php index 6907245bc3..235096ddde 100644 --- a/includes/Html.php +++ b/includes/Html.php @@ -104,8 +104,8 @@ class Html { /** * Modifies a set of attributes meant for button elements * and apply a set of default attributes when $wgUseMediaWikiUIEverywhere enabled. - * @param array $attrs - * @param string[] $modifiers to add to the button + * @param array $attrs HTML attributes in an associative array + * @param string[] $modifiers classes to add to the button * @see https://tools.wmflabs.org/styleguide/desktop/index.html for guidance on available modifiers * @return array $attrs A modified attribute array */ @@ -115,16 +115,15 @@ class Html { if ( isset( $attrs['class'] ) ) { if ( is_array( $attrs['class'] ) ) { $attrs['class'][] = 'mw-ui-button'; - $attrs = array_merge( $attrs, $modifiers ); + $attrs['class'] = array_merge( $attrs['class'], $modifiers ); // ensure compatibility with Xml $attrs['class'] = implode( ' ', $attrs['class'] ); } else { $attrs['class'] .= ' mw-ui-button ' . implode( ' ', $modifiers ); } } else { - $attrs['class'] = array( 'mw-ui-button' ); // ensure compatibility with Xml - $attrs['class'] = implode( ' ', array_merge( $attrs['class'], $modifiers ) ); + $attrs['class'] = 'mw-ui-button ' . implode( ' ', $modifiers ); } } return $attrs; @@ -162,7 +161,7 @@ class Html { * @param array $attrs Associative array of attributes, e.g., array( * 'href' => 'http://www.mediawiki.org/' ). See expandAttributes() for * further documentation. - * @param string[] $modifiers to add to the button + * @param string[] $modifiers classes to add to the button * @see http://tools.wmflabs.org/styleguide/desktop/index.html for guidance on available modifiers * @return string Raw HTML */ @@ -182,7 +181,7 @@ class Html { * @param array $attrs Associative array of attributes, e.g., array( * 'href' => 'http://www.mediawiki.org/' ). See expandAttributes() for * further documentation. - * @param string[] $modifiers to add to the button + * @param string[] $modifiers classes to add to the button * @see http://tools.wmflabs.org/styleguide/desktop/index.html for guidance on available modifiers * @return string Raw HTML */ @@ -716,6 +715,9 @@ class Html { if ( in_array( $type, array( 'text', 'search', 'email', 'password', 'number' ) ) ) { $attribs = self::getTextInputAttributes( $attribs ); } + if ( in_array( $type, array( 'button', 'reset', 'submit' ) ) ) { + $attribs = self::buttonAttributes( $attribs ); + } return self::element( 'input', $attribs ); } diff --git a/includes/HttpFunctions.php b/includes/HttpFunctions.php index 8e05f597d9..825cd064e8 100644 --- a/includes/HttpFunctions.php +++ b/includes/HttpFunctions.php @@ -792,14 +792,14 @@ class CurlHttpRequest extends MWHttpRequest { } if ( $this->followRedirects && $this->canFollowRedirects() ) { - wfSuppressWarnings(); + MediaWiki\suppressWarnings(); if ( !curl_setopt( $curlHandle, CURLOPT_FOLLOWLOCATION, true ) ) { wfDebug( __METHOD__ . ": Couldn't set CURLOPT_FOLLOWLOCATION. " . "Probably safe_mode or open_basedir is set.\n" ); // Continue the processing. If it were in curl_setopt_array, // processing would have halted on its entry } - wfRestoreWarnings(); + MediaWiki\restoreWarnings(); } if ( $this->profiler ) { @@ -938,9 +938,9 @@ class PhpHttpRequest extends MWHttpRequest { } do { $reqCount++; - wfSuppressWarnings(); + MediaWiki\suppressWarnings(); $fh = fopen( $url, "r", false, $context ); - wfRestoreWarnings(); + MediaWiki\restoreWarnings(); if ( !$fh ) { break; diff --git a/includes/Import.php b/includes/Import.php index ee57a9e01e..6a0bfd093b 100644 --- a/includes/Import.php +++ b/includes/Import.php @@ -394,9 +394,9 @@ class WikiImporter { $countKey = 'title_' . $title->getPrefixedText(); $countable = $page->isCountable( $editInfo ); if ( array_key_exists( $countKey, $this->countableCache ) && - $countable != $this->countableCache[ $countKey ] ) { + $countable != $this->countableCache[$countKey] ) { DeferredUpdates::addUpdate( SiteStatsUpdate::factory( array( - 'articles' => ( (int)$countable - (int)$this->countableCache[ $countKey ] ) + 'articles' => ( (int)$countable - (int)$this->countableCache[$countKey] ) ) ) ); } } @@ -611,7 +611,7 @@ class WikiImporter { $tag = $this->reader->localName; if ( $tag == 'namespace' ) { - $this->foreignNamespaces[ $this->nodeAttribute( 'key' ) ] = + $this->foreignNamespaces[$this->nodeAttribute( 'key' )] = $this->nodeContents(); } elseif ( in_array( $tag, $normalFields ) ) { $siteInfo[$tag] = $this->nodeContents(); @@ -1857,9 +1857,9 @@ class ImportStreamSource implements ImportSource { * @return Status */ static function newFromFile( $filename ) { - wfSuppressWarnings(); + MediaWiki\suppressWarnings(); $file = fopen( $filename, 'rt' ); - wfRestoreWarnings(); + MediaWiki\restoreWarnings(); if ( !$file ) { return Status::newFatal( "importcantopen" ); } diff --git a/includes/MWTimestamp.php b/includes/MWTimestamp.php index ea91470e85..f2bd6ba569 100644 --- a/includes/MWTimestamp.php +++ b/includes/MWTimestamp.php @@ -199,42 +199,19 @@ class MWTimestamp { * * @since 1.20 * @since 1.22 Uses Language::getHumanTimestamp to produce the timestamp + * @deprecated since 1.26 Use Language::getHumanTimestamp directly * - * @param MWTimestamp|null $relativeTo The base timestamp to compare to - * (defaults to now). - * @param User|null $user User the timestamp is being generated for (or null - * to use main context's user). - * @param Language|null $lang Language to use to make the human timestamp - * (or null to use main context's language). + * @param MWTimestamp|null $relativeTo The base timestamp to compare to (defaults to now) + * @param User|null $user User the timestamp is being generated for (or null to use main context's user) + * @param Language|null $lang Language to use to make the human timestamp (or null to use main context's language) * @return string Formatted timestamp */ - public function getHumanTimestamp( MWTimestamp $relativeTo = null, - User $user = null, Language $lang = null - ) { - if ( $relativeTo === null ) { - $relativeTo = new self(); - } - if ( $user === null ) { - $user = RequestContext::getMain()->getUser(); - } + public function getHumanTimestamp( MWTimestamp $relativeTo = null, User $user = null, Language $lang = null ) { if ( $lang === null ) { $lang = RequestContext::getMain()->getLanguage(); } - // Adjust for the user's timezone. - $offsetThis = $this->offsetForUser( $user ); - $offsetRel = $relativeTo->offsetForUser( $user ); - - $ts = ''; - if ( Hooks::run( 'GetHumanTimestamp', array( &$ts, $this, $relativeTo, $user, $lang ) ) ) { - $ts = $lang->getHumanTimestamp( $this, $relativeTo, $user ); - } - - // Reset the timezone on the objects. - $this->timestamp->sub( $offsetThis ); - $relativeTo->timestamp->sub( $offsetRel ); - - return $ts; + return $lang->getHumanTimestamp( $this, $relativeTo, $user ); } /** diff --git a/includes/MediaWiki.php b/includes/MediaWiki.php index 58c49f4bac..932dea20d1 100644 --- a/includes/MediaWiki.php +++ b/includes/MediaWiki.php @@ -239,63 +239,97 @@ class MediaWiki { } throw new BadTitleError(); } - // Redirect loops, no title in URL, $wgUsePathInfo URLs, and URLs with a variant - } elseif ( $request->getVal( 'action', 'view' ) == 'view' && !$request->wasPosted() - && ( $request->getVal( 'title' ) === null - || $title->getPrefixedDBkey() != $request->getVal( 'title' ) ) - && !count( $request->getValueNames( array( 'action', 'title' ) ) ) - && Hooks::run( 'TestCanonicalRedirect', array( $request, $title, $output ) ) - ) { - if ( $title->isSpecialPage() ) { - list( $name, $subpage ) = SpecialPageFactory::resolveAlias( $title->getDBkey() ); - if ( $name ) { - $title = SpecialPage::getTitleFor( $name, $subpage ); - } - } - $targetUrl = wfExpandUrl( $title->getFullURL(), PROTO_CURRENT ); - // Redirect to canonical url, make it a 301 to allow caching - if ( $targetUrl == $request->getFullRequestURL() ) { - $message = "Redirect loop detected!\n\n" . - "This means the wiki got confused about what page was " . - "requested; this sometimes happens when moving a wiki " . - "to a new server or changing the server configuration.\n\n"; - - if ( $this->config->get( 'UsePathInfo' ) ) { - $message .= "The wiki is trying to interpret the page " . - "title from the URL path portion (PATH_INFO), which " . - "sometimes fails depending on the web server. Try " . - "setting \"\$wgUsePathInfo = false;\" in your " . - "LocalSettings.php, or check that \$wgArticlePath " . - "is correct."; + // Handle any other redirects. + // Redirect loops, titleless URL, $wgUsePathInfo URLs, and URLs with a variant + } elseif ( !$this->tryNormaliseRedirect( $title ) ) { + + // Special pages + if ( NS_SPECIAL == $title->getNamespace() ) { + // Actions that need to be made when we have a special pages + SpecialPageFactory::executePath( $title, $this->context ); + } else { + // ...otherwise treat it as an article view. The article + // may still be a wikipage redirect to another article or URL. + $article = $this->initializeArticle(); + if ( is_object( $article ) ) { + $this->performAction( $article, $requestTitle ); + } elseif ( is_string( $article ) ) { + $output->redirect( $article ); } else { - $message .= "Your web server was detected as possibly not " . - "supporting URL path components (PATH_INFO) correctly; " . - "check your LocalSettings.php for a customized " . - "\$wgArticlePath setting and/or toggle \$wgUsePathInfo " . - "to true."; + throw new MWException( "Shouldn't happen: MediaWiki::initializeArticle()" + . " returned neither an object nor a URL" ); } - throw new HttpError( 500, $message ); - } else { - $output->setSquidMaxage( 1200 ); - $output->redirect( $targetUrl, '301' ); } - // Special pages - } elseif ( NS_SPECIAL == $title->getNamespace() ) { - // Actions that need to be made when we have a special pages - SpecialPageFactory::executePath( $title, $this->context ); - } else { - // ...otherwise treat it as an article view. The article - // may be a redirect to another article or URL. - $article = $this->initializeArticle(); - if ( is_object( $article ) ) { - $this->performAction( $article, $requestTitle ); - } elseif ( is_string( $article ) ) { - $output->redirect( $article ); + } + } + + /** + * Handle redirects for uncanonical title requests. + * + * Handles: + * - Redirect loops. + * - No title in URL. + * - $wgUsePathInfo URLs. + * - URLs with a variant. + * - Other non-standard URLs (as long as they have no extra query parameters). + * + * Behaviour: + * - Normalise title values: + * /wiki/Foo%20Bar -> /wiki/Foo_Bar + * - Normalise empty title: + * /wiki/ -> /wiki/Main + * /w/index.php?title= -> /wiki/Main + * - Don't redirect anything with query parameters other than 'title' or 'action=view'. + * + * @return bool True if a redirect was set. + */ + private function tryNormaliseRedirect( $title ) { + $request = $this->context->getRequest(); + $output = $this->context->getOutput(); + + if ( $request->getVal( 'action', 'view' ) != 'view' + || $request->wasPosted() + || ( $request->getVal( 'title' ) !== null + && $title->getPrefixedDBkey() == $request->getVal( 'title' ) ) + || count( $request->getValueNames( array( 'action', 'title' ) ) ) + || !Hooks::run( 'TestCanonicalRedirect', array( $request, $title, $output ) ) + ) { + return false; + } + + if ( $title->isSpecialPage() ) { + list( $name, $subpage ) = SpecialPageFactory::resolveAlias( $title->getDBkey() ); + if ( $name ) { + $title = SpecialPage::getTitleFor( $name, $subpage ); + } + } + // Redirect to canonical url, make it a 301 to allow caching + $targetUrl = wfExpandUrl( $title->getFullURL(), PROTO_CURRENT ); + if ( $targetUrl == $request->getFullRequestURL() ) { + $message = "Redirect loop detected!\n\n" . + "This means the wiki got confused about what page was " . + "requested; this sometimes happens when moving a wiki " . + "to a new server or changing the server configuration.\n\n"; + + if ( $this->config->get( 'UsePathInfo' ) ) { + $message .= "The wiki is trying to interpret the page " . + "title from the URL path portion (PATH_INFO), which " . + "sometimes fails depending on the web server. Try " . + "setting \"\$wgUsePathInfo = false;\" in your " . + "LocalSettings.php, or check that \$wgArticlePath " . + "is correct."; } else { - throw new MWException( "Shouldn't happen: MediaWiki::initializeArticle()" - . " returned neither an object nor a URL" ); + $message .= "Your web server was detected as possibly not " . + "supporting URL path components (PATH_INFO) correctly; " . + "check your LocalSettings.php for a customized " . + "\$wgArticlePath setting and/or toggle \$wgUsePathInfo " . + "to true."; } + throw new HttpError( 500, $message ); } + $output->setSquidMaxage( 1200 ); + $output->redirect( $targetUrl, '301' ); + return true; } /** @@ -433,37 +467,68 @@ class MediaWiki { // Bug 62091: while exceptions are convenient to bubble up GUI errors, // they are not internal application faults. As with normal requests, this // should commit, print the output, do deferred updates, jobs, and profiling. - wfGetLBFactory()->commitMasterChanges(); + $this->doPreOutputCommit(); $e->report(); // display the GUI error } } catch ( Exception $e ) { MWExceptionHandler::handleException( $e ); } - if ( function_exists( 'register_postsend_function' ) ) { - // https://github.com/facebook/hhvm/issues/1230 - register_postsend_function( array( $this, 'postSendUpdates' ) ); - } elseif ( function_exists( 'fastcgi_finish_request' ) ) { - fastcgi_finish_request(); - $this->postSendUpdates(); - } else { - $this->postSendUpdates(); - } + $this->doPostOutputShutdown( 'normal' ); + } + + /** + * This function commits all DB changes as needed before + * the user can receive a response (in case commit fails) + * + * @since 1.26 + */ + public function doPreOutputCommit() { + // Either all DBs should commit or none + ignore_user_abort( true ); + wfGetLBFactory()->commitMasterChanges(); } /** * This function does work that can be done *after* the * user gets the HTTP response so they don't block on it * + * @param string $mode Use 'fast' to always skip job running * @since 1.26 */ - public function postSendUpdates() { - try { - JobQueueGroup::pushLazyJobs(); - $this->triggerJobs(); - $this->restInPeace(); - } catch ( Exception $e ) { - MWExceptionHandler::handleException( $e ); + public function doPostOutputShutdown( $mode = 'normal' ) { + // Show profiling data if enabled + Profiler::instance()->logDataPageOutputOnly(); + + $that = $this; + $callback = function () use ( $that, $mode ) { + try { + // Assure deferred updates are not in the main transaction + wfGetLBFactory()->commitMasterChanges(); + // Run jobs occasionally, if enabled + if ( $mode === 'normal' ) { + $that->triggerJobs(); + } + // Do deferred updates and job insertion and final commit + $that->restInPeace(); + } catch ( Exception $e ) { + MWExceptionHandler::handleException( $e ); + } + }; + + if ( function_exists( 'register_postsend_function' ) ) { + // https://github.com/facebook/hhvm/issues/1230 + register_postsend_function( $callback ); + } else { + if ( function_exists( 'fastcgi_finish_request' ) ) { + fastcgi_finish_request(); + } else { + // Either all DB and deferred updates should happen or none. + // The later should not be cancelled due to client disconnect. + ignore_user_abort( true ); + } + + $callback(); } } @@ -478,7 +543,7 @@ class MediaWiki { list( $host, $lag ) = wfGetLB()->getMaxLag(); if ( $lag > $maxLag ) { $resp = $this->context->getRequest()->response(); - $resp->header( 'HTTP/1.1 503 Service Unavailable' ); + $resp->statusHeader( 503 ); $resp->header( 'Retry-After: ' . max( intval( $maxLag ), 5 ) ); $resp->header( 'X-Database-Lag: ' . intval( $lag ) ); $resp->header( 'Content-Type: text/plain' ); @@ -602,16 +667,13 @@ class MediaWiki { // Actually do the work of the request and build up any output $this->performRequest(); - // Either all DB and deferred updates should happen or none. - // The later should not be cancelled due to client disconnect. - ignore_user_abort( true ); // Now commit any transactions, so that unreported errors after - // output() don't roll back the whole DB transaction - wfGetLBFactory()->commitMasterChanges(); + // output() don't roll back the whole DB transaction and so that + // we avoid having both success and error text in the response + $this->doPreOutputCommit(); // Output everything! $this->context->getOutput()->output(); - } /** @@ -644,7 +706,7 @@ class MediaWiki { * to run a specified number of jobs. This registers a callback to cleanup * the socket once it's done. */ - protected function triggerJobs() { + public function triggerJobs() { $jobRunRate = $this->config->get( 'JobRunRate' ); if ( $jobRunRate <= 0 || wfReadOnly() ) { return; @@ -687,7 +749,7 @@ class MediaWiki { $errno = $errstr = null; $info = wfParseUrl( $this->config->get( 'Server' ) ); - wfSuppressWarnings(); + MediaWiki\suppressWarnings(); $sock = fsockopen( $info['host'], isset( $info['port'] ) ? $info['port'] : 80, @@ -697,7 +759,7 @@ class MediaWiki { // is a problem elsewhere. 0.1 ); - wfRestoreWarnings(); + MediaWiki\restoreWarnings(); if ( !$sock ) { $runJobsLogger->error( "Failed to start cron API (socket error $errno): $errstr" ); // Fall back to running the job here while the user waits diff --git a/includes/MimeMagic.php b/includes/MimeMagic.php index ebe98a3c1d..3b065255a4 100644 --- a/includes/MimeMagic.php +++ b/includes/MimeMagic.php @@ -617,16 +617,18 @@ class MimeMagic { /** * Guess the MIME type from the file contents. * + * @todo Remove $ext param + * * @param string $file * @param mixed $ext * @return bool|string * @throws MWException */ - private function doGuessMimeType( $file, $ext ) { // TODO: remove $ext param + private function doGuessMimeType( $file, $ext ) { // Read a chunk of the file - wfSuppressWarnings(); + MediaWiki\suppressWarnings(); $f = fopen( $file, 'rb' ); - wfRestoreWarnings(); + MediaWiki\restoreWarnings(); if ( !$f ) { return 'unknown/unknown'; @@ -780,9 +782,9 @@ class MimeMagic { return $this->detectZipType( $head, $tail, $ext ); } - wfSuppressWarnings(); + MediaWiki\suppressWarnings(); $gis = getimagesize( $file ); - wfRestoreWarnings(); + MediaWiki\restoreWarnings(); if ( $gis && isset( $gis['mime'] ) ) { $mime = $gis['mime']; diff --git a/includes/OutputPage.php b/includes/OutputPage.php index a3a5a2730a..0ed847e137 100644 --- a/includes/OutputPage.php +++ b/includes/OutputPage.php @@ -20,6 +20,8 @@ * @file */ +use MediaWiki\Logger\LoggerFactory; + /** * This class should be covered by a general architecture document which does * not exist as of January 2011. This is one of the Core classes and should @@ -302,6 +304,11 @@ class OutputPage extends ContextSource { */ private $mEnableSectionEditLinks = true; + /** + * @var string|null The URL to send in a element with rel=copyright + */ + private $copyrightUrl; + /** * Constructor for OutputPage. This should not be called directly. * Instead a new RequestContext should be created and it will implicitly create @@ -338,6 +345,18 @@ class OutputPage extends ContextSource { return $this->mRedirect; } + /** + * Set the copyright URL to send with the output. + * Empty string to omit, null to reset. + * + * @since 1.26 + * + * @param string|null $url + */ + public function setCopyrightUrl( $url ) { + $this->copyrightUrl = $url; + } + /** * Set the HTTP status code to send with the output. * @@ -598,7 +617,8 @@ class OutputPage extends ContextSource { $module = $resourceLoader->getModule( $val ); if ( $module instanceof ResourceLoaderModule && $module->isPositionDefault() ) { - $warning = __METHOD__ . ': style module should define its position explicitly: ' . $val . ' ' . get_class( $module ); + $warning = __METHOD__ . ': style module should define its position explicitly: ' . + $val . ' ' . get_class( $module ); wfDebugLog( 'resourceloader', $warning ); wfLogWarning( $warning ); } @@ -807,9 +827,9 @@ class OutputPage extends ContextSource { # this breaks strtotime(). $clientHeader = preg_replace( '/;.*$/', '', $clientHeader ); - wfSuppressWarnings(); // E_STRICT system time bitching + MediaWiki\suppressWarnings(); // E_STRICT system time bitching $clientHeaderTime = strtotime( $clientHeader ); - wfRestoreWarnings(); + MediaWiki\restoreWarnings(); if ( !$clientHeaderTime ) { wfDebug( __METHOD__ . ": unable to parse the client's If-Modified-Since header: $clientHeader\n" ); @@ -836,10 +856,10 @@ class OutputPage extends ContextSource { } # Not modified - # Give a 304 response code and disable body output + # Give a 304 Not Modified response code and disable body output wfDebug( __METHOD__ . ": NOT MODIFIED, $info\n", 'log' ); ini_set( 'zlib.output_compression', 0 ); - $this->getRequest()->response()->header( "HTTP/1.1 304 Not Modified" ); + $this->getRequest()->response()->statusHeader( 304 ); $this->sendCacheControl(); $this->disable(); @@ -2218,8 +2238,7 @@ class OutputPage extends ContextSource { if ( Hooks::run( "BeforePageRedirect", array( $this, &$redirect, &$code ) ) ) { if ( $code == '301' || $code == '303' ) { if ( !$config->get( 'DebugRedirects' ) ) { - $message = HttpStatus::getMessage( $code ); - $response->header( "HTTP/1.1 $code $message" ); + $response->statusHeader( $code ); } $this->mLastModified = wfTimestamp( TS_RFC2822 ); } @@ -2241,10 +2260,7 @@ class OutputPage extends ContextSource { return; } elseif ( $this->mStatusCode ) { - $message = HttpStatus::getMessage( $this->mStatusCode ); - if ( $message ) { - $response->header( 'HTTP/1.1 ' . $this->mStatusCode . ' ' . $message ); - } + $response->statusHeader( $this->mStatusCode ); } # Buffer output; final headers may depend on later processing @@ -2266,7 +2282,6 @@ class OutputPage extends ContextSource { if ( $this->mArticleBodyOnly ) { echo $this->mBodytext; } else { - $sk = $this->getSkin(); // add skin specific modules $modules = $sk->getDefaultModules(); @@ -2737,7 +2752,10 @@ class OutputPage extends ContextSource { */ public function getResourceLoader() { if ( is_null( $this->mResourceLoader ) ) { - $this->mResourceLoader = new ResourceLoader( $this->getConfig() ); + $this->mResourceLoader = new ResourceLoader( + $this->getConfig(), + LoggerFactory::getInstance( 'resourceloader' ) + ); } return $this->mResourceLoader; } @@ -2981,8 +2999,10 @@ class OutputPage extends ContextSource { // Load embeddable private modules before any loader links // This needs to be TYPE_COMBINED so these modules are properly wrapped // in mw.loader.implement() calls and deferred until mw.user is available - $embedScripts = array( 'user.options', 'user.tokens' ); + $embedScripts = array( 'user.options' ); $links[] = $this->makeResourceLoaderLink( $embedScripts, ResourceLoaderModule::TYPE_COMBINED ); + // Separate user.tokens as otherwise caching will be allowed (T84960) + $links[] = $this->makeResourceLoaderLink( 'user.tokens', ResourceLoaderModule::TYPE_COMBINED ); // Scripts and messages "only" requests marked for top inclusion $links[] = $this->makeResourceLoaderLink( @@ -3429,17 +3449,21 @@ class OutputPage extends ContextSource { } # Copyright - $copyright = ''; - if ( $config->get( 'RightsPage' ) ) { - $copy = Title::newFromText( $config->get( 'RightsPage' ) ); + if ( $this->copyrightUrl !== null ) { + $copyright = $this->copyrightUrl; + } else { + $copyright = ''; + if ( $config->get( 'RightsPage' ) ) { + $copy = Title::newFromText( $config->get( 'RightsPage' ) ); - if ( $copy ) { - $copyright = $copy->getLocalURL(); + if ( $copy ) { + $copyright = $copy->getLocalURL(); + } } - } - if ( !$copyright && $config->get( 'RightsUrl' ) ) { - $copyright = $config->get( 'RightsUrl' ); + if ( !$copyright && $config->get( 'RightsUrl' ) ) { + $copyright = $config->get( 'RightsUrl' ); + } } if ( $copyright ) { @@ -3500,8 +3524,25 @@ class OutputPage extends ContextSource { if ( $canonicalUrl !== false ) { $canonicalUrl = wfExpandUrl( $canonicalUrl, PROTO_CANONICAL ); } else { - $reqUrl = $this->getRequest()->getRequestURL(); - $canonicalUrl = wfExpandUrl( $reqUrl, PROTO_CANONICAL ); + if ( $this->isArticleRelated() ) { + // This affects all requests where "setArticleRelated" is true. This is + // typically all requests that show content (query title, curid, oldid, diff), + // and all wikipage actions (edit, delete, purge, info, history etc.). + // It does not apply to File pages and Special pages. + // 'history' and 'info' actions address page metadata rather than the page + // content itself, so they may not be canonicalized to the view page url. + // TODO: this ought to be better encapsulated in the Action class. + $action = Action::getActionName( $this->getContext() ); + if ( in_array( $action, array( 'history', 'info' ) ) ) { + $query = "action={$action}"; + } else { + $query = ''; + } + $canonicalUrl = $this->getTitle()->getCanonicalURL( $query ); + } else { + $reqUrl = $this->getRequest()->getRequestURL(); + $canonicalUrl = wfExpandUrl( $reqUrl, PROTO_CANONICAL ); + } } } if ( $canonicalUrl !== false ) { diff --git a/includes/Preferences.php b/includes/Preferences.php index 9b0ada812a..ecb2294d5b 100644 --- a/includes/Preferences.php +++ b/includes/Preferences.php @@ -1394,7 +1394,7 @@ class Preferences { } # Max is +14:00 and min is -12:00, see: - # http://en.wikipedia.org/wiki/Timezone + # https://en.wikipedia.org/wiki/Timezone $minDiff = min( $minDiff, 840 ); # 14:00 $minDiff = max( $minDiff, - 720 ); # -12:00 return 'Offset|' . $minDiff; diff --git a/includes/ProtectionForm.php b/includes/ProtectionForm.php index 69b64dd62b..1443d1ca69 100644 --- a/includes/ProtectionForm.php +++ b/includes/ProtectionForm.php @@ -541,7 +541,7 @@ class ProtectionForm { $out .= Xml::closeElement( 'fieldset' ); if ( $user->isAllowed( 'editinterface' ) ) { - $link = Linker::link( + $link = Linker::linkKnown( $context->msg( 'protect-dropdown' )->inContentLanguage()->getTitle(), $context->msg( 'protect-edit-reasonlist' )->escaped(), array(), diff --git a/includes/Revision.php b/includes/Revision.php index 3ba6157c79..5939715b5a 100644 --- a/includes/Revision.php +++ b/includes/Revision.php @@ -194,8 +194,8 @@ class Revision implements IDBAccessObject { if ( !isset( $attribs['title'] ) && isset( $row->ar_namespace ) - && isset( $row->ar_title ) ) { - + && isset( $row->ar_title ) + ) { $attribs['title'] = Title::makeTitle( $row->ar_namespace, $row->ar_title ); } @@ -1284,8 +1284,14 @@ class Revision implements IDBAccessObject { if ( $wgCompressRevisions ) { if ( function_exists( 'gzdeflate' ) ) { - $text = gzdeflate( $text ); - $flags[] = 'gzip'; + $deflated = gzdeflate( $text ); + + if ( $deflated === false ) { + wfLogWarning( __METHOD__ . ': gzdeflate() failed' ); + } else { + $text = $deflated; + $flags[] = 'gzip'; + } } else { wfDebug( __METHOD__ . " -- no zlib support, not compressing\n" ); } @@ -1306,6 +1312,11 @@ class Revision implements IDBAccessObject { # This can be done periodically via maintenance/compressOld.php, and # as pages are saved if $wgCompressRevisions is set. $text = gzinflate( $text ); + + if ( $text === false ) { + wfLogWarning( __METHOD__ . ': gzinflate() failed' ); + return false; + } } if ( in_array( 'object', $flags ) ) { diff --git a/includes/Sanitizer.php b/includes/Sanitizer.php index 8256db96bb..2340cd9449 100644 --- a/includes/Sanitizer.php +++ b/includes/Sanitizer.php @@ -374,7 +374,6 @@ class Sanitizer { // are changed (like in the screwed up test system) we will re-initialise the settings. $globalContext = implode( '-', compact( 'wgAllowMicrodataAttributes', 'wgAllowImageTag' ) ); if ( !$staticInitialised || $staticInitialised != $globalContext ) { - $htmlpairsStatic = array( # Tags that must be closed 'b', 'bdi', 'del', 'i', 'ins', 'u', 'font', 'big', 'small', 'sub', 'sup', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'cite', 'code', 'em', 's', @@ -488,9 +487,9 @@ class Sanitizer { $badtag = true; } elseif ( $slash ) { # Closing a tag... is it the one we just opened? - wfSuppressWarnings(); + MediaWiki\suppressWarnings(); $ot = array_pop( $tagstack ); - wfRestoreWarnings(); + MediaWiki\restoreWarnings(); if ( $ot != $t ) { if ( isset( $htmlsingleallowed[$ot] ) ) { @@ -498,32 +497,32 @@ class Sanitizer { # and see if we find a match below them $optstack = array(); array_push( $optstack, $ot ); - wfSuppressWarnings(); + MediaWiki\suppressWarnings(); $ot = array_pop( $tagstack ); - wfRestoreWarnings(); + MediaWiki\restoreWarnings(); while ( $ot != $t && isset( $htmlsingleallowed[$ot] ) ) { array_push( $optstack, $ot ); - wfSuppressWarnings(); + MediaWiki\suppressWarnings(); $ot = array_pop( $tagstack ); - wfRestoreWarnings(); + MediaWiki\restoreWarnings(); } if ( $t != $ot ) { # No match. Push the optional elements back again $badtag = true; - wfSuppressWarnings(); + MediaWiki\suppressWarnings(); $ot = array_pop( $optstack ); - wfRestoreWarnings(); + MediaWiki\restoreWarnings(); while ( $ot ) { array_push( $tagstack, $ot ); - wfSuppressWarnings(); + MediaWiki\suppressWarnings(); $ot = array_pop( $optstack ); - wfRestoreWarnings(); + MediaWiki\restoreWarnings(); } } } else { - wfSuppressWarnings(); + MediaWiki\suppressWarnings(); array_push( $tagstack, $ot ); - wfRestoreWarnings(); + MediaWiki\restoreWarnings(); #
  • can be nested in
      or
        , skip those cases: if ( !isset( $htmllist[$ot] ) || !isset( $listtags[$t] ) ) { diff --git a/includes/Setup.php b/includes/Setup.php index 1324ed8bbe..a97cfa6ad9 100644 --- a/includes/Setup.php +++ b/includes/Setup.php @@ -105,6 +105,10 @@ if ( $wgGitInfoCacheDirectory === false && $wgCacheDirectory !== false ) { $wgGitInfoCacheDirectory = "{$wgCacheDirectory}/gitinfo"; } +if ( $wgEnableParserCache === false ) { + $wgParserCacheType = CACHE_NONE; +} + // Fix path to icon images after they were moved in 1.24 if ( $wgRightsIcon ) { $wgRightsIcon = str_replace( @@ -232,9 +236,7 @@ if ( $wgUseInstantCommons ) { $wgForeignFileRepos[] = array( 'class' => 'ForeignAPIRepo', 'name' => 'wikimediacommons', - 'apibase' => WebRequest::detectProtocol() === 'https' ? - 'https://commons.wikimedia.org/w/api.php' : - 'http://commons.wikimedia.org/w/api.php', + 'apibase' => 'https://commons.wikimedia.org/w/api.php', 'hashLevels' => 2, 'fetchDescription' => true, 'descriptionCacheExpiry' => 43200, @@ -361,13 +363,13 @@ if ( $wgMetaNamespace === false ) { // Default value is 2000 or the suhosin limit if it is between 1 and 2000 if ( $wgResourceLoaderMaxQueryLength === false ) { - $suhosinMaxValueLength = (int) ini_get( 'suhosin.get.max_value_length' ); + $suhosinMaxValueLength = (int)ini_get( 'suhosin.get.max_value_length' ); if ( $suhosinMaxValueLength > 0 && $suhosinMaxValueLength < 2000 ) { $wgResourceLoaderMaxQueryLength = $suhosinMaxValueLength; } else { $wgResourceLoaderMaxQueryLength = 2000; } - unset($suhosinMaxValueLength); + unset( $suhosinMaxValueLength ); } /** @@ -427,12 +429,12 @@ if ( !$wgHtml5Version && $wgAllowRdfaAttributes ) { } // Blacklisted file extensions shouldn't appear on the "allowed" list -$wgFileExtensions = array_values( array_diff ( $wgFileExtensions, $wgFileBlacklist ) ); +$wgFileExtensions = array_values( array_diff( $wgFileExtensions, $wgFileBlacklist ) ); if ( $wgInvalidateCacheOnLocalSettingsChange ) { - // @codingStandardsIgnoreStart Generic.PHP.NoSilencedErrors.Discouraged - No GlobalFunction here yet. - $wgCacheEpoch = max( $wgCacheEpoch, gmdate( 'YmdHis', @filemtime( "$IP/LocalSettings.php" ) ) ); - // @codingStandardsIgnoreEnd + MediaWiki\suppressWarnings(); + $wgCacheEpoch = max( $wgCacheEpoch, gmdate( 'YmdHis', filemtime( "$IP/LocalSettings.php" ) ) ); + MediaWiki\restoreWarnings(); } if ( $wgNewUserLog ) { @@ -466,6 +468,15 @@ if ( $wgProfileOnly ) { $wgDebugLogFile = ''; } +// Backwards compatibility with old password limits +if ( $wgMinimalPasswordLength !== false ) { + $wgPasswordPolicy['policies']['default']['MinimalPasswordLength'] = $wgMinimalPasswordLength; +} + +if ( $wgMaximalPasswordLength !== false ) { + $wgPasswordPolicy['policies']['default']['MaximalPasswordLength'] = $wgMaximalPasswordLength; +} + Profiler::instance()->scopedProfileOut( $ps_default ); // Disable MWDebug for command line mode, this prevents MWDebug from eating up @@ -552,9 +563,9 @@ wfMemoryLimit(); * explicitly set. Inspired by phpMyAdmin's treatment of the problem. */ if ( is_null( $wgLocaltimezone ) ) { - wfSuppressWarnings(); + MediaWiki\suppressWarnings(); $wgLocaltimezone = date_default_timezone_get(); - wfRestoreWarnings(); + MediaWiki\restoreWarnings(); } date_default_timezone_set( $wgLocaltimezone ); diff --git a/includes/SquidPurgeClient.php b/includes/SquidPurgeClient.php index 824dd06b98..ca8f11aef1 100644 --- a/includes/SquidPurgeClient.php +++ b/includes/SquidPurgeClient.php @@ -95,9 +95,9 @@ class SquidPurgeClient { } $this->socket = socket_create( AF_INET, SOCK_STREAM, SOL_TCP ); socket_set_nonblock( $this->socket ); - wfSuppressWarnings(); + MediaWiki\suppressWarnings(); $ok = socket_connect( $this->socket, $ip, $this->port ); - wfRestoreWarnings(); + MediaWiki\restoreWarnings(); if ( !$ok ) { $error = socket_last_error( $this->socket ); if ( $error !== self::EINPROGRESS ) { @@ -153,12 +153,12 @@ class SquidPurgeClient { } elseif ( IP::isIPv6( $this->host ) ) { throw new MWException( '$wgSquidServers does not support IPv6' ); } else { - wfSuppressWarnings(); + MediaWiki\suppressWarnings(); $this->ip = gethostbyname( $this->host ); if ( $this->ip === $this->host ) { $this->ip = false; } - wfRestoreWarnings(); + MediaWiki\restoreWarnings(); } } return $this->ip; @@ -178,11 +178,11 @@ class SquidPurgeClient { */ public function close() { if ( $this->socket ) { - wfSuppressWarnings(); + MediaWiki\suppressWarnings(); socket_set_block( $this->socket ); socket_shutdown( $this->socket ); socket_close( $this->socket ); - wfRestoreWarnings(); + MediaWiki\restoreWarnings(); } $this->socket = null; $this->readBuffer = ''; @@ -252,9 +252,9 @@ class SquidPurgeClient { $buf = substr( $this->writeBuffer, 0, self::BUFFER_SIZE ); $flags = 0; } - wfSuppressWarnings(); + MediaWiki\suppressWarnings(); $bytesSent = socket_send( $socket, $buf, strlen( $buf ), $flags ); - wfRestoreWarnings(); + MediaWiki\restoreWarnings(); if ( $bytesSent === false ) { $error = socket_last_error( $socket ); @@ -278,9 +278,9 @@ class SquidPurgeClient { } $buf = ''; - wfSuppressWarnings(); + MediaWiki\suppressWarnings(); $bytesRead = socket_recv( $socket, $buf, self::BUFFER_SIZE, 0 ); - wfRestoreWarnings(); + MediaWiki\restoreWarnings(); if ( $bytesRead === false ) { $error = socket_last_error( $socket ); if ( $error != self::EAGAIN && $error != self::EINTR ) { @@ -442,9 +442,9 @@ class SquidPurgeClientPool { } $exceptSockets = null; $timeout = min( $startTime + $this->timeout - microtime( true ), 1 ); - wfSuppressWarnings(); + MediaWiki\suppressWarnings(); $numReady = socket_select( $readSockets, $writeSockets, $exceptSockets, $timeout ); - wfRestoreWarnings(); + MediaWiki\restoreWarnings(); if ( $numReady === false ) { wfDebugLog( 'squid', __METHOD__ . ': Error in stream_select: ' . socket_strerror( socket_last_error() ) . "\n" ); diff --git a/includes/StreamFile.php b/includes/StreamFile.php index a52b25b02f..3f73ae3ccd 100644 --- a/includes/StreamFile.php +++ b/includes/StreamFile.php @@ -44,9 +44,9 @@ class StreamFile { throw new MWException( __FUNCTION__ . " given storage path '$fname'." ); } - wfSuppressWarnings(); + MediaWiki\suppressWarnings(); $stat = stat( $fname ); - wfRestoreWarnings(); + MediaWiki\restoreWarnings(); $res = self::prepareForStream( $fname, $stat, $headers, $sendErrors ); if ( $res == self::NOT_MODIFIED ) { @@ -78,7 +78,7 @@ class StreamFile { ) { if ( !is_array( $info ) ) { if ( $sendErrors ) { - header( 'HTTP/1.0 404 Not Found' ); + HttpStatus::header( 404 ); header( 'Cache-Control: no-cache' ); header( 'Content-Type: text/html; charset=utf-8' ); $encFile = htmlspecialchars( $path ); @@ -126,7 +126,7 @@ class StreamFile { $modsince = preg_replace( '/;.*$/', '', $_SERVER['HTTP_IF_MODIFIED_SINCE'] ); if ( wfTimestamp( TS_UNIX, $info['mtime'] ) <= strtotime( $modsince ) ) { ini_set( 'zlib.output_compression', 0 ); - header( "HTTP/1.0 304 Not Modified" ); + HttpStatus::header( 304 ); return self::NOT_MODIFIED; // ok } } diff --git a/includes/TemplateParser.php b/includes/TemplateParser.php index 3de70fa2a2..d53d593f77 100644 --- a/includes/TemplateParser.php +++ b/includes/TemplateParser.php @@ -130,7 +130,8 @@ class TemplateParser { if ( !is_callable( $renderer ) ) { throw new RuntimeException( "Requested template, {$templateName}, is not callable" ); } - return $this->renderers[$templateName] = $renderer; + $this->renderers[$templateName] = $renderer; + return $renderer; } /** diff --git a/includes/Title.php b/includes/Title.php index d5eff46105..7aa4113446 100644 --- a/includes/Title.php +++ b/includes/Title.php @@ -4380,9 +4380,10 @@ class Title { /** * Updates page_touched for this page; called from LinksUpdate.php * + * @param integer $purgeTime TS_MW timestamp [optional] * @return bool True if the update succeeded */ - public function invalidateCache() { + public function invalidateCache( $purgeTime = null ) { if ( wfReadOnly() ) { return false; } @@ -4394,11 +4395,13 @@ class Title { $method = __METHOD__; $dbw = wfGetDB( DB_MASTER ); $conds = $this->pageCond(); - $dbw->onTransactionIdle( function () use ( $dbw, $conds, $method ) { + $dbw->onTransactionIdle( function () use ( $dbw, $conds, $method, $purgeTime ) { + $dbTimestamp = $dbw->timestamp( $purgeTime ?: time() ); + $dbw->update( 'page', - array( 'page_touched' => $dbw->timestamp() ), - $conds, + array( 'page_touched' => $dbTimestamp ), + $conds + array( 'page_touched < ' . $dbw->addQuotes( $dbTimestamp ) ), $method ); } ); diff --git a/includes/User.php b/includes/User.php index eb2a2dc2ed..1ee8173b2f 100644 --- a/includes/User.php +++ b/includes/User.php @@ -330,7 +330,7 @@ class User implements IDBAccessObject { * * @param integer $flags User::READ_* constant bitfield */ - public function load( $flags = self::READ_LATEST ) { + public function load( $flags = self::READ_NORMAL ) { if ( $this->mLoadedItems === true ) { return; } @@ -344,9 +344,13 @@ class User implements IDBAccessObject { $this->loadDefaults(); break; case 'name': - // @TODO: this gets the ID from a slave, assuming renames - // are rare. This should be controllable and more consistent. - $this->mId = self::idFromName( $this->mName ); + // Make sure this thread sees its own changes + if ( wfGetLB()->hasOrMadeRecentMasterChanges() ) { + $flags |= self::READ_LATEST; + $this->queryFlagsUsed = $flags; + } + + $this->mId = self::idFromName( $this->mName, $flags ); if ( !$this->mId ) { // Nonexistent user placeholder object $this->loadDefaults( $this->mName ); @@ -380,21 +384,19 @@ class User implements IDBAccessObject { return false; } - // Try cache - $cache = $this->loadFromCache(); - if ( !$cache ) { + // Try cache (unless this needs to lock the DB). + // NOTE: if this thread called saveSettings(), the cache was cleared. + if ( ( $flags & self::READ_LOCKING ) || !$this->loadFromCache() ) { wfDebug( "User: cache miss for user {$this->mId}\n" ); - // Load from DB + // Load from DB (make sure this thread sees its own changes) + if ( wfGetLB()->hasOrMadeRecentMasterChanges() ) { + $flags |= self::READ_LATEST; + } if ( !$this->loadFromDatabase( $flags ) ) { // Can't load from ID, user is anonymous return false; } - if ( $flags & self::READ_LATEST ) { - // Only save master data back to the cache to keep it consistent. - // @TODO: save it anyway and have callers specifiy $flags and have - // load() called as needed. That requires updating MANY callers... - $this->saveToCache(); - } + $this->saveToCache(); } $this->mLoadedItems = true; @@ -415,9 +417,8 @@ class User implements IDBAccessObject { return false; } - $cache = ObjectCache::getMainWANInstance(); $key = wfMemcKey( 'user', 'id', $this->mId ); - $data = $cache->get( $key ); + $data = ObjectCache::getMainWANInstance()->get( $key ); if ( !is_array( $data ) || $data['mVersion'] < self::VERSION ) { // Object is expired return false; @@ -448,15 +449,6 @@ class User implements IDBAccessObject { return; } - $cache = ObjectCache::getMainWANInstance(); - - // The cache needs good consistency due to its high TTL, so the user - // should have been loaded from the master to avoid lag amplification. - if ( !( $this->queryFlagsUsed & self::READ_LATEST ) ) { - wfWarn( "Cannot cache slave-loaded User object with ID '{$this->mId}'." ); - return; - } - $data = array(); foreach ( self::$mCacheVars as $name ) { $data[$name] = $this->$name; @@ -464,7 +456,7 @@ class User implements IDBAccessObject { $data['mVersion'] = self::VERSION; $key = wfMemcKey( 'user', 'id', $this->mId ); - $cache->set( $key, $data ); + ObjectCache::getMainWANInstance()->set( $key, $data, 3600 ); } /** @name newFrom*() static factory methods */ @@ -598,9 +590,10 @@ class User implements IDBAccessObject { /** * Get database id given a user name * @param string $name Username + * @param integer $flags User::READ_* constant bitfield * @return int|null The corresponding user's ID, or null if user is nonexistent */ - public static function idFromName( $name ) { + public static function idFromName( $name, $flags = self::READ_NORMAL ) { $nt = Title::makeTitleSafe( NS_USER, $name ); if ( is_null( $nt ) ) { // Illegal name @@ -611,8 +604,11 @@ class User implements IDBAccessObject { return self::$idCacheByName[$name]; } - $dbr = wfGetDB( DB_SLAVE ); - $s = $dbr->selectRow( + $db = ( $flags & self::READ_LATEST ) + ? wfGetDB( DB_MASTER ) + : wfGetDB( DB_SLAVE ); + + $s = $db->selectRow( 'user', array( 'user_id' ), array( 'user_name' => $nt->getText() ), @@ -844,15 +840,14 @@ class User implements IDBAccessObject { * @since 1.23 */ public function checkPasswordValidity( $password ) { - global $wgMinimalPasswordLength, $wgMaximalPasswordLength, $wgContLang; + global $wgPasswordPolicy; - static $blockedLogins = array( - 'Useruser' => 'Passpass', 'Useruser1' => 'Passpass1', # r75589 - 'Apitestsysop' => 'testpass', 'Apitestuser' => 'testpass' # r75605 + $upp = new UserPasswordPolicy( + $wgPasswordPolicy['policies'], + $wgPasswordPolicy['checks'] ); $status = Status::newGood(); - $result = false; //init $result to false for the internal checks if ( !Hooks::run( 'isValidPassword', array( $password, &$result, $this ) ) ) { @@ -861,28 +856,8 @@ class User implements IDBAccessObject { } if ( $result === false ) { - if ( strlen( $password ) < $wgMinimalPasswordLength ) { - $status->error( 'passwordtooshort', $wgMinimalPasswordLength ); - return $status; - } elseif ( strlen( $password ) > $wgMaximalPasswordLength ) { - // T64685: Password too long, might cause DoS attack - $status->fatal( 'passwordtoolong', $wgMaximalPasswordLength ); - return $status; - } elseif ( $wgContLang->lc( $password ) == $wgContLang->lc( $this->mName ) ) { - $status->error( 'password-name-match' ); - return $status; - } elseif ( isset( $blockedLogins[$this->getName()] ) - && $password == $blockedLogins[$this->getName()] - ) { - $status->error( 'password-login-forbidden' ); - return $status; - } else { - //it seems weird returning a Good status here, but this is because of the - //initialization of $result to false above. If the hook is never run or it - //doesn't modify $result, then we will likely get down into this if with - //a valid password. - return $status; - } + $status->merge( $upp->checkUserPassword( $this, $password ) ); + return $status; } elseif ( $result === true ) { return $status; } else { @@ -1162,7 +1137,6 @@ class User implements IDBAccessObject { } $proposedUser = User::newFromId( $sId ); - $proposedUser->load( self::READ_LATEST ); if ( !$proposedUser->isLoggedIn() ) { // Not a valid ID return false; @@ -1229,7 +1203,7 @@ class User implements IDBAccessObject { self::selectFields(), array( 'user_id' => $this->mId ), __METHOD__, - ( $flags & self::READ_LOCKING == self::READ_LOCKING ) + ( ( $flags & self::READ_LOCKING ) == self::READ_LOCKING ) ? array( 'LOCK IN SHARE MODE' ) : array() ); @@ -2303,8 +2277,8 @@ class User implements IDBAccessObject { public function clearSharedCache() { $id = $this->getId(); if ( $id ) { - $cache = ObjectCache::getMainWANInstance(); - $cache->delete( wfMemcKey( 'user', 'id', $id ) ); + $key = wfMemcKey( 'user', 'id', $id ); + ObjectCache::getMainWANInstance()->delete( $key ); } } @@ -2331,14 +2305,11 @@ class User implements IDBAccessObject { * @since 1.25 */ public function touch() { - $this->load(); - - if ( $this->mId ) { - $this->mQuickTouched = $this->newTouchedTimestamp(); - - $cache = ObjectCache::getMainWANInstance(); - $key = wfMemcKey( 'user-quicktouched', 'id', $this->mId ); - $cache->touchCheckKey( $key ); + $id = $this->getId(); + if ( $id ) { + $key = wfMemcKey( 'user-quicktouched', 'id', $id ); + ObjectCache::getMainWANInstance()->touchCheckKey( $key ); + $this->mQuickTouched = null; } } @@ -2360,12 +2331,11 @@ class User implements IDBAccessObject { if ( $this->mId ) { if ( $this->mQuickTouched === null ) { - $cache = ObjectCache::getMainWANInstance(); $key = wfMemcKey( 'user-quicktouched', 'id', $this->mId ); - $timestamp = $cache->getCheckKeyTime( $key ); + $timestamp = ObjectCache::getMainWANInstance()->getCheckKeyTime( $key ); if ( $timestamp ) { - $this->mQuickTouched = wfTimestamp( TS_MW, $timestamp ); + $this->mQuickTouched = wfTimestamp( TS_MW, (int)$timestamp ); } else { # Set the timestamp to get HTTP 304 cache hits $this->touch(); @@ -2383,7 +2353,7 @@ class User implements IDBAccessObject { * @return string TS_MW Timestamp * @since 1.26 */ - protected function getDBTouched() { + public function getDBTouched() { $this->load(); return $this->mTouched; @@ -3521,6 +3491,31 @@ class User implements IDBAccessObject { $this->setCookie( $name, '', time() - 86400, $secure, $params ); } + /** + * Set an extended login cookie on the user's client. The expiry of the cookie + * is controlled by the $wgExtendedLoginCookieExpiration configuration + * variable. + * + * @see User::setCookie + * + * @param string $name Name of the cookie to set + * @param string $value Value to set + * @param bool $secure + * true: Force setting the secure attribute when setting the cookie + * false: Force NOT setting the secure attribute when setting the cookie + * null (default): Use the default ($wgCookieSecure) to set the secure attribute + */ + protected function setExtendedLoginCookie( $name, $value, $secure ) { + global $wgExtendedLoginCookieExpiration, $wgCookieExpiration; + + $exp = time(); + $exp += $wgExtendedLoginCookieExpiration !== null + ? $wgExtendedLoginCookieExpiration + : $wgCookieExpiration; + + $this->setCookie( $name, $value, $exp, $secure ); + } + /** * Set the default cookies for this session on the user's client. * @@ -3530,6 +3525,8 @@ class User implements IDBAccessObject { * @param bool $rememberMe Whether to add a Token cookie for elongated sessions */ public function setCookies( $request = null, $secure = null, $rememberMe = false ) { + global $wgExtendedLoginCookies; + if ( $request === null ) { $request = $this->getRequest(); } @@ -3571,6 +3568,8 @@ class User implements IDBAccessObject { foreach ( $cookies as $name => $value ) { if ( $value === false ) { $this->clearCookie( $name ); + } elseif ( $rememberMe && in_array( $name, $wgExtendedLoginCookies ) ) { + $this->setExtendedLoginCookie( $name, $value, $secure ); } else { $this->setCookie( $name, $value, 0, $secure, array(), $request ); } @@ -3643,12 +3642,6 @@ class User implements IDBAccessObject { return; // anon } - // This method is for updating existing users, so the user should - // have been loaded from the master to begin with to avoid problems. - if ( !( $this->queryFlagsUsed & self::READ_LATEST ) ) { - wfWarn( "Attempting to save slave-loaded User object with ID '{$this->mId}'." ); - } - // Get a new user_touched that is higher than the old one. // This will be used for a CAS check as a last-resort safety // check against race conditions and slave lag. @@ -3684,8 +3677,9 @@ class User implements IDBAccessObject { // Maybe the problem was a missed cache update; clear it to be safe $this->clearSharedCache(); // User was changed in the meantime or loaded with stale data + $from = ( $this->queryFlagsUsed & self::READ_LATEST ) ? 'master' : 'slave'; MWExceptionHandler::logException( new MWException( - "CAS update failed on user_touched for user ID '{$this->mId}';" . + "CAS update failed on user_touched for user ID '{$this->mId}' (read from $from);" . "the version of the user to be saved is older than the current version." ) ); diff --git a/includes/WebRequest.php b/includes/WebRequest.php index a5fd9d8fb0..c99e4846db 100644 --- a/includes/WebRequest.php +++ b/includes/WebRequest.php @@ -104,9 +104,9 @@ class WebRequest { if ( !preg_match( '!^https?://!', $url ) ) { $url = 'http://unused' . $url; } - wfSuppressWarnings(); + MediaWiki\suppressWarnings(); $a = parse_url( $url ); - wfRestoreWarnings(); + MediaWiki\restoreWarnings(); if ( $a ) { $path = isset( $a['path'] ) ? $a['path'] : ''; @@ -176,6 +176,8 @@ class WebRequest { * @return string */ public static function detectServer() { + global $wgAssumeProxiesUseDefaultProtocolPorts; + $proto = self::detectProtocol(); $stdPort = $proto === 'https' ? 443 : 80; @@ -186,13 +188,15 @@ class WebRequest { if ( !isset( $_SERVER[$varName] ) ) { continue; } + $parts = IP::splitHostAndPort( $_SERVER[$varName] ); if ( !$parts ) { // Invalid, do not use continue; } + $host = $parts[0]; - if ( isset( $_SERVER['HTTP_X_FORWARDED_PROTO'] ) ) { + if ( $wgAssumeProxiesUseDefaultProtocolPorts && isset( $_SERVER['HTTP_X_FORWARDED_PROTO'] ) ) { // Bug 70021: Assume that upstream proxy is running on the default // port based on the protocol. We have no reliable way to determine // the actual port in use upstream. @@ -691,7 +695,7 @@ class WebRequest { // This shouldn't happen! throw new MWException( "Web server doesn't provide either " . "REQUEST_URI, HTTP_X_ORIGINAL_URL or SCRIPT_NAME. Report details " . - "of your web server configuration to http://bugzilla.wikimedia.org/" ); + "of your web server configuration to https://phabricator.wikimedia.org/" ); } // User-agents should not send a fragment with the URI, but // if they do, and the web server passes it on to us, we @@ -774,7 +778,7 @@ class WebRequest { * * @param int $deflimit Limit to use if no input and the user hasn't set the option. * @param string $optionname To specify an option other than rclimit to pull from. - * @return array First element is limit, second is offset + * @return int[] First element is limit, second is offset */ public function getLimitOffset( $deflimit = 50, $optionname = 'rclimit' ) { global $wgUser; diff --git a/includes/WebResponse.php b/includes/WebResponse.php index ab34931c2c..1b6947cd96 100644 --- a/includes/WebResponse.php +++ b/includes/WebResponse.php @@ -28,7 +28,7 @@ class WebResponse { /** - * Output a HTTP header, wrapper for PHP's header() + * Output an HTTP header, wrapper for PHP's header() * @param string $string Header to output * @param bool $replace Replace current similar header * @param null|int $http_response_code Forces the HTTP response code to the specified value. @@ -53,6 +53,15 @@ class WebResponse { return null; } + /** + * Output an HTTP status code header + * @since 1.26 + * @param int $code Status code + */ + public function statusHeader( $code ) { + HttpStatus::header( $code ); + } + /** * Set the browser cookie * @param string $name The name of the cookie. @@ -162,6 +171,14 @@ class FauxResponse extends WebResponse { } } + /** + * @since 1.26 + * @param int $code Status code + */ + public function statusHeader( $code ) { + $this->code = intval( $code ); + } + /** * @param string $key The name of the header to get (case insensitive). * @return string|null The header value (if set); null otherwise. diff --git a/includes/Xml.php b/includes/Xml.php index f0bd70b23b..37cffdefa0 100644 --- a/includes/Xml.php +++ b/includes/Xml.php @@ -144,26 +144,19 @@ class Xml { public static function monthSelector( $selected = '', $allmonths = null, $id = 'month' ) { global $wgLang; $options = array(); + $data = new XmlSelect( 'month', $id, $selected ); if ( is_null( $selected ) ) { $selected = ''; } if ( !is_null( $allmonths ) ) { - $options[] = self::option( - wfMessage( 'monthsall' )->text(), - $allmonths, - $selected === $allmonths - ); + $options[wfMessage( 'monthsall' )->text()] = $allmonths; } for ( $i = 1; $i < 13; $i++ ) { - $options[] = self::option( $wgLang->getMonthName( $i ), $i, $selected === $i ); + $options[$wgLang->getMonthName( $i )] = $i; } - return self::openElement( 'select', array( - 'id' => $id, - 'name' => 'month', - 'class' => 'mw-month-selector' - ) ) - . implode( "\n", $options ) - . self::closeElement( 'select' ); + $data->addOptions( $options ); + $data->setAttribute( 'class', 'mw-month-selector' ); + return $data->getHTML(); } /** @@ -871,112 +864,6 @@ class Xml { } } -class XmlSelect { - protected $options = array(); - protected $default = false; - protected $attributes = array(); - - public function __construct( $name = false, $id = false, $default = false ) { - if ( $name ) { - $this->setAttribute( 'name', $name ); - } - - if ( $id ) { - $this->setAttribute( 'id', $id ); - } - - if ( $default !== false ) { - $this->default = $default; - } - } - - /** - * @param string $default - */ - public function setDefault( $default ) { - $this->default = $default; - } - - /** - * @param string $name - * @param array $value - */ - public function setAttribute( $name, $value ) { - $this->attributes[$name] = $value; - } - - /** - * @param string $name - * @return array|null - */ - public function getAttribute( $name ) { - if ( isset( $this->attributes[$name] ) ) { - return $this->attributes[$name]; - } else { - return null; - } - } - - /** - * @param string $name - * @param bool $value - */ - public function addOption( $name, $value = false ) { - // Stab stab stab - $value = $value !== false ? $value : $name; - - $this->options[] = array( $name => $value ); - } - - /** - * This accepts an array of form - * label => value - * label => ( label => value, label => value ) - * - * @param array $options - */ - public function addOptions( $options ) { - $this->options[] = $options; - } - - /** - * This accepts an array of form - * label => value - * label => ( label => value, label => value ) - * - * @param array $options - * @param bool $default - * @return string - */ - static function formatOptions( $options, $default = false ) { - $data = ''; - - foreach ( $options as $label => $value ) { - if ( is_array( $value ) ) { - $contents = self::formatOptions( $value, $default ); - $data .= Html::rawElement( 'optgroup', array( 'label' => $label ), $contents ) . "\n"; - } else { - $data .= Xml::option( $label, $value, $value === $default ) . "\n"; - } - } - - return $data; - } - - /** - * @return string - */ - public function getHTML() { - $contents = ''; - - foreach ( $this->options as $options ) { - $contents .= self::formatOptions( $options, $this->default ); - } - - return Html::rawElement( 'select', $this->attributes, rtrim( $contents ) ); - } -} - /** * A wrapper class which causes Xml::encodeJsVar() and Xml::encodeJsCall() to * interpret a given string as being a JavaScript expression, instead of string diff --git a/includes/XmlSelect.php b/includes/XmlSelect.php new file mode 100644 index 0000000000..1cd04ae10e --- /dev/null +++ b/includes/XmlSelect.php @@ -0,0 +1,130 @@ +. + * + * 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 + */ + +/** + * Module of static functions for generating XML