summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPierre Schmitz <pierre@archlinux.de>2008-08-15 01:29:47 +0200
committerPierre Schmitz <pierre@archlinux.de>2008-08-15 01:29:47 +0200
commit370e83bb0dfd0c70de268c93bf07ad5ee0897192 (patch)
tree491674f4c242e4d6ba0d04eafa305174c35a3391
parentf4debf0f12d0524d2b2427c55ea3f16b680fad97 (diff)
Update auf 1.13.0
-rw-r--r--AdminSettings.sample4
-rw-r--r--HISTORY552
-rw-r--r--INSTALL109
-rw-r--r--Makefile9
-rw-r--r--RELEASE-NOTES1371
-rw-r--r--UPGRADE2
-rw-r--r--api.php6
-rwxr-xr-xbin/svnstat2
-rw-r--r--config/index.php355
-rw-r--r--docs/README19
-rw-r--r--docs/database.txt7
-rw-r--r--docs/deferred.txt59
-rw-r--r--docs/design.txt188
-rw-r--r--docs/globals.txt69
-rw-r--r--docs/hooks.txt500
-rw-r--r--docs/html/README4
-rw-r--r--docs/language.txt37
-rw-r--r--docs/linkcache.txt32
-rw-r--r--docs/magicword.txt86
-rw-r--r--docs/memcached.txt233
-rw-r--r--docs/scripts.txt63
-rw-r--r--docs/skin.txt102
-rw-r--r--docs/title.txt123
-rw-r--r--includes/AjaxDispatcher.php23
-rw-r--r--includes/AjaxFunctions.php33
-rw-r--r--includes/AjaxResponse.php10
-rw-r--r--includes/Article.php708
-rw-r--r--includes/AuthPlugin.php4
-rw-r--r--includes/AutoLoader.php669
-rw-r--r--includes/Autopromote.php24
-rw-r--r--includes/BagOStuff.php135
-rw-r--r--includes/Block.php138
-rw-r--r--includes/CacheDependency.php46
-rw-r--r--includes/Category.php261
-rw-r--r--includes/CategoryPage.php125
-rw-r--r--includes/Categoryfinder.php2
-rw-r--r--includes/ChangesFeed.php129
-rw-r--r--includes/ChangesList.php471
-rw-r--r--includes/Credits.php4
-rw-r--r--includes/DatabaseFunctions.php4
-rw-r--r--includes/DefaultSettings.php1107
-rw-r--r--includes/Defines.php83
-rw-r--r--includes/DifferenceEngine.php367
-rw-r--r--includes/DjVuImage.php55
-rw-r--r--includes/DoubleRedirectJob.php166
-rw-r--r--includes/EditPage.php590
-rw-r--r--includes/EmaillingJob.php5
-rw-r--r--includes/EnotifNotifyJob.php24
-rw-r--r--includes/Exception.php91
-rw-r--r--includes/Exif.php15
-rw-r--r--includes/Export.php149
-rw-r--r--includes/ExternalEdit.php3
-rw-r--r--includes/ExternalStore.php34
-rw-r--r--includes/ExternalStoreDB.php20
-rw-r--r--includes/ExternalStoreHttp.php5
-rw-r--r--includes/FakeTitle.php2
-rw-r--r--includes/Feed.php2
-rw-r--r--includes/FeedUtils.php152
-rw-r--r--includes/FileDeleteForm.php142
-rw-r--r--includes/FileRevertForm.php91
-rw-r--r--includes/FileStore.php80
-rw-r--r--includes/FormOptions.php202
-rw-r--r--includes/GlobalFunctions.php632
-rw-r--r--includes/HTMLCacheUpdate.php33
-rw-r--r--includes/HTMLFileCache.php17
-rw-r--r--includes/HistoryBlob.php8
-rw-r--r--includes/Hooks.php7
-rw-r--r--includes/HttpFunctions.php3
-rw-r--r--includes/IP.php34
-rw-r--r--includes/ImageFunctions.php13
-rw-r--r--includes/ImageGallery.php29
-rw-r--r--includes/ImagePage.php647
-rw-r--r--includes/ImageQueryPage.php5
-rw-r--r--includes/JobQueue.php57
-rw-r--r--includes/Licenses.php5
-rw-r--r--includes/LinkBatch.php64
-rw-r--r--includes/LinkCache.php121
-rw-r--r--includes/LinkFilter.php1
-rw-r--r--includes/Linker.php464
-rw-r--r--includes/LinksUpdate.php227
-rw-r--r--includes/LogEventsList.php742
-rw-r--r--includes/LogPage.php112
-rw-r--r--includes/MacBinary.php4
-rw-r--r--includes/MagicWord.php68
-rw-r--r--includes/Math.php9
-rw-r--r--includes/MediaTransformOutput.php51
-rw-r--r--includes/MemcachedSessions.php4
-rw-r--r--includes/MessageCache.php726
-rw-r--r--includes/Metadata.php4
-rw-r--r--includes/MimeMagic.php51
-rw-r--r--includes/Namespace.php55
-rw-r--r--includes/NamespaceCompat.php9
-rw-r--r--includes/ObjectCache.php11
-rw-r--r--includes/OutputHandler.php16
-rw-r--r--includes/OutputPage.php451
-rw-r--r--includes/PageHistory.php258
-rw-r--r--includes/PageQueryPage.php9
-rw-r--r--includes/Pager.php260
-rw-r--r--includes/PatrolLog.php6
-rw-r--r--includes/PrefixSearch.php85
-rw-r--r--includes/Profiler.php243
-rw-r--r--includes/ProfilerSimple.php17
-rw-r--r--includes/ProfilerSimpleText.php35
-rw-r--r--includes/ProfilerSimpleUDP.php11
-rw-r--r--includes/ProfilerStub.php46
-rw-r--r--includes/ProtectionForm.php221
-rw-r--r--includes/ProxyTools.php48
-rw-r--r--includes/QueryPage.php56
-rw-r--r--includes/RawPage.php20
-rw-r--r--includes/RecentChange.php125
-rw-r--r--includes/RefreshLinksJob.php5
-rw-r--r--includes/Revision.php283
-rw-r--r--includes/Sanitizer.php35
-rw-r--r--includes/SearchEngine.php831
-rw-r--r--includes/SearchMySQL.php71
-rw-r--r--includes/SearchMySQL4.php60
-rw-r--r--includes/SearchOracle.php13
-rw-r--r--includes/SearchPostgres.php36
-rw-r--r--includes/SearchUpdate.php10
-rw-r--r--includes/Setup.php78
-rw-r--r--includes/SiteConfiguration.php10
-rw-r--r--includes/SiteStats.php19
-rw-r--r--includes/Skin.php229
-rw-r--r--includes/SkinTemplate.php167
-rw-r--r--includes/SpecialPage.php170
-rw-r--r--includes/SquidUpdate.php19
-rw-r--r--includes/Status.php194
-rw-r--r--includes/StreamFile.php8
-rw-r--r--includes/StringUtils.php49
-rw-r--r--includes/StubObject.php98
-rw-r--r--includes/Title.php619
-rw-r--r--includes/User.php905
-rw-r--r--includes/UserArray.php62
-rw-r--r--includes/UserMailer.php85
-rw-r--r--includes/UserRightsProxy.php45
-rw-r--r--includes/WatchedItem.php13
-rw-r--r--includes/WatchlistEditor.php105
-rw-r--r--includes/WebRequest.php150
-rw-r--r--includes/WebResponse.php2
-rw-r--r--includes/WebStart.php39
-rw-r--r--includes/Wiki.php281
-rw-r--r--includes/WikiError.php19
-rw-r--r--includes/Xml.php279
-rw-r--r--includes/XmlFunctions.php6
-rw-r--r--includes/XmlTypeCheck.php22
-rw-r--r--includes/ZhClient.php17
-rw-r--r--includes/ZhConversion.php4946
-rw-r--r--includes/api/ApiBase.php134
-rw-r--r--includes/api/ApiBlock.php10
-rw-r--r--includes/api/ApiDelete.php117
-rw-r--r--includes/api/ApiEditPage.php299
-rw-r--r--includes/api/ApiEmailUser.php114
-rw-r--r--includes/api/ApiExpandTemplates.php38
-rw-r--r--includes/api/ApiFeedWatchlist.php33
-rw-r--r--includes/api/ApiFormatBase.php51
-rw-r--r--includes/api/ApiFormatDbg.php5
-rw-r--r--includes/api/ApiFormatJson.php7
-rw-r--r--includes/api/ApiFormatJson_json.php19
-rw-r--r--includes/api/ApiFormatPhp.php5
-rw-r--r--includes/api/ApiFormatTxt.php5
-rw-r--r--includes/api/ApiFormatWddx.php5
-rw-r--r--includes/api/ApiFormatXml.php34
-rw-r--r--includes/api/ApiFormatYaml.php5
-rw-r--r--includes/api/ApiFormatYaml_spyc.php235
-rw-r--r--includes/api/ApiHelp.php7
-rw-r--r--includes/api/ApiLogin.php73
-rw-r--r--includes/api/ApiLogout.php10
-rw-r--r--includes/api/ApiMain.php150
-rw-r--r--includes/api/ApiMove.php50
-rw-r--r--includes/api/ApiOpenSearch.php22
-rw-r--r--includes/api/ApiPageSet.php200
-rw-r--r--includes/api/ApiParamInfo.php11
-rw-r--r--includes/api/ApiParse.php83
-rw-r--r--includes/api/ApiProtect.php15
-rw-r--r--includes/api/ApiQuery.php67
-rw-r--r--includes/api/ApiQueryAllCategories.php63
-rw-r--r--includes/api/ApiQueryAllLinks.php49
-rw-r--r--includes/api/ApiQueryAllUsers.php81
-rw-r--r--includes/api/ApiQueryAllimages.php205
-rw-r--r--includes/api/ApiQueryAllmessages.php25
-rw-r--r--includes/api/ApiQueryAllpages.php48
-rw-r--r--includes/api/ApiQueryBacklinks.php371
-rw-r--r--includes/api/ApiQueryBase.php208
-rw-r--r--includes/api/ApiQueryBlocks.php59
-rw-r--r--includes/api/ApiQueryCategories.php73
-rw-r--r--includes/api/ApiQueryCategoryInfo.php91
-rw-r--r--includes/api/ApiQueryCategoryMembers.php75
-rw-r--r--includes/api/ApiQueryDeletedrevs.php30
-rw-r--r--includes/api/ApiQueryExtLinksUsage.php65
-rw-r--r--includes/api/ApiQueryExternalLinks.php51
-rw-r--r--includes/api/ApiQueryImageInfo.php162
-rw-r--r--includes/api/ApiQueryImages.php70
-rw-r--r--includes/api/ApiQueryInfo.php344
-rw-r--r--includes/api/ApiQueryLangLinks.php61
-rw-r--r--includes/api/ApiQueryLinks.php78
-rw-r--r--includes/api/ApiQueryLogEvents.php57
-rw-r--r--includes/api/ApiQueryRandom.php16
-rw-r--r--includes/api/ApiQueryRecentChanges.php120
-rw-r--r--includes/api/ApiQueryRevisions.php183
-rw-r--r--includes/api/ApiQuerySearch.php19
-rw-r--r--includes/api/ApiQuerySiteinfo.php304
-rw-r--r--includes/api/ApiQueryUserContributions.php69
-rw-r--r--includes/api/ApiQueryUserInfo.php18
-rw-r--r--includes/api/ApiQueryUsers.php47
-rw-r--r--includes/api/ApiQueryWatchlist.php29
-rw-r--r--includes/api/ApiResult.php36
-rw-r--r--includes/api/ApiRollback.php13
-rw-r--r--includes/api/ApiUnblock.php11
-rw-r--r--includes/api/ApiUndelete.php17
-rw-r--r--includes/cbt/CBTCompiler.php35
-rw-r--r--includes/cbt/CBTProcessor.php81
-rw-r--r--includes/cbt/README44
-rw-r--r--includes/db/Database.php2699
-rw-r--r--includes/db/DatabaseMssql.php1029
-rw-r--r--includes/db/DatabaseOracle.php720
-rw-r--r--includes/db/DatabasePostgres.php1394
-rw-r--r--includes/db/DatabaseSqlite.php405
-rw-r--r--includes/db/LBFactory.php261
-rw-r--r--includes/db/LBFactory_Multi.php233
-rw-r--r--includes/db/LoadBalancer.php918
-rw-r--r--includes/db/LoadMonitor.php121
-rw-r--r--includes/filerepo/ArchivedFile.php72
-rw-r--r--includes/filerepo/FSRepo.php44
-rw-r--r--includes/filerepo/File.php221
-rw-r--r--includes/filerepo/FileRepo.php174
-rw-r--r--includes/filerepo/FileRepoStatus.php151
-rw-r--r--includes/filerepo/ForeignAPIFile.php101
-rw-r--r--includes/filerepo/ForeignAPIRepo.php110
-rw-r--r--includes/filerepo/ForeignDBFile.php33
-rw-r--r--includes/filerepo/ForeignDBRepo.php13
-rw-r--r--includes/filerepo/ForeignDBViaLBRepo.php39
-rw-r--r--includes/filerepo/Image.php74
-rw-r--r--includes/filerepo/LocalFile.php533
-rw-r--r--includes/filerepo/LocalRepo.php103
-rw-r--r--includes/filerepo/NullRepo.php8
-rw-r--r--includes/filerepo/OldLocalFile.php192
-rw-r--r--includes/filerepo/README14
-rw-r--r--includes/filerepo/RepoGroup.php74
-rw-r--r--includes/filerepo/UnregisteredLocalFile.php9
-rw-r--r--includes/media/BMP.php8
-rw-r--r--includes/media/Bitmap.php22
-rw-r--r--includes/media/DjVu.php20
-rw-r--r--includes/media/Generic.php56
-rw-r--r--includes/media/SVG.php18
-rw-r--r--includes/memcached-client.php79
-rw-r--r--includes/mime.info15
-rw-r--r--includes/mime.types9
-rw-r--r--includes/normal/CleanUpTest.php3
-rw-r--r--includes/normal/Makefile9
-rw-r--r--includes/normal/RandomTest.php4
-rw-r--r--includes/normal/Utf8Case.php2078
-rw-r--r--includes/normal/Utf8CaseGenerate.php112
-rw-r--r--includes/normal/Utf8Test.php4
-rw-r--r--includes/normal/UtfNormal.php56
-rw-r--r--includes/normal/UtfNormalBench.php4
-rw-r--r--includes/normal/UtfNormalData.inc2
-rw-r--r--includes/normal/UtfNormalDataK.inc2
-rw-r--r--includes/normal/UtfNormalDefines.php53
-rw-r--r--includes/normal/UtfNormalGenerate.php4
-rw-r--r--includes/normal/UtfNormalTest.php4
-rw-r--r--includes/normal/UtfNormalUtil.php5
-rw-r--r--includes/parser/CoreParserFunctions.php385
-rw-r--r--includes/parser/DateFormatter.php283
-rw-r--r--includes/parser/Parser.php5002
-rw-r--r--includes/parser/ParserCache.php116
-rw-r--r--includes/parser/ParserOptions.php149
-rw-r--r--includes/parser/ParserOutput.php206
-rw-r--r--includes/parser/Parser_DiffTest.php87
-rw-r--r--includes/parser/Parser_OldPP.php4944
-rw-r--r--includes/parser/Preprocessor.php163
-rw-r--r--includes/parser/Preprocessor_DOM.php1421
-rw-r--r--includes/parser/Preprocessor_Hash.php1539
-rw-r--r--includes/proxy_check.php2
-rw-r--r--includes/specials/SpecialAllmessages.php217
-rw-r--r--includes/specials/SpecialAllpages.php404
-rw-r--r--includes/specials/SpecialAncientpages.php60
-rw-r--r--includes/specials/SpecialBlankpage.php6
-rw-r--r--includes/specials/SpecialBlockip.php494
-rw-r--r--includes/specials/SpecialBlockme.php37
-rw-r--r--includes/specials/SpecialBooksources.php110
-rw-r--r--includes/specials/SpecialBrokenRedirects.php93
-rw-r--r--includes/specials/SpecialCategories.php112
-rw-r--r--includes/specials/SpecialConfirmemail.php139
-rw-r--r--includes/specials/SpecialContributions.php470
-rw-r--r--includes/specials/SpecialDeadendpages.php62
-rw-r--r--includes/specials/SpecialDisambiguations.php108
-rw-r--r--includes/specials/SpecialDoubleRedirects.php103
-rw-r--r--includes/specials/SpecialEmailuser.php286
-rw-r--r--includes/specials/SpecialExport.php284
-rw-r--r--includes/specials/SpecialFewestrevisions.php74
-rw-r--r--includes/specials/SpecialFileDuplicateSearch.php135
-rw-r--r--includes/specials/SpecialFilepath.php53
-rw-r--r--includes/specials/SpecialImagelist.php161
-rw-r--r--includes/specials/SpecialImport.php1154
-rw-r--r--includes/specials/SpecialIpblocklist.php427
-rw-r--r--includes/specials/SpecialListgrouprights.php112
-rw-r--r--includes/specials/SpecialListredirects.php58
-rw-r--r--includes/specials/SpecialListusers.php235
-rw-r--r--includes/specials/SpecialLockdb.php131
-rw-r--r--includes/specials/SpecialLog.php65
-rw-r--r--includes/specials/SpecialLonelypages.php58
-rw-r--r--includes/specials/SpecialLongpages.php31
-rw-r--r--includes/specials/SpecialMIMEsearch.php138
-rw-r--r--includes/specials/SpecialMergeHistory.php448
-rw-r--r--includes/specials/SpecialMostcategories.php58
-rw-r--r--includes/specials/SpecialMostimages.php54
-rw-r--r--includes/specials/SpecialMostlinked.php95
-rw-r--r--includes/specials/SpecialMostlinkedcategories.php78
-rw-r--r--includes/specials/SpecialMostlinkedtemplates.php132
-rw-r--r--includes/specials/SpecialMostrevisions.php64
-rw-r--r--includes/specials/SpecialMovepage.php452
-rw-r--r--includes/specials/SpecialNewimages.php211
-rw-r--r--includes/specials/SpecialNewpages.php437
-rw-r--r--includes/specials/SpecialPopularpages.php67
-rw-r--r--includes/specials/SpecialPreferences.php1126
-rw-r--r--includes/specials/SpecialPrefixindex.php152
-rw-r--r--includes/specials/SpecialProtectedpages.php309
-rw-r--r--includes/specials/SpecialProtectedtitles.php216
-rw-r--r--includes/specials/SpecialRandompage.php100
-rw-r--r--includes/specials/SpecialRandomredirect.php19
-rw-r--r--includes/specials/SpecialRecentchanges.php662
-rw-r--r--includes/specials/SpecialRecentchangeslinked.php178
-rw-r--r--includes/specials/SpecialResetpass.php167
-rw-r--r--includes/specials/SpecialRevisiondelete.php1474
-rw-r--r--includes/specials/SpecialSearch.php651
-rw-r--r--includes/specials/SpecialShortpages.php98
-rw-r--r--includes/specials/SpecialSpecialpages.php82
-rw-r--r--includes/specials/SpecialStatistics.php93
-rw-r--r--includes/specials/SpecialUncategorizedcategories.php30
-rw-r--r--includes/specials/SpecialUncategorizedimages.php48
-rw-r--r--includes/specials/SpecialUncategorizedpages.php55
-rw-r--r--includes/specials/SpecialUncategorizedtemplates.php33
-rw-r--r--includes/specials/SpecialUndelete.php1276
-rw-r--r--includes/specials/SpecialUnlockdb.php107
-rw-r--r--includes/specials/SpecialUnusedcategories.php46
-rw-r--r--includes/specials/SpecialUnusedimages.php60
-rw-r--r--includes/specials/SpecialUnusedtemplates.php54
-rw-r--r--includes/specials/SpecialUnwatchedpages.php68
-rw-r--r--includes/specials/SpecialUpload.php1755
-rw-r--r--includes/specials/SpecialUploadMogile.php135
-rw-r--r--includes/specials/SpecialUserlogin.php929
-rw-r--r--includes/specials/SpecialUserlogout.php23
-rw-r--r--includes/specials/SpecialUserrights.php589
-rw-r--r--includes/specials/SpecialVersion.php391
-rw-r--r--includes/specials/SpecialWantedcategories.php90
-rw-r--r--includes/specials/SpecialWantedpages.php131
-rw-r--r--includes/specials/SpecialWatchlist.php383
-rw-r--r--includes/specials/SpecialWhatlinkshere.php408
-rw-r--r--includes/specials/SpecialWithoutinterwiki.php88
-rw-r--r--includes/templates/NoLocalSettings.php5
-rw-r--r--includes/templates/Userlogin.php68
-rw-r--r--includes/tidy.conf6
-rw-r--r--includes/zhtable/Makefile118
-rw-r--r--includes/zhtable/README21
-rw-r--r--includes/zhtable/simp2trad.manual96
-rw-r--r--includes/zhtable/simp2trad_noconvert.manual4
-rw-r--r--includes/zhtable/simp2trad_supp_set.manual2
-rw-r--r--includes/zhtable/simpphrases.manual389
-rw-r--r--includes/zhtable/simpphrases_exclude.manual0
-rw-r--r--includes/zhtable/toCN.manual11
-rw-r--r--includes/zhtable/toHK.manual10
-rw-r--r--includes/zhtable/toSG.manual6
-rw-r--r--includes/zhtable/toSimp.manual21
-rw-r--r--includes/zhtable/toTW.manual34
-rw-r--r--includes/zhtable/toTrad.manual42
-rw-r--r--includes/zhtable/trad2simp.manual11
-rw-r--r--includes/zhtable/trad2simp_noconvert.manual4
-rw-r--r--includes/zhtable/trad2simp_supp_set.manual1
-rw-r--r--includes/zhtable/trad2simp_supp_unset.manual0
-rw-r--r--includes/zhtable/tradphrases.manual1522
-rw-r--r--includes/zhtable/tradphrases_exclude.manual161
-rw-r--r--index.php33
-rw-r--r--install-utils.inc4
-rw-r--r--languages/Language.php445
-rw-r--r--languages/LanguageConverter.php896
-rw-r--r--languages/Names.php45
-rw-r--r--languages/classes/LanguageAr.php4
-rw-r--r--languages/classes/LanguageAz.php4
-rw-r--r--languages/classes/LanguageBat_smg.php5
-rw-r--r--languages/classes/LanguageBe.php5
-rw-r--r--languages/classes/LanguageBe_tarask.php26
-rw-r--r--languages/classes/LanguageBg.php8
-rw-r--r--languages/classes/LanguageBs.php11
-rw-r--r--languages/classes/LanguageCs.php71
-rw-r--r--languages/classes/LanguageCu.php11
-rw-r--r--languages/classes/LanguageCy.php2
-rw-r--r--languages/classes/LanguageDsb.php6
-rw-r--r--languages/classes/LanguageEo.php9
-rw-r--r--languages/classes/LanguageEt.php5
-rw-r--r--languages/classes/LanguageFi.php16
-rw-r--r--languages/classes/LanguageFr.php7
-rw-r--r--languages/classes/LanguageGa.php7
-rw-r--r--languages/classes/LanguageGsw.php9
-rw-r--r--languages/classes/LanguageHe.php6
-rw-r--r--languages/classes/LanguageHr.php5
-rw-r--r--languages/classes/LanguageHsb.php4
-rw-r--r--languages/classes/LanguageHu.php10
-rw-r--r--languages/classes/LanguageHy.php12
-rw-r--r--languages/classes/LanguageJa.php5
-rw-r--r--languages/classes/LanguageKaa.php31
-rw-r--r--languages/classes/LanguageKk.deps.php4
-rw-r--r--languages/classes/LanguageKk.php51
-rw-r--r--languages/classes/LanguageKk_cyrl.php22
-rw-r--r--languages/classes/LanguageKm.php17
-rw-r--r--languages/classes/LanguageKsh.php5
-rw-r--r--languages/classes/LanguageKu.deps.php5
-rw-r--r--languages/classes/LanguageKu.php29
-rw-r--r--languages/classes/LanguageKu_ku.php12
-rw-r--r--languages/classes/LanguageLa.php12
-rw-r--r--languages/classes/LanguageLt.php6
-rw-r--r--languages/classes/LanguageLv.php8
-rw-r--r--languages/classes/LanguageMt.php22
-rw-r--r--languages/classes/LanguagePl.php6
-rw-r--r--languages/classes/LanguagePt_br.php6
-rw-r--r--languages/classes/LanguageRmy.php5
-rw-r--r--languages/classes/LanguageRu.php7
-rw-r--r--languages/classes/LanguageSk.php5
-rw-r--r--languages/classes/LanguageSl.php7
-rw-r--r--languages/classes/LanguageSr.deps.php3
-rw-r--r--languages/classes/LanguageSr.php45
-rw-r--r--languages/classes/LanguageSr_ec.php12
-rw-r--r--languages/classes/LanguageSr_el.deps.php1
-rw-r--r--languages/classes/LanguageSr_el.php12
-rw-r--r--languages/classes/LanguageTg.php104
-rw-r--r--languages/classes/LanguageTr.php5
-rw-r--r--languages/classes/LanguageTyv.php18
-rw-r--r--languages/classes/LanguageUk.php15
-rw-r--r--languages/classes/LanguageWa.php10
-rw-r--r--languages/classes/LanguageYue.php4
-rw-r--r--languages/classes/LanguageZh.deps.php2
-rw-r--r--languages/classes/LanguageZh.php91
-rw-r--r--languages/classes/LanguageZh_hans.php5
-rw-r--r--languages/messages/MessagesAb.php13
-rw-r--r--languages/messages/MessagesAf.php1808
-rw-r--r--languages/messages/MessagesAk.php5
-rw-r--r--languages/messages/MessagesAln.php337
-rw-r--r--languages/messages/MessagesAls.php9
-rw-r--r--languages/messages/MessagesAm.php1838
-rw-r--r--languages/messages/MessagesAn.php1245
-rw-r--r--languages/messages/MessagesAng.php234
-rw-r--r--languages/messages/MessagesAr.php2068
-rw-r--r--languages/messages/MessagesArc.php39
-rw-r--r--languages/messages/MessagesArn.php108
-rw-r--r--languages/messages/MessagesArz.php2860
-rw-r--r--languages/messages/MessagesAs.php1007
-rw-r--r--languages/messages/MessagesAst.php1186
-rw-r--r--languages/messages/MessagesAv.php32
-rw-r--r--languages/messages/MessagesAvk.php960
-rw-r--r--languages/messages/MessagesAy.php26
-rw-r--r--languages/messages/MessagesAz.php128
-rw-r--r--languages/messages/MessagesBa.php167
-rw-r--r--languages/messages/MessagesBar.php36
-rw-r--r--languages/messages/MessagesBat_smg.php1446
-rw-r--r--languages/messages/MessagesBcc.php2838
-rw-r--r--languages/messages/MessagesBcl.php1248
-rw-r--r--languages/messages/MessagesBe.php1423
-rw-r--r--languages/messages/MessagesBe_tarask.php2244
-rw-r--r--languages/messages/MessagesBe_x_old.php9
-rw-r--r--languages/messages/MessagesBg.php1883
-rw-r--r--languages/messages/MessagesBh.php9
-rw-r--r--languages/messages/MessagesBi.php19
-rw-r--r--languages/messages/MessagesBm.php47
-rw-r--r--languages/messages/MessagesBn.php434
-rw-r--r--languages/messages/MessagesBo.php231
-rw-r--r--languages/messages/MessagesBpy.php631
-rw-r--r--languages/messages/MessagesBr.php915
-rw-r--r--languages/messages/MessagesBs.php742
-rw-r--r--languages/messages/MessagesBug.php107
-rw-r--r--languages/messages/MessagesCa.php1190
-rw-r--r--languages/messages/MessagesCbk_zam.php11
-rw-r--r--languages/messages/MessagesCdo.php152
-rw-r--r--languages/messages/MessagesCe.php58
-rw-r--r--languages/messages/MessagesCeb.php387
-rw-r--r--languages/messages/MessagesCh.php1148
-rw-r--r--languages/messages/MessagesChr.php26
-rw-r--r--languages/messages/MessagesCo.php87
-rw-r--r--languages/messages/MessagesCrh.php4
-rw-r--r--languages/messages/MessagesCrh_cyrl.php498
-rw-r--r--languages/messages/MessagesCrh_latn.php478
-rw-r--r--languages/messages/MessagesCs.php1280
-rw-r--r--languages/messages/MessagesCsb.php116
-rw-r--r--languages/messages/MessagesCu.php488
-rw-r--r--languages/messages/MessagesCv.php1236
-rw-r--r--languages/messages/MessagesCy.php1910
-rw-r--r--languages/messages/MessagesDa.php1366
-rw-r--r--languages/messages/MessagesDe.php1426
-rw-r--r--languages/messages/MessagesDe_formal.php239
-rw-r--r--languages/messages/MessagesDiq.php271
-rw-r--r--languages/messages/MessagesDk.php11
-rw-r--r--languages/messages/MessagesDsb.php1305
-rw-r--r--languages/messages/MessagesDv.php79
-rw-r--r--languages/messages/MessagesDz.php685
-rw-r--r--languages/messages/MessagesEe.php72
-rw-r--r--languages/messages/MessagesEl.php1255
-rw-r--r--languages/messages/MessagesEml.php25
-rw-r--r--languages/messages/MessagesEn.php2002
-rw-r--r--languages/messages/MessagesEnRTL.php9
-rw-r--r--languages/messages/MessagesEn_gb.php60
-rw-r--r--languages/messages/MessagesEo.php2220
-rw-r--r--languages/messages/MessagesEs.php1411
-rw-r--r--languages/messages/MessagesEt.php487
-rw-r--r--languages/messages/MessagesEu.php1370
-rw-r--r--languages/messages/MessagesExt.php808
-rw-r--r--languages/messages/MessagesFa.php1145
-rw-r--r--languages/messages/MessagesFf.php23
-rw-r--r--languages/messages/MessagesFi.php1228
-rw-r--r--languages/messages/MessagesFiu_vro.php464
-rw-r--r--languages/messages/MessagesFj.php38
-rw-r--r--languages/messages/MessagesFo.php403
-rw-r--r--languages/messages/MessagesFr.php1436
-rw-r--r--languages/messages/MessagesFrc.php117
-rw-r--r--languages/messages/MessagesFrp.php409
-rw-r--r--languages/messages/MessagesFur.php767
-rw-r--r--languages/messages/MessagesFy.php1393
-rw-r--r--languages/messages/MessagesGa.php670
-rw-r--r--languages/messages/MessagesGag.php146
-rw-r--r--languages/messages/MessagesGan.php631
-rw-r--r--languages/messages/MessagesGd.php151
-rw-r--r--languages/messages/MessagesGl.php1615
-rw-r--r--languages/messages/MessagesGlk.php19
-rw-r--r--languages/messages/MessagesGn.php462
-rw-r--r--languages/messages/MessagesGot.php476
-rw-r--r--languages/messages/MessagesGrc.php1487
-rw-r--r--languages/messages/MessagesGsw.php183
-rw-r--r--languages/messages/MessagesGu.php634
-rw-r--r--languages/messages/MessagesGv.php1062
-rw-r--r--languages/messages/MessagesHak.php401
-rw-r--r--languages/messages/MessagesHaw.php445
-rw-r--r--languages/messages/MessagesHe.php1409
-rw-r--r--languages/messages/MessagesHi.php2643
-rw-r--r--languages/messages/MessagesHif.php9
-rw-r--r--languages/messages/MessagesHif_latn.php1019
-rw-r--r--languages/messages/MessagesHil.php310
-rw-r--r--languages/messages/MessagesHr.php1143
-rw-r--r--languages/messages/MessagesHsb.php1325
-rw-r--r--languages/messages/MessagesHt.php777
-rw-r--r--languages/messages/MessagesHu.php1917
-rw-r--r--languages/messages/MessagesHy.php452
-rw-r--r--languages/messages/MessagesIa.php3042
-rw-r--r--languages/messages/MessagesId.php1174
-rw-r--r--languages/messages/MessagesIe.php247
-rw-r--r--languages/messages/MessagesIg.php12
-rw-r--r--languages/messages/MessagesIi.php7
-rw-r--r--languages/messages/MessagesIk.php11
-rw-r--r--languages/messages/MessagesIke_cans.php95
-rw-r--r--languages/messages/MessagesIke_latn.php82
-rw-r--r--languages/messages/MessagesIlo.php1988
-rw-r--r--languages/messages/MessagesInh.php49
-rw-r--r--languages/messages/MessagesIo.php763
-rw-r--r--languages/messages/MessagesIs.php1205
-rw-r--r--languages/messages/MessagesIt.php1342
-rw-r--r--languages/messages/MessagesIu.php5
-rw-r--r--languages/messages/MessagesJa.php855
-rw-r--r--languages/messages/MessagesJbo.php40
-rw-r--r--languages/messages/MessagesJut.php484
-rw-r--r--languages/messages/MessagesJv.php2568
-rw-r--r--languages/messages/MessagesKa.php516
-rw-r--r--languages/messages/MessagesKaa.php426
-rw-r--r--languages/messages/MessagesKab.php268
-rw-r--r--languages/messages/MessagesKg.php19
-rw-r--r--languages/messages/MessagesKk.php28
-rw-r--r--languages/messages/MessagesKk_arab.php2473
-rw-r--r--languages/messages/MessagesKk_cn.php12
-rw-r--r--languages/messages/MessagesKk_cyrl.php2444
-rw-r--r--languages/messages/MessagesKk_kz.php6
-rw-r--r--languages/messages/MessagesKk_latn.php2441
-rw-r--r--languages/messages/MessagesKk_tr.php8
-rw-r--r--languages/messages/MessagesKl.php108
-rw-r--r--languages/messages/MessagesKm.php2740
-rw-r--r--languages/messages/MessagesKn.php1667
-rw-r--r--languages/messages/MessagesKo.php953
-rw-r--r--languages/messages/MessagesKrj.php112
-rw-r--r--languages/messages/MessagesKs.php8
-rw-r--r--languages/messages/MessagesKsh.php2616
-rw-r--r--languages/messages/MessagesKu.php8
-rw-r--r--languages/messages/MessagesKu_arab.php25
-rw-r--r--languages/messages/MessagesKu_latn.php454
-rw-r--r--languages/messages/MessagesKv.php70
-rw-r--r--languages/messages/MessagesKw.php27
-rw-r--r--languages/messages/MessagesKy.php56
-rw-r--r--languages/messages/MessagesLa.php907
-rw-r--r--languages/messages/MessagesLad.php281
-rw-r--r--languages/messages/MessagesLb.php1996
-rw-r--r--languages/messages/MessagesLbe.php13
-rw-r--r--languages/messages/MessagesLfn.php359
-rw-r--r--languages/messages/MessagesLg.php107
-rw-r--r--languages/messages/MessagesLi.php1151
-rw-r--r--languages/messages/MessagesLij.php582
-rw-r--r--languages/messages/MessagesLld.php5
-rw-r--r--languages/messages/MessagesLmo.php237
-rw-r--r--languages/messages/MessagesLn.php287
-rw-r--r--languages/messages/MessagesLo.php673
-rw-r--r--languages/messages/MessagesLoz.php158
-rw-r--r--languages/messages/MessagesLt.php1074
-rw-r--r--languages/messages/MessagesLv.php1396
-rw-r--r--languages/messages/MessagesMai.php83
-rw-r--r--languages/messages/MessagesMap_bms.php74
-rw-r--r--languages/messages/MessagesMdf.php2008
-rw-r--r--languages/messages/MessagesMg.php195
-rw-r--r--languages/messages/MessagesMi.php29
-rw-r--r--languages/messages/MessagesMk.php1125
-rw-r--r--languages/messages/MessagesMl.php1660
-rw-r--r--languages/messages/MessagesMn.php2194
-rw-r--r--languages/messages/MessagesMo.php41
-rw-r--r--languages/messages/MessagesMr.php1257
-rw-r--r--languages/messages/MessagesMs.php1398
-rw-r--r--languages/messages/MessagesMt.php2615
-rw-r--r--languages/messages/MessagesMwl.php660
-rw-r--r--languages/messages/MessagesMy.php283
-rw-r--r--languages/messages/MessagesMyv.php1275
-rw-r--r--languages/messages/MessagesMzn.php6
-rw-r--r--languages/messages/MessagesNa.php32
-rw-r--r--languages/messages/MessagesNah.php1113
-rw-r--r--languages/messages/MessagesNan.php152
-rw-r--r--languages/messages/MessagesNap.php72
-rw-r--r--languages/messages/MessagesNb.php6
-rw-r--r--languages/messages/MessagesNds.php1775
-rw-r--r--languages/messages/MessagesNds_nl.php2254
-rw-r--r--languages/messages/MessagesNe.php82
-rw-r--r--languages/messages/MessagesNew.php139
-rw-r--r--languages/messages/MessagesNl.php1819
-rw-r--r--languages/messages/MessagesNn.php1089
-rw-r--r--languages/messages/MessagesNo.php1562
-rw-r--r--languages/messages/MessagesNov.php106
-rw-r--r--languages/messages/MessagesNso.php177
-rw-r--r--languages/messages/MessagesNv.php3
-rw-r--r--languages/messages/MessagesNy.php12
-rw-r--r--languages/messages/MessagesOc.php2302
-rw-r--r--languages/messages/MessagesOr.php9
-rw-r--r--languages/messages/MessagesOs.php467
-rw-r--r--languages/messages/MessagesPa.php408
-rw-r--r--languages/messages/MessagesPag.php68
-rw-r--r--languages/messages/MessagesPam.php2370
-rw-r--r--languages/messages/MessagesPap.php92
-rw-r--r--languages/messages/MessagesPdc.php19
-rw-r--r--languages/messages/MessagesPfl.php37
-rw-r--r--languages/messages/MessagesPi.php9
-rw-r--r--languages/messages/MessagesPih.php15
-rw-r--r--languages/messages/MessagesPl.php2775
-rw-r--r--languages/messages/MessagesPms.php474
-rw-r--r--languages/messages/MessagesPnt.php892
-rw-r--r--languages/messages/MessagesPs.php956
-rw-r--r--languages/messages/MessagesPt.php1419
-rw-r--r--languages/messages/MessagesPt_br.php2642
-rw-r--r--languages/messages/MessagesQu.php1126
-rw-r--r--languages/messages/MessagesRif.php646
-rw-r--r--languages/messages/MessagesRm.php296
-rw-r--r--languages/messages/MessagesRmy.php105
-rw-r--r--languages/messages/MessagesRo.php1711
-rw-r--r--languages/messages/MessagesRoa_rup.php44
-rw-r--r--languages/messages/MessagesRu.php1588
-rw-r--r--languages/messages/MessagesRuq.php5
-rw-r--r--languages/messages/MessagesRuq_cyrl.php122
-rw-r--r--languages/messages/MessagesRuq_grek.php5
-rw-r--r--languages/messages/MessagesRuq_latn.php122
-rw-r--r--languages/messages/MessagesSa.php41
-rw-r--r--languages/messages/MessagesSah.php1190
-rw-r--r--languages/messages/MessagesSc.php155
-rw-r--r--languages/messages/MessagesScn.php900
-rw-r--r--languages/messages/MessagesSco.php232
-rw-r--r--languages/messages/MessagesSd.php840
-rw-r--r--languages/messages/MessagesSdc.php473
-rw-r--r--languages/messages/MessagesSe.php221
-rw-r--r--languages/messages/MessagesSei.php208
-rw-r--r--languages/messages/MessagesSg.php7
-rw-r--r--languages/messages/MessagesShi.php134
-rw-r--r--languages/messages/MessagesSi.php268
-rw-r--r--languages/messages/MessagesSimple.php10
-rw-r--r--languages/messages/MessagesSk.php1279
-rw-r--r--languages/messages/MessagesSl.php336
-rw-r--r--languages/messages/MessagesSm.php64
-rw-r--r--languages/messages/MessagesSma.php268
-rw-r--r--languages/messages/MessagesSn.php31
-rw-r--r--languages/messages/MessagesSo.php110
-rw-r--r--languages/messages/MessagesSq.php1238
-rw-r--r--languages/messages/MessagesSr.php4
-rw-r--r--languages/messages/MessagesSr_ec.php1308
-rw-r--r--languages/messages/MessagesSr_el.php287
-rw-r--r--languages/messages/MessagesSrn.php1186
-rw-r--r--languages/messages/MessagesSs.php102
-rw-r--r--languages/messages/MessagesSt.php23
-rw-r--r--languages/messages/MessagesStq.php1270
-rw-r--r--languages/messages/MessagesSu.php1352
-rw-r--r--languages/messages/MessagesSv.php1745
-rw-r--r--languages/messages/MessagesSw.php226
-rw-r--r--languages/messages/MessagesSzl.php2465
-rw-r--r--languages/messages/MessagesTa.php1622
-rw-r--r--languages/messages/MessagesTe.php1218
-rw-r--r--languages/messages/MessagesTet.php335
-rw-r--r--languages/messages/MessagesTg.php2343
-rw-r--r--languages/messages/MessagesTg_cyrl.php2420
-rw-r--r--languages/messages/MessagesTh.php978
-rw-r--r--languages/messages/MessagesTi.php35
-rw-r--r--languages/messages/MessagesTk.php165
-rw-r--r--languages/messages/MessagesTl.php193
-rw-r--r--languages/messages/MessagesTlh.php10
-rw-r--r--languages/messages/MessagesTn.php40
-rw-r--r--languages/messages/MessagesTo.php194
-rw-r--r--languages/messages/MessagesTokipona.php43
-rw-r--r--languages/messages/MessagesTp.php10
-rw-r--r--languages/messages/MessagesTpi.php64
-rw-r--r--languages/messages/MessagesTr.php1358
-rw-r--r--languages/messages/MessagesTs.php356
-rw-r--r--languages/messages/MessagesTt.php700
-rw-r--r--languages/messages/MessagesTt_cyrl.php1024
-rw-r--r--languages/messages/MessagesTt_latn.php727
-rw-r--r--languages/messages/MessagesTy.php39
-rw-r--r--languages/messages/MessagesTyv.php113
-rw-r--r--languages/messages/MessagesUdm.php66
-rw-r--r--languages/messages/MessagesUg.php22
-rw-r--r--languages/messages/MessagesUk.php2438
-rw-r--r--languages/messages/MessagesUr.php149
-rw-r--r--languages/messages/MessagesUz.php264
-rw-r--r--languages/messages/MessagesVe.php8
-rw-r--r--languages/messages/MessagesVec.php2893
-rw-r--r--languages/messages/MessagesVi.php1377
-rw-r--r--languages/messages/MessagesVls.php11
-rw-r--r--languages/messages/MessagesVo.php1260
-rw-r--r--languages/messages/MessagesWa.php280
-rw-r--r--languages/messages/MessagesWar.php98
-rw-r--r--languages/messages/MessagesWo.php751
-rw-r--r--languages/messages/MessagesWuu.php138
-rw-r--r--languages/messages/MessagesXal.php9
-rw-r--r--languages/messages/MessagesXh.php33
-rw-r--r--languages/messages/MessagesXmf.php583
-rw-r--r--languages/messages/MessagesYdd.php5
-rw-r--r--languages/messages/MessagesYi.php1188
-rw-r--r--languages/messages/MessagesYo.php158
-rw-r--r--languages/messages/MessagesYue.php1190
-rw-r--r--languages/messages/MessagesZa.php35
-rw-r--r--languages/messages/MessagesZea.php1092
-rw-r--r--languages/messages/MessagesZh.php50
-rw-r--r--languages/messages/MessagesZh_classical.php1077
-rw-r--r--languages/messages/MessagesZh_cn.php10
-rw-r--r--languages/messages/MessagesZh_hans.php1149
-rw-r--r--languages/messages/MessagesZh_hant.php1150
-rw-r--r--languages/messages/MessagesZh_hk.php7
-rw-r--r--languages/messages/MessagesZh_min_nan.php8
-rw-r--r--languages/messages/MessagesZh_mo.php10
-rw-r--r--languages/messages/MessagesZh_my.php10
-rw-r--r--languages/messages/MessagesZh_sg.php9
-rw-r--r--languages/messages/MessagesZh_tw.php304
-rw-r--r--languages/messages/MessagesZh_yue.php8
-rw-r--r--languages/messages/MessagesZu.php36
-rw-r--r--maintenance/Doxyfile12
-rw-r--r--maintenance/FiveUpgrade.inc24
-rw-r--r--maintenance/Makefile13
-rw-r--r--maintenance/README25
-rw-r--r--maintenance/addwiki.php58
-rw-r--r--maintenance/archives/patch-ar_parent_id.sql3
-rw-r--r--maintenance/archives/patch-category.sql17
-rw-r--r--maintenance/archives/patch-filearhive-user-index.sql5
-rw-r--r--maintenance/archives/patch-hitcounter.sql2
-rw-r--r--maintenance/archives/patch-ipb_by_text.sql10
-rw-r--r--maintenance/archives/patch-page_props.sql9
-rw-r--r--maintenance/archives/patch-profiling-memory.sql2
-rw-r--r--maintenance/archives/patch-profiling.sql3
-rw-r--r--maintenance/archives/patch-protected_titles.sql2
-rw-r--r--maintenance/archives/patch-pt_title-encoding.sql5
-rw-r--r--maintenance/archives/patch-searchindex.sql2
-rw-r--r--maintenance/archives/patch-updatelog.sql4
-rw-r--r--maintenance/archives/patch-user_last_timestamp.sql3
-rw-r--r--maintenance/archives/populateSha1.php8
-rw-r--r--maintenance/archives/rebuildRecentchanges.inc6
-rw-r--r--maintenance/archives/upgradeLogging.php189
-rw-r--r--maintenance/archives/upgradeWatchlist.php5
-rw-r--r--maintenance/attachLatest.php3
-rw-r--r--maintenance/attribute.php4
-rw-r--r--maintenance/backup.inc13
-rw-r--r--maintenance/backupPrefetch.inc3
-rw-r--r--maintenance/benchmarkPurge.php4
-rw-r--r--maintenance/changePassword.php21
-rw-r--r--maintenance/checkAutoLoader.php22
-rw-r--r--maintenance/checkUsernames.php8
-rw-r--r--maintenance/cleanupCaps.php8
-rw-r--r--maintenance/cleanupDupes.inc5
-rw-r--r--maintenance/cleanupImages.php6
-rw-r--r--maintenance/cleanupSpam.php6
-rw-r--r--maintenance/cleanupTable.inc5
-rw-r--r--maintenance/cleanupTitles.php8
-rw-r--r--maintenance/cleanupWatchlist.php6
-rw-r--r--maintenance/clear_interwiki_cache.php4
-rw-r--r--maintenance/clear_stats.php7
-rw-r--r--maintenance/commandLine.inc66
-rw-r--r--maintenance/convertLinks.inc7
-rw-r--r--maintenance/convertLinks.php5
-rw-r--r--maintenance/counter.php7
-rw-r--r--maintenance/createAndPromote.php3
-rw-r--r--maintenance/deleteArchivedFiles.inc22
-rw-r--r--maintenance/deleteArchivedFiles.php3
-rw-r--r--maintenance/deleteArchivedRevisions.inc5
-rw-r--r--maintenance/deleteArchivedRevisions.php5
-rw-r--r--maintenance/deleteBatch.php19
-rw-r--r--maintenance/deleteDefaultMessages.php3
-rw-r--r--maintenance/deleteImageMemcached.php14
-rw-r--r--maintenance/deleteOldRevisions.inc6
-rw-r--r--maintenance/deleteOldRevisions.php3
-rw-r--r--maintenance/deleteOrphanedRevisions.inc.php3
-rw-r--r--maintenance/deleteOrphanedRevisions.php3
-rw-r--r--maintenance/deleteRevision.php7
-rw-r--r--maintenance/dumpBackup.php9
-rw-r--r--maintenance/dumpInterwiki.inc13
-rw-r--r--maintenance/dumpInterwiki.php4
-rw-r--r--maintenance/dumpLinks.php3
-rw-r--r--maintenance/dumpSisterSites.php3
-rw-r--r--maintenance/dumpTextPass.php13
-rw-r--r--maintenance/dumpUploads.php4
-rw-r--r--maintenance/edit.php4
-rw-r--r--maintenance/eval.php34
-rw-r--r--maintenance/fetchText.php11
-rw-r--r--maintenance/findhooks.php62
-rw-r--r--maintenance/fixSlaveDesync.php10
-rw-r--r--maintenance/fixTimestamps.php4
-rw-r--r--maintenance/fixUserRegistration.php3
-rw-r--r--maintenance/fuzz-tester.php5
-rw-r--r--maintenance/generateSitemap.php47
-rw-r--r--maintenance/getLagTimes.php12
-rw-r--r--maintenance/getSlaveServer.php19
-rw-r--r--maintenance/importDump.php33
-rw-r--r--maintenance/importImages.inc.php3
-rw-r--r--maintenance/importImages.php3
-rw-r--r--maintenance/importLogs.inc7
-rw-r--r--maintenance/importLogs.php3
-rw-r--r--maintenance/importTextFile.php3
-rw-r--r--maintenance/importUseModWiki.php3
-rw-r--r--maintenance/initEditCount.php4
-rw-r--r--maintenance/initStats.inc6
-rw-r--r--maintenance/initStats.php3
-rw-r--r--maintenance/installExtension.php58
-rw-r--r--maintenance/interwiki.sql117
-rw-r--r--maintenance/language/StatOutputs.php2
-rw-r--r--maintenance/language/alltrans.php3
-rw-r--r--maintenance/language/checkExtensions.php268
-rw-r--r--maintenance/language/checkLanguage.inc476
-rw-r--r--maintenance/language/checkLanguage.php306
-rw-r--r--maintenance/language/date-formats.php4
-rw-r--r--maintenance/language/diffLanguage.php3
-rw-r--r--maintenance/language/digit2html.php5
-rw-r--r--maintenance/language/dumpMessages.php3
-rw-r--r--maintenance/language/function-list.php4
-rw-r--r--maintenance/language/lang2po.php3
-rw-r--r--maintenance/language/langmemusage.php3
-rw-r--r--maintenance/language/languages.inc47
-rw-r--r--maintenance/language/messageTypes.inc83
-rw-r--r--maintenance/language/messages.inc430
-rw-r--r--maintenance/language/rebuildLanguage.php23
-rw-r--r--maintenance/language/transstat.php3
-rw-r--r--maintenance/language/validate.php4
-rw-r--r--maintenance/language/writeMessagesArray.inc50
-rw-r--r--maintenance/mcc.php3
-rw-r--r--maintenance/mctest.php9
-rw-r--r--maintenance/moveBatch.php3
-rw-r--r--maintenance/mssql/README78
-rw-r--r--maintenance/mssql/tables.sql395
-rw-r--r--maintenance/mwdocgen.php158
-rw-r--r--maintenance/namespace2sql.php10
-rw-r--r--maintenance/namespaceDupes.php5
-rw-r--r--maintenance/nextJobDB.php18
-rw-r--r--maintenance/nukeNS.php3
-rw-r--r--maintenance/nukePage.inc3
-rw-r--r--maintenance/nukePage.php3
-rw-r--r--maintenance/orphans.php3
-rw-r--r--maintenance/ourusers.php15
-rw-r--r--maintenance/parserTests.inc582
-rw-r--r--maintenance/parserTests.php3
-rw-r--r--maintenance/parserTests.txt179
-rw-r--r--maintenance/parserTestsParserHook.php3
-rw-r--r--maintenance/parserTestsParserTime.php3
-rw-r--r--maintenance/parserTestsStaticParserHook.php3
-rw-r--r--maintenance/patchSql.php36
-rw-r--r--maintenance/populateCategory.inc85
-rw-r--r--maintenance/populateCategory.php52
-rw-r--r--maintenance/populateParentId.inc83
-rw-r--r--maintenance/populateParentId.php18
-rw-r--r--maintenance/postgres/archives/patch-category.sql15
-rw-r--r--maintenance/postgres/archives/patch-page_props.sql9
-rw-r--r--maintenance/postgres/archives/patch-tsearch2funcs.sql29
-rw-r--r--maintenance/postgres/archives/patch-updatelog.sql4
-rw-r--r--maintenance/postgres/compare_schemas.pl130
-rw-r--r--maintenance/postgres/mediawiki_mysql2postgres.pl8
-rw-r--r--maintenance/postgres/tables.sql45
-rw-r--r--maintenance/preprocessorFuzzTest.php4
-rw-r--r--maintenance/purgeList.php4
-rw-r--r--maintenance/purgeOldText.inc5
-rw-r--r--maintenance/purgeOldText.php3
-rw-r--r--maintenance/reassignEdits.inc.php5
-rw-r--r--maintenance/reassignEdits.php3
-rw-r--r--maintenance/rebuildImages.php3
-rw-r--r--maintenance/rebuildInterwiki.inc13
-rw-r--r--maintenance/rebuildInterwiki.php4
-rw-r--r--maintenance/rebuildall.php17
-rw-r--r--maintenance/rebuildmessages.php11
-rw-r--r--maintenance/rebuildrecentchanges.inc96
-rw-r--r--maintenance/rebuildrecentchanges.php3
-rw-r--r--maintenance/rebuildtextindex.inc5
-rw-r--r--maintenance/rebuildtextindex.php7
-rw-r--r--maintenance/refreshImageCount.php10
-rw-r--r--maintenance/refreshLinks.inc48
-rw-r--r--maintenance/refreshLinks.php26
-rw-r--r--maintenance/removeUnusedAccounts.inc6
-rw-r--r--maintenance/removeUnusedAccounts.php4
-rw-r--r--maintenance/renamewiki.php7
-rw-r--r--maintenance/renderDump.php3
-rw-r--r--maintenance/runJobs.php14
-rw-r--r--maintenance/showJobs.php4
-rw-r--r--maintenance/showStats.php2
-rw-r--r--maintenance/sql.php6
-rw-r--r--maintenance/sqlite/tables.sql340
-rw-r--r--maintenance/stats.php7
-rw-r--r--maintenance/storage/blobs.sql2
-rw-r--r--maintenance/storage/checkStorage.php10
-rw-r--r--maintenance/storage/compressOld.inc4
-rw-r--r--maintenance/storage/compressOld.php10
-rw-r--r--maintenance/storage/dumpRev.php4
-rw-r--r--maintenance/storage/moveToExternal.php8
-rw-r--r--maintenance/storage/resolveStubs.php4
-rw-r--r--maintenance/tables.sql76
-rw-r--r--maintenance/undelete.php6
-rw-r--r--maintenance/update.php5
-rw-r--r--maintenance/updateArticleCount.inc.php4
-rw-r--r--maintenance/updateArticleCount.php4
-rw-r--r--maintenance/updateRestrictions.php13
-rw-r--r--maintenance/updateSearchIndex.inc5
-rw-r--r--maintenance/updateSearchIndex.php3
-rw-r--r--maintenance/updateSpecialPages.php13
-rw-r--r--maintenance/updaters.inc175
-rw-r--r--maintenance/upgrade1_5.php25
-rw-r--r--maintenance/userDupes.inc39
-rw-r--r--maintenance/userOptions.inc9
-rw-r--r--maintenance/userOptions.php2
-rw-r--r--maintenance/waitForSlave.php13
-rw-r--r--maintenance/wikipedia-interwiki.sql64
-rw-r--r--maintenance/wiktionary-interwiki.sql27
-rw-r--r--math/README44
-rw-r--r--math/texutil.ml2
-rw-r--r--opensearch_desc.php98
-rw-r--r--profileinfo.php111
-rw-r--r--redirect.php4
-rw-r--r--serialized/.htaccess1
-rw-r--r--serialized/Makefile2
-rw-r--r--serialized/Utf8Case.ser2
-rw-r--r--skins/Chick.deps.php2
-rw-r--r--skins/Chick.php8
-rw-r--r--skins/CologneBlue.php13
-rw-r--r--skins/Modern.deps.php7
-rw-r--r--skins/Modern.php249
-rw-r--r--skins/MonoBook.deps.php2
-rw-r--r--skins/MonoBook.php241
-rw-r--r--skins/MySkin.deps.php2
-rw-r--r--skins/MySkin.php7
-rw-r--r--skins/Nostalgia.php7
-rw-r--r--skins/Simple.deps.php2
-rw-r--r--skins/Simple.php8
-rw-r--r--skins/Standard.php10
-rw-r--r--skins/chick/main.css45
-rw-r--r--skins/common/allmessages.js83
-rw-r--r--skins/common/commonPrint.css25
-rw-r--r--skins/common/common_rtl.css16
-rw-r--r--skins/common/diff.css2
-rw-r--r--skins/common/edit.js156
-rw-r--r--skins/common/history.js83
-rw-r--r--skins/common/images/ar/button_bold.pngbin0 -> 741 bytes
-rw-r--r--skins/common/images/ar/button_headline.pngbin0 -> 629 bytes
-rw-r--r--skins/common/images/ar/button_italic.pngbin0 -> 692 bytes
-rw-r--r--skins/common/images/ar/button_link.pngbin0 -> 741 bytes
-rw-r--r--skins/common/images/ar/button_nowiki.pngbin0 -> 1185 bytes
-rw-r--r--skins/common/images/be-tarask/button_bold.pngbin0 -> 575 bytes
-rw-r--r--skins/common/images/be-tarask/button_italic.pngbin0 -> 638 bytes
-rw-r--r--skins/common/images/be-tarask/button_link.pngbin0 -> 550 bytes
-rw-r--r--skins/common/images/cyrl/LICENSE17
-rw-r--r--skins/common/images/cyrl/button_bold.pngbin0 -> 275 bytes
-rw-r--r--skins/common/images/cyrl/button_italic.pngbin0 -> 461 bytes
-rw-r--r--skins/common/images/cyrl/button_link.pngbin0 -> 353 bytes
-rw-r--r--skins/common/images/spinner.gifbin2285 -> 586 bytes
-rw-r--r--skins/common/mwsuggest.js775
-rw-r--r--skins/common/oldshared.css41
-rw-r--r--skins/common/prefs.js119
-rw-r--r--skins/common/preview.js3
-rw-r--r--skins/common/rightclickedit.js48
-rw-r--r--skins/common/shared.css170
-rw-r--r--skins/common/upload.js14
-rw-r--r--skins/common/wikibits.js606
-rw-r--r--skins/common/wikistandard.css2
-rw-r--r--skins/modern/main.css75
-rw-r--r--skins/modern/rtl.css28
-rw-r--r--skins/monobook/main.css117
-rw-r--r--skins/monobook/rtl.css24
-rw-r--r--skins/simple/main.css45
-rw-r--r--skins/simple/rtl.css26
-rw-r--r--t/.htaccess1
-rw-r--r--t/README8
-rw-r--r--t/Search.inc165
-rw-r--r--t/Test.php496
-rw-r--r--t/inc/Database.t55
-rw-r--r--t/inc/Global.t154
-rw-r--r--t/inc/IP.t3
-rw-r--r--t/inc/ImageFunctions.t56
-rw-r--r--t/inc/Language.t30
-rw-r--r--t/inc/Licenses.t3
-rw-r--r--t/inc/LocalFile.t77
-rw-r--r--t/inc/Parser.t39
-rw-r--r--t/inc/Revision.t79
-rw-r--r--t/inc/Sanitizer.t3
-rw-r--r--t/inc/Search.t14
-rw-r--r--t/inc/Title.t3
-rw-r--r--t/inc/Xml.t3
-rw-r--r--thumb.php12
-rw-r--r--trackback.php17
1008 files changed, 227559 insertions, 81623 deletions
diff --git a/AdminSettings.sample b/AdminSettings.sample
index 1670cf5e..140cb0a9 100644
--- a/AdminSettings.sample
+++ b/AdminSettings.sample
@@ -7,8 +7,6 @@
* privileges to do maintenance work.
*
* Developers: Do not check AdminSettings.php into Subversion
- *
- * @package MediaWiki
*/
/*
@@ -27,5 +25,3 @@ $wgDBadminpassword = 'adminpass';
* Whether to enable the profileinfo.php script.
*/
$wgEnableProfileInfo = false;
-
-?>
diff --git a/HISTORY b/HISTORY
index e95ca184..8e89f410 100644
--- a/HISTORY
+++ b/HISTORY
@@ -1,5 +1,557 @@
Change notes from older releases. For current info see RELEASE-NOTES.
+== MediaWiki 1.12 ==
+
+This is the Winter 2007 quarterly release.
+
+MediaWiki is now using a "continuous integration" development model with
+quarterly snapshot releases. The latest development code is always kept
+"ready to run", and in fact runs our own sites on Wikipedia.
+
+Release branches will continue to receive security updates for about a year
+from first release, but nonessential bugfixes and feature developments
+will be made on the development trunk and appear in the next quarterly release.
+
+Those wishing to use the latest code instead of a branch release can obtain
+it from source control: http://www.mediawiki.org/wiki/Download_from_SVN
+
+=== Configuration changes in 1.12 ===
+* Marking edits as bot edits with Special:Contributions?bot=1 now requires the
+ markbotedit permission, rather than the rollback permission previously used.
+ This permission is assigned by default to the sysop group.
+* MediaWiki now checks if serialized files are out of date. New configuration
+ variable $wgCheckSerialized can be set to false to enable old behavior (i.e.
+ to not check and assume they are always up to date)
+* The rollback permission can now be rate-limited using the normal mechanism.
+* New configuration variable $wgExtraLanguageNames
+* Behaviour of $wgAddGroups and $wgRemoveGroups changed. New behaviour:
+* * Granting the userrights privilege allows arbitrary changing of rights.
+* * Without the userrights privilege, a user will be able to add and/or
+ remove the groups specified in $wgAddGroups and $wgRemoveGroups for
+ any groups they are in.
+* New permission userrights-interwiki for changing user rights on foreign wikis.
+* $wgImplictGroups for groups that are hidden from Special:Listusers, etc.
+* $wgAutopromote: automatically promote users who match specified criteria
+* $wgGroupsAddToSelf, $wgGroupsRemoveFromSelf: allow users to add or remove
+ themselves from specified groups via Special:Userrights.
+* When $wgUseTidy has been enabled, PHP's Tidy module is now used if it is
+ present, in preference to an external Tidy executable which may or may not
+ be present. To force use of external Tidy even when the PHP module is
+ available, set $wgTidyInternal to false.
+
+
+=== New features in 1.12 ===
+* (bug 10735) Add a warning for non-descriptive filenames at Special:Upload
+* Add {{filepath:}} parser function to get full path to an uploaded file,
+ complementing {{fullurl:}} for pages.
+* (bug 11136) If using Postgres, search path is explicitly set if wgDBmwschema
+ is not set to 'mediawiki', allowing multiple mediawiki instances per user.
+* (bug 11151) Add descriptive <title> to revision history page
+* (bug 5412) Add feed links for the site to all pages
+* (bug 11353) Add ability to retrieve raw section content via action=raw
+* (bug 6909) Show relevant deletion log lines when uploading a previously
+ deleted file
+* On SkinTemplate based skins (like MonoBook), omit confusing "edit"/"view
+ source" tab entirely if the page doesn't exist and the user isn't allowed to
+ create it
+* Clarify instructions given when an exception is thrown
+* AuthPlugin added strictUserAuth() method to allow per-user override
+ of the strict() authentication behavior.
+* (bug 7872) Deleted revisions can now be viewed as diffs showing changes
+ against the previous revision, whether currently deleted or live.
+* Added tooltips for the "Go" and "Search" buttons
+* (bug 11649) Show input form when Special:Whatlinkshere has no parameters
+* isValidEmailAddr hook added to User method of that name, to allow, e.g., re-
+ stricting e-mail addresses to a specific domain
+* Removed "Clear" link in watchlist editor tools, as people were afraid to
+ click it. Existing clear links will fall back to the raw editor, which is
+ very easy to clear your watchlist with.
+* (bug 1405) Add wgUseNPPatrol option to control patroling for new articles
+ on Special:Newpages
+* LogLine hook added to allow formatting custom entries in Special:Log.
+* Support for Iranian calendar
+* (bug 1401) Allow hiding logged-in users, bots and patrolled pages on
+ Special:Newpages
+* ChangesListInsertArticleLink hook added for adding extra article info to RC.
+* MediaWikiPerformAction hook added for diverting control after the main
+ globals have been set up but before any actions have been taken.
+* BeforeWatchlist hook added for filtering or replacing watchlist.
+* SkinTemplateTabAction hook added for altering the properties of tab links.
+* OutputPage::getRedirect public method added.
+* (bug 11848, 12506) Allow URL parameters 'section', 'editintro' and 'preload'
+ in Special:Mypage and Special:Mytalk
+* Add ot=raw to Special:Allmessages
+* Support for Hebrew calendar
+* Support for Hebrew numerals in dates and times
+* (bug 11315) Signatures can be configured in [[MediaWiki:Signature]] and
+ [[MediaWiki:Signature-anon]]
+* Signatures for anonymous users link to Special:Contributions page rather than
+ user page
+* Added --override switch for disabled pages in updateSpecialPages.php
+* Provide a unique message (ipb_blocked_as_range) if unblock of a single IP
+ fails
+ because it is part of a blocked range.
+* (bug 3973) Use a separate message for the email content when an account is
+ created by another user
+* dumpTextPass.php can spawn fetchText.php as a subprocess, which should restart
+ cleanly if database connections fail unpleasantly.
+* (bug 12028) Add Special:Listbots as shortcut for Special:Listusers/bot
+* (bug 9633) Add a predefined list of delete reasons to the deletion form
+* Show a warning message when creating/editing a user (talk) page but the user
+ does not exists
+* (bug 8396) Ignore out-of-date serialised message caches
+* (bug 12195) Undeleting pages now requires 'undelete' permission
+* (bug 11810) Localize displayed semicolons
+* (bug 11657) Support for Thai solar calendar
+* (bug 943) RSS feed for Recentchangeslinked
+* Introduced AbortMove hook
+* (bug 2919) Protection of nonexistent pages with regular protection interface.
+* Special:Upload now lists permitted/prohibited file extensions.
+* Split ambiguous filetype-badtype message into two new messages,
+ filetype-unwanted-type and filetype-banned-type.
+* Added link to the old title in Special:Movepage
+* On Special:Movepage, errors are now more noticeable.
+* It is now possible to change rights on other local wikis without the MakeSysop
+ extension
+* Add HTML ID's mw-read-only-warning and mw-anon-edit-warning to warnings when
+ editing to allow CSS styling.
+* Parser now returns list of sections
+* When a user is prohibited from creating a page, a title of "View source"
+ makes no sense, and there should be no "Return to [[Page]]" link.
+* (bug 12486) Protected titles now give a warning for privileged editors.
+* (bug 9939) Special:Search now sets focus to search input box when no existing
+ search is active
+* For Special:Userrights, use GET instead of POST to search for users.
+* Allow subpage syntax for Special:Userrights, i.e., Special:Userrights/Name.
+* When submitting changes on Special:Userrights, show the full form again, not
+ just the search box.
+* Added exception hooks
+* (bug 12574) Allow bots to specify whether an edit should be marked as a bot
+ edit, via the parameter 'bot'. (Default: '1')
+* (bug 12536) User should be able to get MediaWiki version from any page
+* (bug 12622) A JavaScript constant to declare whether api.php is available
+* Add caching to the AJAX search
+* Add APCOND_INGROUPS
+* Add DBA caching to installer
+* (bug 12585) Added a bunch of parameters to the revertpage message
+* Support redirects in image namespace
+* (bug 10049) Prefix index search and namespaces in Special:Withoutinterwiki
+* (bug 12668) Support for custom iPhone bookmark icon via $wgAppleTouchIcon
+* Add option to include templates in Special:Export.
+* (bug 12655) Added $wgUserEmailUseReplyTo config option to put sender
+ address in Reply-To instead of From for user-to-user emails.
+ This protects against SPF problems and privacy-leaking bounce messages
+ when using mailers that set the envelope sender to the From header value.
+* (bug 11897) Add alias [[Special:CreateAccount]] & [[Special:Userlogin/signup]]
+ for Special:Userlogin?type=signup
+* (bug 12214) Add a predefined list of delete reasons to the file deletion form
+* Merged backends for OpenSearch suggestions and AJAX search.
+ Both now accept namespace prefixes, handle 'Media:' and 'Special:' pages,
+ and reject interwiki prefixes. PrefixSearch class centralizes this code,
+ and the backend part can be overridden by the PrefixSearchBackend hook.
+* (bug 10365) Localization of Special:Version
+* When installing using Postgres, the Pl/Pgsql language is now checked for
+ and installed when at the superuser level.
+* The default robot policy for the entire wiki is now configurable via the
+ $wgDefaultRobotPolicy setting.
+* (bug 12239) Use different separators for autocomments
+* (bug 12857) Patrol link on new pages should clear floats
+* (bug 12968) Render redirect wikilinks in a redirect class for customization
+ via user/site CSS.
+* EditPageBeforeEditButtons hook added for altering the edit buttons below the edit box
+
+=== Bug fixes in 1.12 ===
+
+* Subpages are now indexed for searching properly when using PostgreSQL
+* (bug 3846) Suppress warnings from, e.g. open_basedir when scanning for
+ ImageMagick, diff3 et al. during installation [patch by Jan Reininghaus]
+* (bug 7027) Shift handling of deletion permissions-checking to
+ getUserPermissionsErrors.
+* Login and signup forms are now more correct for right-to-left languages.
+* (bug 5387) Block log items on RecentChanges don't make use of possible
+ translations
+* (bug 11211) Pass, as a parameter to the protectedpagetext interface
+ message, the level of protection.
+* (bug 9611) Supply the blocker and reason for the cantcreateaccounttext
+ message.
+* (bug 8759) Fixed bug where rollback was allowed on protected pages for wikis
+ where rollback is given to non-sysops.
+* (bug 8834) Split off permission for editing user JavaScript and CSS from
+ editinterface to a new permission key editusercssjs.
+* (bug 11266) Set fallback language for Fulfulde (ff) to French
+* (bug 11179) Include image version deletion comment in public log
+* Fixed notice when accessing special page without read permission and whitelist
+ is not defined
+* (bug 9252) Fix for tidy funkiness when using editintro mode
+* (bug 4021) Fix for MySQL wildcard search
+* (bug 10699) Fix for MySQL phrase search
+* (bug 11321) Fix width of gallerybox when option "width=xxx" is used
+* (bug 7890) Special:BrokenRedirects links deleted redirects to a non-existent
+ page
+* Fix initial statistics when installing: add correct values
+* (bug 11342) Fix several 'returnto' links in permissions/error pages which
+ linked to the main page instead of targetted page
+* Strike the link to the redirect rather than using an asterisk in
+ Special:Listredirects
+* (bug 11355) Fix false positives in Safe Mode and other config detection
+ when boolean settings are disabled with 'Off' via php_admin_value/php_value
+* (bug 11292) Fixed unserialize errors with Postgres by creating special Blob
+ object.
+* (bug 11363) Make all metadata fields bytea when using Postgres.
+* (bug 11331) Add buildConcat() and use CASE not IF for DB compatibility. Make
+ oldimage cascade delete via image table for Postgres, change fa_storage_key
+ TEXT.
+* (bug 11438) Live Preview chops returned text
+* Show the right message on account creation when the user is blocked
+* (bug 11450) Fix creation of objectcache table on upgrade
+* Fix namespace selection after submit of Special:Newpages
+* Make input form of Special:Newpages nicer for RTL wikis
+* (bug 11462) Fix typo in LanguageGetSpecialPageAliases hook name
+* (bug 11474) Fix unintentional fall-through in math error handling
+* (bug 11478) Fix undefined method call in file deletion interface
+* (bug 278) Search results no longer highlight incorrect partial word matches
+* Compatibility with incorrectly detected old-style DJVU mime types
+* (bug 11560) Fix broken HTML output from weird link nesting in edit comments.
+ Nested links (as in image caption text) still don't work _right_ but they're
+ less wrong
+* (bug 9718) Remove unnecessary css from main.css causing spacing issues on
+ some browsers.
+* (bug 11574) Add an interface message loginstart, which, similarly to loginend,
+ appears just before the login form. Patch by MinuteElectron.
+* Do not cache category pages if using 'from' or 'until'
+* Created new hook getUserPermissionsErrors, to go with userCan changes.
+* Diff pages did not properly display css/js pages.
+* (bug 11620) Add call to User::isValidEmailAddr during accout creation.
+* (bug 11629) If $wgEmailConfirmToEdit is true, require people to supply an
+ email address when registering.
+* (bug 11612) Days to show in recent changes cannot be larger than 7
+* (bug 11131) Change filearchive width/height columns to int for Postgres
+* Support plural in undeleted{revisions,revisions-files,files}
+* (bug 11343) If the database is read-only, ensure that undelete fails.
+* (bug 11690) Show revert link for page moves in Special:Log to allowed users
+ only
+* Initial-lowercase prefix checks in namespaceDupes.php now actually work.
+* Fix regression in LinkBatch.php breaking PHP 5.0
+* (bug 11452) wfMsgExt uses sometimes wrong language object for parsing magic
+ words when called with options ''parsemag'' or ''content''.
+* (bug 11727) Support plural in 'historysize' message
+* (bug 11744) Incorrect return value from Title::getParentCategories()
+* (bug 11762) Fix native language name of Akan (ak)
+* (bug 11722) Fix inconsistent case in unprotect tabs
+* (bug 11795) Be more paranoid about confirming accept-encoding header is
+ present
+* (bug 11809) Use formatNum() for more numbers
+* (bug 11818) Fix native language name of Inuktitut (iu)
+* Remove all commas when parsing float numbers in sorted tables
+* Limit text field of deletion, protection and user rights changes reasons to
+ 255 characters (already restricted in the database)
+* In the deletion default reasons, calculate how much text to get from the
+ article text, rather than getting 150 characters (which may be too much)
+* Add two messages for Special:Blockme which were used but undefined
+* (bug 11921) Support plural in message number_of_watching_users_pageview
+* If an IP address is blocked as part of a rangeblock, attempting to unblock
+ the single IP should not unblock the entire range.
+* (bug 6695) Fix native language name of Southern Sotho (Sesotho) (st)
+* Make action=render follow redirects by default
+* If restricted read access was enabled, whitelist didn't work with special
+ pages which had spaces in theirs names
+* If restricted read access was enabled, requests for non-existing special pages
+ threw an exception
+* Feeds for recent changes now provide correct URLs for the change, not just
+ the page
+* Check for if IP is blocked as part of a range when unblocking (see above bug-
+ fix) was faulty. Now fixed.
+* Fixed wpReason URL parameter to action=delete.
+* Do not force a password for account creation by email
+* Ensure that rate-limiting is applied to rollbacks.
+* Make a better rate-limiting error message (i.e. a normal MW error,
+ rather than an "Internal Server Error").
+* Do not present an image bigger than the source when 'frameless' option is used
+ (to be consistent with the 'thumb' option now)
+* Support {{PLURAL}} for import log
+* Make sure that the correct log entries are shown on Special:Userrights even
+ for users with special characters in their names
+* The number of watching users in watchlists was always reported as 1
+* namespaceDupes.php no longer dies when coming across an illegal title
+* (bug 12143) Do not show a link to patrol new pages for non existent pages
+* (bug 12166) Fix XHTML validity for Special:Emailuser
+* (bug 11346) Users who cannot edit a page can now no longer unprotect it.
+* (bug 451) Add a generic Traditional / Simplified Chinese conversion table,
+ instead of a Traditional conversion with Taiwan variant, and a Simplified
+ conversion with China variant.
+* (bug 12178) Fix wpReason parameter to action=delete, again.
+* Graceful behavior for updateRestrictions.php if a page already has records
+ in the page_restrictions matching its old page_restrictions field.
+ May help with odd upgrade issues or race condition.
+* (bug 11993) Remove contentsub "revision history"
+* (bug 11952) Ensure we quote_ident() all schema names as needed
+ inside of the DatabasePostgres.php file.
+* (bug 12184) Exceptions now sent to stderr instead of stdout for command-line
+ scripts, making for cleaner reporting during batch jobs. PHP errors will also
+ be redirected in most cases on PHP 5.2.4 and later, switching 'display_errors'
+ to 'stderr' at runtime.
+* (bug 12148) Text highlight wasn't applied to cleanly deleted and added
+ lines in diff output
+* (bug 10166) Fix a PHP warning in Language::getMagic
+* Only mark rollback edits as minor if the user can normally mark edits minor
+* Escape page names in the move successful page (e.g. for pages with two
+ apostrophes).
+* (bug 12145) Add localized names of kk-variants
+* (bug 12259) Localize the numbers in deleted pages on the sysop view
+* Set proper page title for successful file deletion
+* (bug 11221) Do not show 'Compare selected versions' button for a history page
+ with one revision only
+* (bug 12267) Set the default date format to Thai solar calender for the Thai
+ language
+* (bug 10184) Extensions' stylesheets and scripts should be loaded before
+ user-customized ones (like Common.css, Common.js)
+* (bug 12283) Special:Newpages forgets parameters
+* (bug 12031) All namespaces doesn't work in Special:Newpages
+* (bug 585) Only create searchindex replica table for parser tests if db is
+ MySQL
+* Allow --record option if parserTests.php to work when using Postgres
+* (bug 12296) Simplify cache epoch in default LocalSettings.php
+* (bug 12346) XML fix when body double-click and click handlers are present
+* Fix regression -- missing feed links in sidebar on Special:Recentchanges
+* (bug 12371) Handle more namespace case variants in namespaceDupes.php
+* (bug 12380) Bot-friendly EditPage::spamPage
+* (bug 8066) Spaces can't be entered in special page aliases
+* Hide undo link if user can't edit article
+* (bug 12416) Fix password setting for createAndPromote.php
+* (bug 3097) Inconsistently usable titles containing HTML character entities
+ are now forbidden. A run of cleanupTitles.php will fix up existing pages.
+* (bug 12446) Permissions check fix for undelete link
+* (bug 12451) AJAX title normalization tweaks
+* When a user creating a page is not allowed to either create the page nor edit
+ it, all applicable reasons are now shown.
+* (bug 11428) Allow $wgScript inside $wgArticlePath when emulating PATH_INFO
+ Fixes 'root'-style rewrite configurations
+* (bug 12493) Removed hardcoded MAX_FILE_SIZE from Special:Import upload form
+* (bug 12489) Special:Userrights listed in restricted section again
+* (bug 12553) Fixed invalid XHTML in edit conflict screen
+* (bug 12505) Fixed section=0 with action=raw
+* (bug 12614) Do not log user rights change that didn't change anything
+* (bug 12584) Don't reset cl_timestamp when auto-updating sort key on move
+* (bug 12588) Fix selection in namespace selector on Special:Newpages
+* Use only default options when generating RSS and Atom syndication links.
+ This should help prevent infinite link loops that some software may follow,
+ and will generally keep feed behavior cleaner.
+* (bug 12608) Unifying the spelling of getDBkey() in the code.
+* (bug 12611) Bot flag ignored in recent changes
+* (bug 12617) Decimal and thousands separators for Romanian
+* (bug 12567) Fix for misformatted read-only messages on edit, protect.
+ Also added proper read-only checks to several special pages.
+ Have removed read-only checks from the general user permission framework.
+* Creating a site with a name containing '#' is no longer permitted, since the
+ name will not work (but $wgSiteName is not checked if manually set).
+* (bug 12695) Suppress dvips verbiage from web server error log
+* (bug 12716) Unprotecting a non-protected page leaves a log entry
+* Log username blocks with canonical form of name instead of input form
+* (bug 11593, 12719) Fixes for overzealous invocation of thumb.php.
+ Non-image handlers and full-size images may now decline it, fixing
+ mystery failures when using $wgThumbnailScriptPath.
+* (bug 12327) Comma in username no longer disrupts mail headers
+* (bug 6436) Localization of Special:Import XML parser Error message(s).
+* Security fix for API on MSIE
+* (bug 12768) Database query syntax error in maintenance/storage/compressOld.inc
+* (bug 12753) Empty captions in MediaWiki:Sidebar result in PHP errors
+* (bug 12790) Page protection is not logged when edit-protection is used
+ and move-protection is not
+* (bug 12793) Fix for restricted namespaces/pages in Special:Export
+* Fix for Special:Export so it doesn't ignore the page named '0'
+* Don't display rollback link if the user doesn't have all required permissions
+* The comment of a time-limited protection now contains the date in the default
+ format
+* (bug 12880) wfLoadExtensionMessages does not use $fallback from MessagesXx.php
+* (bug 12885) Correction for Russian convertPlural function
+* (bug 12768) Make DatabasePostgres->hasContraint() schema aware.
+* (bug 12735) Truncate usernames in comments using mb_ functions.
+* (bug 12892) Poor tab indexing on "delete file" form
+* (bug 12660) When creating an account by e-mail, do not send the creator's IP
+ address
+* (bug 12931) Fix wrong global variable in SpecialVersion
+* (bug 12919) Use 'deletedrevision' message as content when deleting an old file
+ version
+* (bug 12952) Using Nosuchusershort instead of Nosuchuser when account creation
+ is disabled
+* (bug 12869) Magnify icon alignment should be adjusted using linked CSS
+* Fixing message cache updates for MediaWiki messages moves
+* (bug 12815) Signature timestamps were always in UTC, even if the timezone code
+ in parentheses after them claimed otherwise
+* (bug 12732) Fix installer and searching to handle built-in tsearch2 for Postgres.
+* (bug 12784) Change "bool" types to smallint to handle Postgres 8.3 strictness.
+* (bug 12301) Allow maintenance/findhooks.php to search hooks in multiple directories.
+* (bug 7681, 11559) Cookie values no longer override GET and POST variables.
+* (bug 5262) Fully-qualified $wgStylePath no longer corrupted on XML feeds
+* (bug 3269) Inaccessible titles ending in '/.' or '/..' now forbidden.
+* (bug 12935, 12981) Fully-qualify archive URLs in delete, revert messages
+* (bug 12938) Fix template expansion and 404 returns for action=raw with section
+* (bug 11567) Fix error checking for PEAR::Mail. UserMailer::send() now returns
+ true-or-WikiError, which seems to be the calling convention expected by half
+ its callers already
+* (bug 12846) IE rtl.css issue in RTL wikis special:Preferences when selecting an
+ LTR user language
+* (bug 13005) DISPLAYTITLE does not work on preview
+* (bug 13004) Fix error on Postgres searches that return too many results.
+
+== Parser changes in 1.12 ==
+
+For help with migration to the MediaWiki 1.12 parser, please visit:
+
+http://meta.wikimedia.org/wiki/Migration_to_the_new_preprocessor
+
+The parser pass order has changed from
+
+ * Extension tag strip and render
+ * HTML normalisation and security
+ * Template expansion
+ * Main section...
+
+to
+
+ * Template and extension tag parse to intermediate representation
+ * Template expansion and extension rendering
+ * HTML normalisation and security
+ * Main section...
+
+The main effect of this for the user is that the rules for uncovered syntax
+have changed.
+
+Uncovered main-pass syntax, such as HTML tags, are now generally valid, whereas
+previously in some cases they were escaped. For example, you could have "<ta" in
+one template, and "ble>" in another template, and put them together to make a
+valid <table> tag. Previously the result would have been "&lt;table&gt;".
+
+Uncovered preprocessor syntax is generally not recognised. For example, if you
+have "{{a" in Template:A and "b}}" in Template:B, then "{{a}}{{b}}" will be
+converted to a literal "{{ab}}" rather than the contents of Template:Ab. This
+was the case previously in HTML output mode, and is now uniformly the case in
+the other modes as well. HTML-style comments uncovered by template expansion
+will not be recognised by the preprocessor and hence will not prevent template
+expansion within them, but they will be stripped by the following HTML security
+pass.
+
+Bug 5678 has been fixed. This has a number of user-visible effects related to
+the removal of this double-parse. Please see the wiki page for examples.
+
+Message transformation mode has been removed, and replaced with "preprocess"
+mode. This means that some MediaWiki namespace messages may need to be updated,
+especially ones which took advantage of the terribly counterintuitive behaviour
+of the former message mode.
+
+The header identification routines for section edit and for numbering section
+edit links have been merged. This removes a significant failure mode and fixes a
+whole category of bugs (tracked by bug #4899). Wikitext headings uncovered by
+template expansion will still be rendered into a heading tag, and will get an
+entry in the TOC, but will not have a section edit link. HTML-style headings
+will also not have a section edit link. Valid wikitext headings present in the
+template source text will get a template section edit link. This is a major
+break from previous behaviour, but I believe the effects are almost entirely
+beneficial.
+
+The main motivation for making these changes was performance. The new two-pass
+preprocessor can skip "dead branches" in template expansion, such as unfollowed
+#switch cases and unused defaults for template arguments. This provides a
+significant performance improvement in template-heavy test cases taken from
+Wikipedia. Parser function hooks can participate in this performance improvement
+by using the new SFH_OBJECT_ARGS flag during registration.
+
+The pre-expand include size limit has been removed, since there's no efficient
+way to calculate such a figure, and it would now be meaningless for performance
+anyway. The "preprocessor node count" takes its place, with a generous default
+limit.
+
+The context in which XML-style extension tags are called has changed, so
+extensions which make use of the parser state may need compatibility changes.
+
+The new preprocessor syntax has been documented in Backus-Naur Form at:
+
+http://www.mediawiki.org/wiki/Preprocessor_ABNF
+
+The ExpandTemplates extension now has the ability to generate an XML parse
+tree from wikitext source. This parse tree corresponds closely to the grammar
+documented on that page.
+
+=== API changes in 1.12 ===
+
+Full API documentation is available at http://www.mediawiki.org/wiki/API
+
+* (bug 11275) Enable descending sort in categorymembers
+* (bug 11308) Allow the API to output the image metadata
+* (bug 11296) Temporary fix for escaping of ampersands inside links in
+ pretty-printed
+ help document.
+* (bug 11405) Expand templates implementation in the API
+* (bug 11218) Add option to feedwatchlist to display multiple revisions for each
+ page.
+* (bug 11404) Provide name of exception caught in error code field of internal
+ api error messages.
+* (bug 11534) rvendid doesn't work
+* Fixed rvlimit of the revisions query to only enforce the lower query limit if
+ revision content is requested.
+* Include svn revision number (if install is checked-out from svn) in siteinfo
+ query.
+* (bug 11173) Allow limited wikicode rendering via api.php
+* (bug 11572) API should provide interface for expanding templates
+* (bug 11569) Login should return the cookie prefix
+* (bug 11632) Breaking change: Specify the type of a change in the recentchanges
+ list as 'edit', 'new', 'log' instead of 0, 1, 2, respectively.
+* Compatibility fix for PHP 5.0.x.
+* Add rctype parameter to list=recentchanges that filters by type
+* Add apprtype and apprlevel parameters to filter list=allpages by protection
+ types and levels
+* Add apdir parameter to enable listing all pages from Z to A
+* (bug 11721) Use a different title for results than for the help page.
+* (bug 11562) Added a user_registration parameter/field to the list=allusers
+ query.
+* (bug 11588) Preserve document structure for empty dataset in backlinks query.
+* Outputting list of all user preferences rather than having to request them by
+ name
+* (bug 11206) api.php should honor maxlag
+* Make prop=info check for restrictions in the old format too.
+* Add apihighlimits permission, default for sysops and bots
+* Add limit=max to use maximal limit
+* Add action=parse to render parser output. Use it instead of action=render
+ which has been removed
+* Add rvtoken=rollback to prop=revisions
+* Add meta=allmessages to get messages from site's messages cache.
+* Use bold and italics highlighting only in API help
+* Added action={block,delete,move,protect,rollback,unblock,undelete} and
+ list={blocks,deletedrevs}
+* Fixed sessionid attribute in action=login
+* Standardized limits. Revisions and Deletedrevisions formerly using
+ 200 / 10000, now 500 / 5000, in line with other modules.
+* Added list=allcategories module
+* (bug 12321) API list=blocks reveals private data
+* Fix output of wfSajaxSearch
+* (bug 12413) meta=userinfo missing <query> tag
+* Add list of sections to action=parse output
+* Added action=logout
+* Added cascade flag to prop=info&inprop=protections
+* Added wlshow parameter to list=watchlist, similar to rcshow
+ (list=recentchanges)
+* Added support for image thumbnailing to prop=imageinfo
+* action={login,block,delete,move,protect,rollback,unblock,undelete} now must be
+ POSTed
+* prop=imageinfo interface changed: iihistory replaced by iilimit, iistart and
+ iiend parameters
+* Added amlang parameter to meta=allmessages
+* Added apfilterlanglinks parameter to list=allpages, replacing
+ query.php?what=nolanglinks
+* (bug 12718) Added action=paraminfo module that provides information about API
+ modules and their parameters
+* Added iiurlwidth and iiurlheight parameters to prop=imageinfo
+* Added format=txt and format=dbg, imported from query.php
+* Added uiprop=editcount to meta=userinfo
+* Added list=users which fetches user information
+* Added list=random which fetches a list of random pages
+* Added page parameter to action=parse to facilitate parsing of existing pages
+* Added uiprop=ratelimits to meta=userinfo
+* Added siprop=namespacealiases to meta=siteinfo
+* Made multiple values for ucuser possible in list=usercontribs
+* (bug 12944) Added cmstart and cmend parameters to list=categorymembers
+* Allow queries to have a where range that does not match the range field
+
== MediaWiki 1.11 ==
This is the Summer 2007 branch release of MediaWiki.
diff --git a/INSTALL b/INSTALL
index 1bbdc201..e5bf0c11 100644
--- a/INSTALL
+++ b/INSTALL
@@ -2,101 +2,94 @@
Installing MediaWiki
---
-Starting with MediaWiki 1.2.0, it's possible to install
-and configure the wiki "in-place", as long as you have
-the necessary prerequisites available.
+Starting with MediaWiki 1.2.0, it's possible to install and configure the wiki
+"in-place", as long as you have the necessary prerequisites available.
Required software:
* Web server with PHP 5.x or higher.
* A MySQL server, 4.0.14 or higher OR a Postgres server, 8.1 or higher
-MediaWiki is developed and tested mainly on Unix/Linux
-platforms, but should work on Windows as well.
+MediaWiki is developed and tested mainly on Unix/Linux platforms, but should
+work on Windows as well.
-If your PHP is configured as a CGI plug-in rather than
-an Apache module you may experience problems, as this
-configuration is not well tested. safe_mode is also not
-tested and unlikely to work.
+If your PHP is configured as a CGI plug-in rather than an Apache module you may
+experience problems, as this configuration is not well tested. safe_mode is also
+not tested and unlikely to work.
If you want math support see the instructions in math/README
Don't forget to check the RELEASE-NOTES file...
-Additional documentation is available online, which may include more
-detailed notes on particular operating systems and workarounds for
-difficult hosting environments:
+Additional documentation is available online, which may include more detailed
+notes on particular operating systems and workarounds for difficult hosting
+environments:
-http://www.mediawiki.org/wiki/Manual:Installation
+http://www.mediawiki.org/wiki/Manual:Installation_guide
-********************** WARNING **************************
+******************* WARNING *******************
-REMEMBER: ALWAYS BACK UP YOUR DATABASE BEFORE ATTEMPTING
-TO INSTALL OR UPGRADE!!!
+REMEMBER: ALWAYS BACK UP YOUR DATABASE BEFORE
+ATTEMPTING TO INSTALL OR UPGRADE!!!
-********************** WARNING **************************
+******************* WARNING *******************
----
In-place web install
----
-Decompress the MediaWiki installation archive either on
-your server, or on your local machine and upload the
-directory tree. Rename it from "mediawiki-1.x.x" to
+Decompress the MediaWiki installation archive either on your server, or on your
+local machine and upload the directory tree. Rename it from "mediawiki-1.x.x" to
something nice, like "wiki", since it'll be in your URL.
- +-----------------------------------------------------------+
- | Hint: If you plan to use a fancy URL-rewriting scheme |
- | to prettify your URLs, you should put the files in a |
- | *different* directory from the virtual path where page |
- | names will appear. |
- | |
- | See: http://www.mediawiki.org/wiki/Manual:Short_URL |
- +-----------------------------------------------------------+
+ +--------------------------------------------------------------------------+
+ | Hint: If you plan to use a fancy URL-rewriting scheme to prettify your |
+ | URLs, you should put the files in a *different* directory from the |
+ | virtual path where page names will appear. |
+ | |
+ | See: http://www.mediawiki.org/wiki/Manual:Short_URL |
+ +--------------------------------------------------------------------------+
-To run the install script, you'll need to temporarily make
-the 'config' subdirectory writable by the web server. The
-simplest way to do this on a Unix/Linux system is to make
-it world-writable:
+To run the install script, you'll need to temporarily make the 'config'
+subdirectory writable by the web server. The simplest way to do this on a
+Unix/Linux system is to make it world-writable:
chmod a+w config
-Hop into your browser and surf into the wiki directory.
-It'll direct you into the config script. Fill out the form...
-remember you're probably not on an encrypted connection.
+Hop into your browser and surf into the wiki directory. It'll direct you into
+the config script. Fill out the form... remember you're probably not on an
+encrypted connection.
Gaaah! :)
-If all goes well, you should soon be told that it's set up
-your wiki database and written a configuration file. There
-should now be a 'LocalSettings.php' in the config directory;
-move it back up to the main wiki directory, and the wiki
+If all goes well, you should soon be told that it's set up your wiki database
+and written a configuration file. There should now be a 'LocalSettings.php' in
+the config directory; move it back up to the main wiki directory, and the wiki
should now be working.
- +------------------------------------------------------------+
- | Security hint: if you have limited access on your server |
- | and cannot change ownership of files, you might want to |
- | *copy* instead of *move* LocalSettings.php. |
- | |
- | This will make the file owned by your user account |
- | instead of by the web server, which is safer in case |
- | another user's account is compromised. |
- +------------------------------------------------------------+
+ +-------------------------------------------------------------------------+
+ | Security hint: if you have limited access on your server and cannot |
+ | change ownership of files, you might want to *copy* instead of *move* |
+ | LocalSettings.php. |
+ | |
+ | This will make the file owned by your user account instead of by |
+ | the web server, which is safer in case another user's account is |
+ | compromised. |
+ +-------------------------------------------------------------------------+
-Once the wiki is set up, you should remove the config
-directory, or at least make it not world-writable (though
-it will refuse to config again if the wiki is set up).
+Once the wiki is set up, you should remove the config directory, or at least
+make it not world-writable (though it will refuse to config again if the wiki
+is set up).
----
-Don't forget that this is free software under development!
-Chances are good there's a crucial step that hasn't made it
-into the documentation. You should probably sign up for the
-MediaWiki developers' mailing list; you can ask for help (please
-provide enough information to work with, and preferably be aware
-of what you're doing!) and keep track of major changes to the
-software, including performance improvements and security patches.
+Don't forget that this is free software under development! Chances are good
+there's a crucial step that hasn't made it into the documentation. You should
+probably sign up for the MediaWiki developers' mailing list; you can ask for
+help (please provide enough information to work with, and preferably be aware of
+what you're doing!) and keep track of major changes to the software, including
+performance improvements and security patches.
http://lists.wikimedia.org/mailman/listinfo/mediawiki-announce (low traffic)
diff --git a/Makefile b/Makefile
index b9d5b1cf..b414ffa3 100644
--- a/Makefile
+++ b/Makefile
@@ -15,11 +15,14 @@ MAINTENANCE_TESTS=$(wildcard t/maint/*t)
FAST_TESTS=$(BASE_TEST) $(INCLUDES_TESTS)
ALL_TESTS=$(BASE_TEST) $(INCLUDES_TESTS) $(MAINTENANCE_TESTS)
-test: Test.php
+test: t/Test.php
$(PROVE_BIN) $(ALL_TESTS)
-fast: Test.php
+fast: t/Test.php
$(PROVE_BIN) $(FAST_TESTS)
-verbose: Test.php
+maint:
+ $(PROVE_BIN) $(MAINTENANCE_TESTS)
+
+verbose: t/Test.php
$(PROVE_BIN) -v $(ALL_TESTS) | egrep -v '^ok'
diff --git a/RELEASE-NOTES b/RELEASE-NOTES
index f38b41a5..2d1dbb4f 100644
--- a/RELEASE-NOTES
+++ b/RELEASE-NOTES
@@ -3,35 +3,11 @@
Security reminder: MediaWiki does not require PHP's register_globals
setting since version 1.2.0. If you have it on, turn it *off* if you can.
-== MediaWiki 1.12.0 ==
+== MediaWiki 1.13.0 ==
-This is the quarterly branch release of MediaWiki for Winter 2008.
-
-
-MediaWiki is now using a "continuous integration" development model with
-quarterly snapshot releases. The latest development code is always kept
-"ready to run", and in fact runs our own sites on Wikipedia.
-
-Release branches will continue to receive security updates for about a year
-from first release, but nonessential bugfixes and feature developments
-will be made on the development trunk and appear in the next quarterly release.
-
-Those wishing to use the latest code instead of a branch release can obtain
-it from source control: http://www.mediawiki.org/wiki/Download_from_SVN
-
-
-Changes since 1.12.0rc1:
-
-* (bug 13359) Double-escaping in Special:Allpages
-* Localization updates.
-
-
-== MediaWiki 1.12.0rc1 ==
-
-This is a release candidate of the Winter 2008 quarterly snapshot release
+This is the first stable release of the Summer 2008 quarterly snapshot release
of MediaWiki.
-
MediaWiki is now using a "continuous integration" development model with
quarterly snapshot releases. The latest development code is always kept
"ready to run", and in fact runs our own sites on Wikipedia.
@@ -43,774 +19,589 @@ will be made on the development trunk and appear in the next quarterly release.
Those wishing to use the latest code instead of a branch release can obtain
it from source control: http://www.mediawiki.org/wiki/Download_from_SVN
-=== Configuration changes in 1.12 ===
-* Marking edits as bot edits with Special:Contributions?bot=1 now requires the
- markbotedit permission, rather than the rollback permission previously used.
- This permission is assigned by default to the sysop group.
-* MediaWiki now checks if serialized files are out of date. New configuration
- variable $wgCheckSerialized can be set to false to enable old behavior (i.e.
- to not check and assume they are always up to date)
-* The rollback permission can now be rate-limited using the normal mechanism.
-* New configuration variable $wgExtraLanguageNames
-* Behaviour of $wgAddGroups and $wgRemoveGroups changed. New behaviour:
-* * Granting the userrights privilege allows arbitrary changing of rights.
-* * Without the userrights privilege, a user will be able to add and/or
- remove the groups specified in $wgAddGroups and $wgRemoveGroups for
- any groups they are in.
-* New permission userrights-interwiki for changing user rights on foreign wikis.
-* $wgImplictGroups for groups that are hidden from Special:Listusers, etc.
-* $wgAutopromote: automatically promote users who match specified criteria
-* $wgGroupsAddToSelf, $wgGroupsRemoveFromSelf: allow users to add or remove
- themselves from specified groups via Special:Userrights.
-* When $wgUseTidy has been enabled, PHP's Tidy module is now used if it is
- present, in preference to an external Tidy executable which may or may not
- be present. To force use of external Tidy even when the PHP module is
- available, set $wgTidyInternal to false.
-
-
-=== New features in 1.12 ===
-* (bug 10735) Add a warning for non-descriptive filenames at Special:Upload
-* Add {{filepath:}} parser function to get full path to an uploaded file,
- complementing {{fullurl:}} for pages.
-* (bug 11136) If using Postgres, search path is explicitly set if wgDBmwschema
- is not set to 'mediawiki', allowing multiple mediawiki instances per user.
-* (bug 11151) Add descriptive <title> to revision history page
-* (bug 5412) Add feed links for the site to all pages
-* (bug 11353) Add ability to retrieve raw section content via action=raw
-* (bug 6909) Show relevant deletion log lines when uploading a previously
- deleted file
-* On SkinTemplate based skins (like MonoBook), omit confusing "edit"/"view
- source" tab entirely if the page doesn't exist and the user isn't allowed to
- create it
-* Clarify instructions given when an exception is thrown
-* AuthPlugin added strictUserAuth() method to allow per-user override
- of the strict() authentication behavior.
-* (bug 7872) Deleted revisions can now be viewed as diffs showing changes
- against the previous revision, whether currently deleted or live.
-* Added tooltips for the "Go" and "Search" buttons
-* (bug 11649) Show input form when Special:Whatlinkshere has no parameters
-* isValidEmailAddr hook added to User method of that name, to allow, e.g., re-
- stricting e-mail addresses to a specific domain
-* Removed "Clear" link in watchlist editor tools, as people were afraid to
- click it. Existing clear links will fall back to the raw editor, which is
- very easy to clear your watchlist with.
-* (bug 1405) Add wgUseNPPatrol option to control patroling for new articles
- on Special:Newpages
-* LogLine hook added to allow formatting custom entries in Special:Log.
-* Support for Iranian calendar
-* (bug 1401) Allow hiding logged-in users, bots and patrolled pages on
- Special:Newpages
-* ChangesListInsertArticleLink hook added for adding extra article info to RC.
-* MediaWikiPerformAction hook added for diverting control after the main
- globals have been set up but before any actions have been taken.
-* BeforeWatchlist hook added for filtering or replacing watchlist.
-* SkinTemplateTabAction hook added for altering the properties of tab links.
-* OutputPage::getRedirect public method added.
-* (bug 11848, 12506) Allow URL parameters 'section', 'editintro' and 'preload'
- in Special:Mypage and Special:Mytalk
-* Add ot=raw to Special:Allmessages
-* Support for Hebrew calendar
-* Support for Hebrew numerals in dates and times
-* (bug 11315) Signatures can be configured in [[MediaWiki:Signature]] and
- [[MediaWiki:Signature-anon]]
-* Signatures for anonymous users link to Special:Contributions page rather than
- user page
-* Added --override switch for disabled pages in updateSpecialPages.php
-* Provide a unique message (ipb_blocked_as_range) if unblock of a single IP
- fails
- because it is part of a blocked range.
-* (bug 3973) Use a separate message for the email content when an account is
- created by another user
-* dumpTextPass.php can spawn fetchText.php as a subprocess, which should restart
- cleanly if database connections fail unpleasantly.
-* (bug 12028) Add Special:Listbots as shortcut for Special:Listusers/bot
-* (bug 9633) Add a predefined list of delete reasons to the deletion form
-* Show a warning message when creating/editing a user (talk) page but the user
- does not exists
-* (bug 8396) Ignore out-of-date serialised message caches
-* (bug 12195) Undeleting pages now requires 'undelete' permission
-* (bug 11810) Localize displayed semicolons
-* (bug 11657) Support for Thai solar calendar
-* (bug 943) RSS feed for Recentchangeslinked
-* Introduced AbortMove hook
-* (bug 2919) Protection of nonexistent pages with regular protection interface.
-* Special:Upload now lists permitted/prohibited file extensions.
-* Split ambiguous filetype-badtype message into two new messages,
- filetype-unwanted-type and filetype-banned-type.
-* Added link to the old title in Special:Movepage
-* On Special:Movepage, errors are now more noticeable.
-* It is now possible to change rights on other local wikis without the MakeSysop
- extension
-* Add HTML ID's mw-read-only-warning and mw-anon-edit-warning to warnings when
- editing to allow CSS styling.
-* Parser now returns list of sections
-* When a user is prohibited from creating a page, a title of "View source"
- makes no sense, and there should be no "Return to [[Page]]" link.
-* (bug 12486) Protected titles now give a warning for privileged editors.
-* (bug 9939) Special:Search now sets focus to search input box when no existing
- search is active
-* For Special:Userrights, use GET instead of POST to search for users.
-* Allow subpage syntax for Special:Userrights, i.e., Special:Userrights/Name.
-* When submitting changes on Special:Userrights, show the full form again, not
- just the search box.
-* Added exception hooks
-* (bug 12574) Allow bots to specify whether an edit should be marked as a bot
- edit, via the parameter 'bot'. (Default: '1')
-* (bug 12536) User should be able to get MediaWiki version from any page
-* (bug 12622) A JavaScript constant to declare whether api.php is available
-* Add caching to the AJAX search
-* Add APCOND_INGROUPS
-* Add DBA caching to installer
-* (bug 18585) Added a bunch of parameters to the revertpage message
-* Support redirects in image namespace
-* (bug 10049) Prefix index search and namespaces in Special:Withoutinterwiki
-* (bug 12668) Support for custom iPhone bookmark icon via $wgAppleTouchIcon
-* Add option to include templates in Special:Export.
-* (bug 12655) Added $wgUserEmailUseReplyTo config option to put sender
- address in Reply-To instead of From for user-to-user emails.
- This protects against SPF problems and privacy-leaking bounce messages
- when using mailers that set the envelope sender to the From header value.
-* (bug 11897) Add alias [[Special:CreateAccount]] & [[Special:Userlogin/signup]]
- for Special:Userlogin?type=signup
-* (bug 12214) Add a predefined list of delete reasons to the file deletion form
-* Merged backends for OpenSearch suggestions and AJAX search.
- Both now accept namespace prefixes, handle 'Media:' and 'Special:' pages,
- and reject interwiki prefixes. PrefixSearch class centralizes this code,
- and the backend part can be overridden by the PrefixSearchBackend hook.
-* (bug 10365) Localization of Special:Version
-* When installing using Postgres, the Pl/Pgsql language is now checked for
- and installed when at the superuser level.
-* The default robot policy for the entire wiki is now configurable via the
- $wgDefaultRobotPolicy setting.
-* (bug 12239) Use different separators for autocomments
-* (bug 12857) Patrol link on new pages should clear floats
-* (bug 12968) Render redirect wikilinks in a redirect class for customization
- via user/site CSS.
-* EditPageBeforeEditButtons hook added for altering the edit buttons below the edit box
-
-=== Bug fixes in 1.12 ===
-
-* Subpages are now indexed for searching properly when using PostgreSQL
-* (bug 3846) Suppress warnings from, e.g. open_basedir when scanning for
- ImageMagick, diff3 et al. during installation [patch by Jan Reininghaus]
-* (bug 7027) Shift handling of deletion permissions-checking to
- getUserPermissionsErrors.
-* Login and signup forms are now more correct for right-to-left languages.
-* (bug 5387) Block log items on RecentChanges don't make use of possible
- translations
-* (bug 11211) Pass, as a parameter to the protectedpagetext interface
- message, the level of protection.
-* (bug 9611) Supply the blocker and reason for the cantcreateaccounttext
- message.
-* (bug 8759) Fixed bug where rollback was allowed on protected pages for wikis
- where rollback is given to non-sysops.
-* (bug 8834) Split off permission for editing user JavaScript and CSS from
- editinterface to a new permission key editusercssjs.
-* (bug 11266) Set fallback language for Fulfulde (ff) to French
-* (bug 11179) Include image version deletion comment in public log
-* Fixed notice when accessing special page without read permission and whitelist
- is not defined
-* (bug 9252) Fix for tidy funkiness when using editintro mode
-* (bug 4021) Fix for MySQL wildcard search
-* (bug 10699) Fix for MySQL phrase search
-* (bug 11321) Fix width of gallerybox when option "width=xxx" is used
-* (bug 7890) Special:BrokenRedirects links deleted redirects to a non-existent
- page
-* Fix initial statistics when installing: add correct values
-* (bug 11342) Fix several 'returnto' links in permissions/error pages which
- linked to the main page instead of targetted page
-* Strike the link to the redirect rather than using an asterisk in
- Special:Listredirects
-* (bug 11355) Fix false positives in Safe Mode and other config detection
- when boolean settings are disabled with 'Off' via php_admin_value/php_value
-* (bug 11292) Fixed unserialize errors with Postgres by creating special Blob
- object.
-* (bug 11363) Make all metadata fields bytea when using Postgres.
-* (bug 11331) Add buildConcat() and use CASE not IF for DB compatibility. Make
- oldimage cascade delete via image table for Postgres, change fa_storage_key
- TEXT.
-* (bug 11438) Live Preview chops returned text
-* Show the right message on account creation when the user is blocked
-* (bug 11450) Fix creation of objectcache table on upgrade
-* Fix namespace selection after submit of Special:Newpages
-* Make input form of Special:Newpages nicer for RTL wikis
-* (bug 11462) Fix typo in LanguageGetSpecialPageAliases hook name
-* (bug 11474) Fix unintentional fall-through in math error handling
-* (bug 11478) Fix undefined method call in file deletion interface
-* (bug 278) Search results no longer highlight incorrect partial word matches
-* Compatibility with incorrectly detected old-style DJVU mime types
-* (bug 11560) Fix broken HTML output from weird link nesting in edit comments.
- Nested links (as in image caption text) still don't work _right_ but they're
- less wrong
-* (bug 9718) Remove unnecessary css from main.css causing spacing issues on
- some browsers.
-* (bug 11574) Add an interface message loginstart, which, similarly to loginend,
- appears just before the login form. Patch by MinuteElectron.
-* Do not cache category pages if using 'from' or 'until'
-* Created new hook getUserPermissionsErrors, to go with userCan changes.
-* Diff pages did not properly display css/js pages.
-* (bug 11620) Add call to User::isValidEmailAddr during accout creation.
-* (bug 11629) If $wgEmailConfirmToEdit is true, require people to supply an
- email address when registering.
-* (bug 11612) Days to show in recent changes cannot be larger than 7
-* (bug 11131) Change filearchive width/height columns to int for Postgres
-* Support plural in undeleted{revisions,revisions-files,files}
-* (bug 11343) If the database is read-only, ensure that undelete fails.
-* (bug 11690) Show revert link for page moves in Special:Log to allowed users
- only
-* Initial-lowercase prefix checks in namespaceDupes.php now actually work.
-* Fix regression in LinkBatch.php breaking PHP 5.0
-* (bug 11452) wfMsgExt uses sometimes wrong language object for parsing magic
- words when called with options ''parsemag'' or ''content''.
-* (bug 11727) Support plural in 'historysize' message
-* (bug 11744) Incorrect return value from Title::getParentCategories()
-* (bug 11762) Fix native language name of Akan (ak)
-* (bug 11722) Fix inconsistent case in unprotect tabs
-* (bug 11795) Be more paranoid about confirming accept-encoding header is
- present
-* (bug 11809) Use formatNum() for more numbers
-* (bug 11818) Fix native language name of Inuktitut (iu)
-* Remove all commas when parsing float numbers in sorted tables
-* Limit text field of deletion, protection and user rights changes reasons to
- 255 characters (already restricted in the database)
-* In the deletion default reasons, calculate how much text to get from the
- article text, rather than getting 150 characters (which may be too much)
-* Add two messages for Special:Blockme which were used but undefined
-* (bug 11921) Support plural in message number_of_watching_users_pageview
-* If an IP address is blocked as part of a rangeblock, attempting to unblock
- the single IP should not unblock the entire range.
-* (bug 6695) Fix native language name of Southern Sotho (Sesotho) (st)
-* Make action=render follow redirects by default
-* If restricted read access was enabled, whitelist didn't work with special
- pages which had spaces in theirs names
-* If restricted read access was enabled, requests for non-existing special pages
- threw an exception
-* Feeds for recent changes now provide correct URLs for the change, not just
- the page
-* Check for if IP is blocked as part of a range when unblocking (see above bug-
- fix) was faulty. Now fixed.
-* Fixed wpReason URL parameter to action=delete.
-* Do not force a password for account creation by email
-* Ensure that rate-limiting is applied to rollbacks.
-* Make a better rate-limiting error message (i.e. a normal MW error,
- rather than an "Internal Server Error").
-* Do not present an image bigger than the source when 'frameless' option is used
- (to be consistent with the 'thumb' option now)
-* Support {{PLURAL}} for import log
-* Make sure that the correct log entries are shown on Special:Userrights even
- for users with special characters in their names
-* The number of watching users in watchlists was always reported as 1
-* namespaceDupes.php no longer dies when coming across an illegal title
-* (bug 12143) Do not show a link to patrol new pages for non existent pages
-* (bug 12166) Fix XHTML validity for Special:Emailuser
-* (bug 11346) Users who cannot edit a page can now no longer unprotect it.
-* (bug 451) Add a generic Traditional / Simplified Chinese conversion table,
- instead of a Traditional conversion with Taiwan variant, and a Simplified
- conversion with China variant.
-* (bug 12178) Fix wpReason parameter to action=delete, again.
-* Graceful behavior for updateRestrictions.php if a page already has records
- in the page_restrictions matching its old page_restrictions field.
- May help with odd upgrade issues or race condition.
-* (bug 11993) Remove contentsub "revision history"
-* (bug 11952) Ensure we quote_ident() all schema names as needed
- inside of the DatabasePostgres.php file.
-* (bug 12184) Exceptions now sent to stderr instead of stdout for command-line
- scripts, making for cleaner reporting during batch jobs. PHP errors will also
- be redirected in most cases on PHP 5.2.4 and later, switching 'display_errors'
- to 'stderr' at runtime.
-* (bug 12148) Text highlight wasn't applied to cleanly deleted and added
- lines in diff output
-* (bug 10166) Fix a PHP warning in Language::getMagic
-* Only mark rollback edits as minor if the user can normally mark edits minor
-* Escape page names in the move successful page (e.g. for pages with two
- apostrophes).
-* (bug 12145) Add localized names of kk-variants
-* (bug 12259) Localize the numbers in deleted pages on the sysop view
-* Set proper page title for successful file deletion
-* (bug 11221) Do not show 'Compare selected versions' button for a history page
- with one revision only
-* (bug 12267) Set the default date format to Thai solar calender for the Thai
- language
-* (bug 10184) Extensions' stylesheets and scripts should be loaded before
- user-customized ones (like Common.css, Common.js)
-* (bug 12283) Special:Newpages forgets parameters
-* (bug 12031) All namespaces doesn't work in Special:Newpages
-* (bug 585) Only create searchindex replica table for parser tests if db is
- MySQL
-* Allow --record option if parserTests.php to work when using Postgres
-* (bug 12296) Simplify cache epoch in default LocalSettings.php
-* (bug 12346) XML fix when body double-click and click handlers are present
-* Fix regression -- missing feed links in sidebar on Special:Recentchanges
-* (bug 12371) Handle more namespace case variants in namespaceDupes.php
-* (bug 12380) Bot-friendly EditPage::spamPage
-* (bug 8066) Spaces can't be entered in special page aliases
-* Hide undo link if user can't edit article
-* (bug 12416) Fix password setting for createAndPromote.php
-* (bug 3097) Inconsistently usable titles containing HTML character entities
- are now forbidden. A run of cleanupTitles.php will fix up existing pages.
-* (bug 12446) Permissions check fix for undelete link
-* (bug 12451) AJAX title normalization tweaks
-* When a user creating a page is not allowed to either create the page nor edit
- it, all applicable reasons are now shown.
-* (bug 11428) Allow $wgScript inside $wgArticlePath when emulating PATH_INFO
- Fixes 'root'-style rewrite configurations
-* (bug 12493) Removed hardcoded MAX_FILE_SIZE from Special:Import upload form
-* (bug 12489) Special:Userrights listed in restricted section again
-* (bug 12553) Fixed invalid XHTML in edit conflict screen
-* (bug 12505) Fixed section=0 with action=raw
-* (bug 12614) Do not log user rights change that didn't change anything
-* (bug 12584) Don't reset cl_timestamp when auto-updating sort key on move
-* (bug 12588) Fix selection in namespace selector on Special:Newpages
-* Use only default options when generating RSS and Atom syndication links.
- This should help prevent infinite link loops that some software may follow,
- and will generally keep feed behavior cleaner.
-* (bug 12608) Unifying the spelling of getDBkey() in the code.
-* (bug 12611) Bot flag ignored in recent changes
-* (bug 12617) Decimal and thousands separators for Romanian
-* (bug 12567) Fix for misformatted read-only messages on edit, protect.
- Also added proper read-only checks to several special pages.
- Have removed read-only checks from the general user permission framework.
-* Creating a site with a name containing '#' is no longer permitted, since the
- name will not work (but $wgSiteName is not checked if manually set).
-* (bug 12695) Suppress dvips verbiage from web server error log
-* (bug 12716) Unprotecting a non-protected page leaves a log entry
-* Log username blocks with canonical form of name instead of input form
-* (bug 11593, 12719) Fixes for overzealous invocation of thumb.php.
- Non-image handlers and full-size images may now decline it, fixing
- mystery failures when using $wgThumbnailScriptPath.
-* (bug 12327) Comma in username no longer disrupts mail headers
-* (bug 6436) Localization of Special:Import XML parser Error message(s).
-* Security fix for API on MSIE
-* (bug 12768) Database query syntax error in maintenance/storage/compressOld.inc
-* (bug 12753) Empty captions in MediaWiki:Sidebar result in PHP errors
-* (bug 12790) Page protection is not logged when edit-protection is used
- and move-protection is not
-* (bug 12793) Fix for restricted namespaces/pages in Special:Export
-* Fix for Special:Export so it doesn't ignore the page named '0'
-* Don't display rollback link if the user doesn't have all required permissions
-* The comment of a time-limited protection now contains the date in the default
- format
-* (bug 12880) wfLoadExtensionMessages does not use $fallback from MessagesXx.php
-* (bug 12885) Correction for Russian convertPlural function
-* (bug 12768) Make DatabasePostgres->hasContraint() schema aware.
-* (bug 12735) Truncate usernames in comments using mb_ functions.
-* (bug 12892) Poor tab indexing on "delete file" form
-* (bug 12660) When creating an account by e-mail, do not send the creator's IP
- address
-* (bug 12931) Fix wrong global variable in SpecialVersion
-* (bug 12919) Use 'deletedrevision' message as content when deleting an old file
- version
-* (bug 12952) Using Nosuchusershort instead of Nosuchuser when account creation
- is disabled
-* (bug 12869) Magnify icon alignment should be adjusted using linked CSS
-* Fixing message cache updates for MediaWiki messages moves
-* (bug 12815) Signature timestamps were always in UTC, even if the timezone code
- in parentheses after them claimed otherwise
-* (bug 12732) Fix installer and searching to handle built-in tsearch2 for Postgres.
-* (bug 12784) Change "bool" types to smallint to handle Postgres 8.3 strictness.
-* (bug 12301) Allow maintenance/findhooks.php to search hooks in multiple directories.
-* (bug 7681, 11559) Cookie values no longer override GET and POST variables.
-* (bug 5262) Fully-qualified $wgStylePath no longer corrupted on XML feeds
-* (bug 3269) Inaccessible titles ending in '/.' or '/..' now forbidden.
-* (bug 12935, 12981) Fully-qualify archive URLs in delete, revert messages
-* (bug 12938) Fix template expansion and 404 returns for action=raw with section
-* (bug 11567) Fix error checking for PEAR::Mail. UserMailer::send() now returns
- true-or-WikiError, which seems to be the calling convention expected by half
- its callers already
-* (bug 12846) IE rtl.css issue in RTL wikis special:Preferences when selecting an
- LTR user language
-* (bug 13005) DISPLAYTITLE does not work on preview
-* (bug 13004) Fix error on Postgres searches that return too many results.
+== Changes since 1.13.0rc2 ==
+
+* (bug 13770) Fixed incorrect detection of PHP's DOM module
+* Fix regression from r37834: accesskey tooltip hint should be given for the
+ minor edit and watch labels on the edit page.
+* Updated Chinese simplified/traditional conversion tables
+
+== Changes since 1.13.0rc1 ==
+
+* $wgForwardSearchUrl has been removed entirely. Documented setting since 1.4
+ has been $wgSearchForwardUrl.
+* (bug 14907) DatabasePostgres::fieldType now defined.
+* (bug 14966) Fix SearchEngineDummy class for silently non-functional search
+ on Sqlite instead of horribly fatal error breaky one.
+* (bug 14987) Only fix double redirects on page move when the checkbox is
+ checked
+* (bug 13376) Use $wgPasswordSender, not $wgEmergencyContact, as return
+ address for page update notification mails.
+* API: Registration time of users registered before the DB field was created is now
+ shown as empty instead of the current time.
+* (bug 14904): fragments were lost when redirects were fixed.
+* Added magic word __STATICREDIRECT__ to suppress the redirect fixer
+* (bug 15035) Revert English linkTrail to /^([a-z]+)(.*)$/sD, as it was before
+ r36253. Multiple reports of breakage due to old (pre-5.0) PCRE libraries,
+ both bundled with PHP and packaged with distros such as RHEL.
+* (bug 14944) Shell invocation of external programs such as ImageMagick convert
+ was broken in PHP 5.2.6, if the server had a non-UTF-8 locale.
+
+== Changes since 1.12 ==
+
+=== Configuration changes in 1.13 ===
+
+* New option $wgFeed can be set false to turn off syndication feeds
+* (bug 5745) Special:Whatlinkshere now shows up to $wgMaxRedirectLinksRetrieved
+ links through each redirect instead of hardcoded 500
+* Set $wgUploadSizeWarning to false by default
+* Added $wgLBFactoryConf, for generic configuration of multi-master wiki farms
+* Removed $wgAlternateMaster, use $wgLBFactoryConf
+* (bug 13562) Misspelled option $wgUserNotifedOnAllChanges changed to
+ $wgUserNotifiedOnAllChanges
+* (bug 12860) New option $wgSitemapNamespaces allows sitemaps to be generated
+ for only some namespaces
+* Removed the emailconfirmed implicit group by default. To re-add it, use:
+ $wgAutopromote['emailconfirmed'] = APCOND_EMAILCONFIRMED;
+ in your LocalSettings.php.
+* (bug 2396) New shared database configuration variables. $wgSharedPrefix allows
+ you to use a shared database with a different prefix. Or you can now use a local
+ database and use prefixes to separate wiki and the shared tables. And the new
+ $wgSharedTables variable allows you to specify a list of tables to share.
+* Automatic edit summaries can be disabled with $wgUseAutomaticEditSummaries
+* Duplicates of images are now shown on the image page
+* $wgRCFilterByAge allows for the list of dates in recent changes special pages to
+ be filtered to only those within the range of $wgRCMaxAge
+* $wgRCLinkLimits and $wgRCLinkDays allow for customization of the list and limits
+ displayed on the recent changes special pages
+* The "createpage" permission is no longer required when uploading if the target
+ image page already exists
+* $wgMaximumMovedPages restricts the number of pages that can be moved at once
+ (default 100) with the new subpage-move functionality of Special:Movepage
+* Hooks display in Special:Version is now disabled by default, use
+ $wgSpecialVersionShowHooks = true; to enable it.
+* $wgActiveUserEditCount sets the number of edits that must be performed over
+ a certain number of days to be considered active
+* $wgActiveUserDays is that number of days
+* $wgRateLimitsExcludedGroups has been deprecated in favor of
+ $wgGroupPermissions[]['noratelimit']. The former still works, however.
+* New $wgGroupPermissions option 'move-subpages' added to control bulk-moving
+ subpages along with pages. Assigned to 'user' and 'sysop' by default.
+* New $wgRC2UDPOmitBots allows user to omit bot edits from UDP output.
+ Default: false
+* Removed $wgEnableCascadingProtection option. Disabling cascading protection
+ is no longer possible.
+* $wgMessageCacheType defines now the type of cache used by the MessageCache class,
+ previously it was choosen based on $wgParserCacheType
+* $wgExtensionAliasesFiles option to simplify adding aliases to special pages
+ provided by extensions, in a similar way to $wgExtensionMessagesFiles
+* Added $wgXMLMimeTypes, an array of XML mimetypes we can check for
+ with MimeMagic.
+* Added $wgDirectoryMode, which allows for setting the default CHMOD value when
+ creating new directories.
+* (bug 14843) $wgCookiePrefix can be set by LocalSettings now, false defaults
+ current behavior.
+
+=== New features in 1.13 ===
+
+* __HIDDENCAT__ on a category page causes the category to be hidden on the
+ article page
+* Do not show edit permissions errors on a red link click, just redirect to the
+ article. This is so that readers who don't know what a red link is are not
+ confused when they are told they are range-blocked.
+* Add a new hook ImageBeforeProduceHTML to allow extensions to modify wikitext
+ image syntax output
+* (bug 13100) Added 'preloadtitle' parameter to action=edit&section=new that
+ pre-fills the section title field
+* (bug 13112) Added Special:RelatedChanges alias to Special:RecentChangesLinked
+* (bug 13130) Moved edit token and autosummary fields above edit tools to
+ reduce broken form submissions
+* Add --old-redirects-only option to maintenance/refreshLinks.php, to add old
+ redirects to the redirect table
+* Add links to page and file deletion forms to edit predefined delete reasons
+* (bug 13269) Added MediaWiki:Uploadfooter to the bottom of Special:Upload
+* (bug 2815) Search results for media now use thumbnail instead of text extract
+* When a page doesn't exist, the tab should say "create", not "edit"
+* (bug 12882) Added a span with class "patrollink" around "Mark as patrolled"
+ link on diffs
+* Magic word formatnum can now take raw suffix to undo formatting
+* Add updatelog table to reliably permit updates that don't change the schema
+* Add category table to allow better tracking of category membership counts
+** (bug 1212) Give correct membership counts on the pages of large categories
+** Use category table for more efficient display of Special:Categories
+* (bug 1459) Search for duplicate files by hash: Special:FileDuplicateSearch
+* (bug 9447) Added hooks for search result headings
+* Image redirects are now enabled by default
+* (bug 13450) Email confirmation can now be canceled before the expiration
+* (bug 13490) Show upload/file size limit on upload form
+* Redesign of Special:UserRights
+* Make rev_deleted log entries more intelligible
+* (bug 6943) Added PAGESINCATEGORY: magic word
+* (bug 13604) Added Special:ListGroupRights
+* (bug 6332, 8617) Added message 'mainpage-description' as duplicate of
+ 'mainpage' and added it to message 'sidebar'
+* Automatically add old redirects to the redirect table when needed
+* (bug 6934) Allow inclusions, links, redirects to be separately toggled on or
+ off on Special:WhatLinksHere
+* Cache image redirects
+* (bug 10457) Organize Special:SpecialPages into sections
+* Add a new hook EditPageBeforeConflictDiff to allow extensions like FCKeditor
+ to modify the output for edit conflicts
+* Add class="nested" for <fieldset>s so fieldsets inside fieldsets get
+ a slightly less huge margin and padding
+* (bug 13527) Use sitemaps.org format 0.9 instead of a Google-specific format
+* Allow \C and \Q as TeX commands to match \R, \N, \Z
+* On Special:UserRights, when you can add a group you can't remove or remove
+ one you can't add, a notice is printed to warn you
+* (bug 12698) Create PAGESIZE parser function, to return the size of a page
+* Allow the "log in / create account" link in the toolbar to have different
+ text from Special:UserLogin title (new message 'nav-login-createaccount')
+* Say "log in / create account" if an anonymous user can create an account,
+ otherwise just "log in", consistently across skins
+* Special:Shortpages and Special:Longpages now returns pages in all content
+ namespaces, not just NS_MAIN.
+* (bug 889) Improve conflict-handling between shared upload repository
+ and local one
+* Update documentation links in auto-generated LocalSettings.php
+* (bug 13584) The new hook SkinTemplateToolboxEnd was added.
+* (bug 709) Cannot rename/move images and other media files [EXPERIMENTAL]
+* Custom rollback summaries now accept the same arguments as the default message
+* (bug 12542) Added hooks for expansion of Special:Listusers
+* Drop-down AJAX search suggestions (turn on $wgEnableMWSuggest)
+* More relevant search snippets (turn on $wgAdvancedSearchHighlighting)
+* (bug 13950) Allow users to watch the user/talk pages of users they block.
+* (bug 13970) Allow MonoBook-based skins to specify their own print stylesheet
+* Show image links on Special:Whatlinkshere
+* Use rel="start", "prev", "next" appropriately on Pager-based pages
+* Add support for SQLite
+* AutoAuthenticate hook renamed to UserLoadFromSession
+* (bug 13232) importScript(), importStylesheet() funcs available to custom JS
+* (bug 13095) Search by first letters or digits in [[Special:Categories]]
+* Users moving a page can now move all subpages automatically as well
+* (bug 14259) Localisation message for upload button on Special:Import is now
+ 'import-upload' instead of 'upload'
+* Add information about user group membership to Special:Preferences
+* (bug 14146) Wrap usage section on imagepages into <div>s.
+* New layout for Special:Specialpages. Restricted pages are marked but not separated
+ from other pages in their group.
+* (bug 14263) Show a diff of the revert on rollback notification page.
+* (bug 13434) Show a warning when hash identical files exist
+* Sidebar is now cached for all languages
+* The User class now contains a public function called isActiveEditor. Figures
+ out if a user is active based on at least $wgActiveUserEditCount number of
+ edits in the last $wgActiveUserDays days.
+* SpecialSearchResults hook now passes results by reference, so they can be
+ changed by extensions.
+* Add a new hook LinkerMakeExternalLink to allow extensions to modify the output of
+ external links.
+* (bug 14132) Allow user to disable bot edits from being output to UDP.
+* (bug 14328) jsMsg() within Wikibits now accepts a DOM object, not just a string
+* (bug 14558) New system message (emailuserfooter) is now added to the footer of
+ e-mails sent with Special:Emailuser
+* Add support for Hijri (Islamic) calendar
+* Add a new hook LinkerMakeExternalImage to allow extensions to modify the output
+ of external (hotlinked) images.
+* (bug 14604) Introduced the following features for the LanguageConverter:
+ Multi-tag support, single conversion flag, remove conversion flag on a single
+ page, description flag, variant name, multi-variant fallbacks.
+* Add zh-mo and zh-my variants for the zh language
+* (bugs 4832, 9481, 12890) Special:Recentchangeslinked now has all options that
+ are in Special:Recentchanges
+* Allow an $error message to be passed to ArticleDelete hook
+* Allow extensions to modify the user creation form by calling addInputItem();
+* Add meta generator tag to HTML output
+* MediawikiPerformAction hook is now passed the Mediawiki object
+* Added blank special page Special:BlankPage for benchmarking, etc.
+* Foreign repo file descriptions and thumbnails are now cached.
+* (bug 11732) Allow localisation of edit button images
+* Allow the search box, toolbox and languages box in the Monobook sidebar to be
+ moved around arbitrarily using special sections in [[MediaWiki:Sidebar]]:
+ SEARCH, TOOLBOX and LANGUAGES
+* Add a new hook NormalizeMessageKey to allow extensions to replace messages before
+ the database is potentially queried
+* (bug 9736) Redirects on Special:Fewestrevisions are now marked as such.
+* New date/time formats in Cs localization according to ČSN and PČP.
+* Special:Recentchangeslinked now includes changes to transcluded pages and
+ displayed images; also, the "Show changes to pages linked" checkbox now works on
+ category pages too, showing all links that are not categorizations
+* (bug 4578) Automatically fix redirects broken by a page move
+
+=== Bug fixes in 1.13 ===
+
+* (bug 10677) Add link to the file description page on the shared repository
+* (bug 13084) Increase size of source/destination filename fields in upload form
+* (bug 13115) rebuildrecentchanges should print the current value of $wgRCMaxAge
+* (bug 13140) Show parent categories in category namespace
+* (bug 13149) Correctly format 'fileexists' message on Upload page
+* Make the default filepageexists message accurate
+* (bug 12988) $wgMinimalPasswordLength no longer breaks create user by email
* (bug 13022) Fix upload from URL on PHP 5.0.x
-* (bug 13139, 13074) Fix request data for parameters with numeric names
-* (bug 13086) Trackbacks were returning invalid XML (extra whitespace)
+* (bug 13132) Unable to unprotect pages protected with earlier versions of MediaWiki
+* (bug 12723) OpenSearch description name now uses more compact language code
+ to avoid passing the length limit as often, is customizable per site via
+ 'opensearch-desc' message.
+* (bug 13135) Special:Userrights now passes IDs through form submission
+ to allow functionality on not-quite-right usernames
+* (bug 12575) Prevent duplicate patrol log entries from being created
+* (bug 13174) __HIDDENCAT__ now applies only to category pages
+* (bug 13031) Add links to user pages in e-mail form
+* (bug 13147) Description for categoriespagetext (used in Special:Categories) reworded
+* (bug 11561) Fix fatal error when calling action=revert to non-image page
* (bug 12430) Fix call to private method LinkFilter::makeRegex fatal error in
maintenance/cleanupSpam.php
-* (bug 13211) Don't break edit buttons when Image namespace includes apostrophe
-* Fix regression with upgrades from 1.4 or below.
-* Fix regression: make dumpUploads.php work again
-* dumpUploads.php options now actually supported
-* wfRelativePath() no longer includes spurious ".." when base path is "/"
-* wfRelativePath() now returns full path for differing Windows drives
-* (bug 13274) Change link for message to ucfirst
-
-== Parser changes in 1.12 ==
-
-For help with migration to the MediaWiki 1.12 parser, please visit:
-
-http://meta.wikimedia.org/wiki/Migration_to_the_new_preprocessor
-
-The parser pass order has changed from
-
- * Extension tag strip and render
- * HTML normalisation and security
- * Template expansion
- * Main section...
-
-to
-
- * Template and extension tag parse to intermediate representation
- * Template expansion and extension rendering
- * HTML normalisation and security
- * Main section...
-
-The main effect of this for the user is that the rules for uncovered syntax
-have changed.
-
-Uncovered main-pass syntax, such as HTML tags, are now generally valid, whereas
-previously in some cases they were escaped. For example, you could have "<ta" in
-one template, and "ble>" in another template, and put them together to make a
-valid <table> tag. Previously the result would have been "&lt;table&gt;".
-
-Uncovered preprocessor syntax is generally not recognised. For example, if you
-have "{{a" in Template:A and "b}}" in Template:B, then "{{a}}{{b}}" will be
-converted to a literal "{{ab}}" rather than the contents of Template:Ab. This
-was the case previously in HTML output mode, and is now uniformly the case in
-the other modes as well. HTML-style comments uncovered by template expansion
-will not be recognised by the preprocessor and hence will not prevent template
-expansion within them, but they will be stripped by the following HTML security
-pass.
-
-Bug 5678 has been fixed. This has a number of user-visible effects related to
-the removal of this double-parse. Please see the wiki page for examples.
-
-Message transformation mode has been removed, and replaced with "preprocess"
-mode. This means that some MediaWiki namespace messages may need to be updated,
-especially ones which took advantage of the terribly counterintuitive behaviour
-of the former message mode.
-
-The header identification routines for section edit and for numbering section
-edit links have been merged. This removes a significant failure mode and fixes a
-whole category of bugs (tracked by bug #4899). Wikitext headings uncovered by
-template expansion will still be rendered into a heading tag, and will get an
-entry in the TOC, but will not have a section edit link. HTML-style headings
-will also not have a section edit link. Valid wikitext headings present in the
-template source text will get a template section edit link. This is a major
-break from previous behaviour, but I believe the effects are almost entirely
-beneficial.
-
-The main motivation for making these changes was performance. The new two-pass
-preprocessor can skip "dead branches" in template expansion, such as unfollowed
-#switch cases and unused defaults for template arguments. This provides a
-significant performance improvement in template-heavy test cases taken from
-Wikipedia. Parser function hooks can participate in this performance improvement
-by using the new SFH_OBJECT_ARGS flag during registration.
-
-The pre-expand include size limit has been removed, since there's no efficient
-way to calculate such a figure, and it would now be meaningless for performance
-anyway. The "preprocessor node count" takes its place, with a generous default
-limit.
-
-The context in which XML-style extension tags are called has changed, so
-extensions which make use of the parser state may need compatibility changes.
-
-The new preprocessor syntax has been documented in Backus-Naur Form at:
-
-http://www.mediawiki.org/wiki/Preprocessor_ABNF
-
-The ExpandTemplates extension now has the ability to generate an XML parse
-tree from wikitext source. This parse tree corresponds closely to the grammar
-documented on that page.
-
-=== API changes in 1.12 ===
-
-Full API documentation is available at http://www.mediawiki.org/wiki/API
-
-* (bug 11275) Enable descending sort in categorymembers
-* (bug 11308) Allow the API to output the image metadata
-* (bug 11296) Temporary fix for escaping of ampersands inside links in
- pretty-printed
- help document.
-* (bug 11405) Expand templates implementation in the API
-* (bug 11218) Add option to feedwatchlist to display multiple revisions for each
- page.
-* (bug 11404) Provide name of exception caught in error code field of internal
- api error messages.
-* (bug 11534) rvendid doesn't work
-* Fixed rvlimit of the revisions query to only enforce the lower query limit if
- revision content is requested.
-* Include svn revision number (if install is checked-out from svn) in siteinfo
- query.
-* (bug 11173) Allow limited wikicode rendering via api.php
-* (bug 11572) API should provide interface for expanding templates
-* (bug 11569) Login should return the cookie prefix
-* (bug 11632) Breaking change: Specify the type of a change in the recentchanges
- list as 'edit', 'new', 'log' instead of 0, 1, 2, respectively.
-* Compatibility fix for PHP 5.0.x.
-* Add rctype parameter to list=recentchanges that filters by type
-* Add apprtype and apprlevel parameters to filter list=allpages by protection
- types and levels
-* Add apdir parameter to enable listing all pages from Z to A
-* (bug 11721) Use a different title for results than for the help page.
-* (bug 11562) Added a user_registration parameter/field to the list=allusers
- query.
-* (bug 11588) Preserve document structure for empty dataset in backlinks query.
-* Outputting list of all user preferences rather than having to request them by
- name
-* (bug 11206) api.php should honor maxlag
-* Make prop=info check for restrictions in the old format too.
-* Add apihighlimits permission, default for sysops and bots
-* Add limit=max to use maximal limit
-* Add action=parse to render parser output. Use it instead of action=render
- which has been removed
-* Add rvtoken=rollback to prop=revisions
-* Add meta=allmessages to get messages from site's messages cache.
-* Use bold and italics highlighting only in API help
-* Added action={block,delete,move,protect,rollback,unblock,undelete} and
- list={blocks,deletedrevs}
-* Fixed sessionid attribute in action=login
-* Standardized limits. Revisions and Deletedrevisions formerly using
- 200 / 10000, now 500 / 5000, in line with other modules.
-* Added list=allcategories module
-* (bug 12321) API list=blocks reveals private data
-* Fix output of wfSajaxSearch
-* (bug 12413) meta=userinfo missing <query> tag
-* Add list of sections to action=parse output
-* Added action=logout
-* Added cascade flag to prop=info&inprop=protections
-* Added wlshow parameter to list=watchlist, similar to rcshow
- (list=recentchanges)
-* Added support for image thumbnailing to prop=imageinfo
-* action={login,block,delete,move,protect,rollback,unblock,undelete} now must be
- POSTed
-* prop=imageinfo interface changed: iihistory replaced by iilimit, iistart and
- iiend parameters
-* Added amlang parameter to meta=allmessages
-* Added apfilterlanglinks parameter to list=allpages, replacing
- query.php?what=nolanglinks
-* (bug 12718) Added action=paraminfo module that provides information about API
- modules and their parameters
-* Added iiurlwidth and iiurlheight parameters to prop=imageinfo
-* Added format=txt and format=dbg, imported from query.php
-* Added uiprop=editcount to meta=userinfo
-* Added list=users which fetches user information
-* Added list=random which fetches a list of random pages
-* Added page parameter to action=parse to facilitate parsing of existing pages
-* Added uiprop=ratelimits to meta=userinfo
-* Added siprop=namespacealiases to meta=siteinfo
-* Made multiple values for ucuser possible in list=usercontribs
-* (bug 12944) Added cmstart and cmend parameters to list=categorymembers
-* Allow queries to have a where range that does not match the range field
-
-=== Languages updated in 1.12 ===
-
-* Afrikaans (af)
-* Akan (ak) (new)
-* Amharic (am) (new)
-* Aragonese (an)
-* Old English (ang) (new)
-* Arabic (ar)
-* Aramaic (arc)
-* Mapudungun (arn) (new)
-* Assamese (as)
-* Asturian (ast)
-* Avaric (av)
-* Kotava (avk) (new)
-* Aymara (ay)
-* Samogitian (bat-smg)
-* Boarisch (bar)
-* Bikol Central (bcl)
-* Belarusian (be)
-* Belarusian Taraskievica orthography (be-tarask)
-* Bulgarian (bg)
-* Bislama (bi) (new)
-* Bamanankan (bm)
-* Bengali (bn)
-* Bishnupriya Manipuri (bpy)
-* Breton (br)
-* Buginese (bug) (new)
-* Catalan (ca)
-* Zamboangueño (cbk-zam) (new)
-* Min Dong (cdo) (new)
-* Chechen (ce)
-* Cebuano (ceb) (new)
-* Cherokee (chr) (new)
-* Corsican (co) (new)
-* Crimean Tatar (Cyrillic) (crh-cyrl) (new)
-* Crimean Tatar (Latin) (crh-latn) (new)
-* Czech (cs)
-* Cassubian (csb)
-* Old Church Slavonic (cu)
-* Welsh (cy)
-* Danish (da)
-* German (de)
-* German (de-formal) (new)
-* Zazaki (diq) (new)
-* Lower Sorbian (dsb) (new)
-* Middle Dutch (dum) (new)
-* Divehi (dv)
-* Ewe (ee) (new)
-* Greek (el)
-* Emiliano-Romagnolo (eml)
-* English (en)
-* Spanish (es)
-* Estonian (et)
-* Euskara (eu)
-* Extremaduran (ext)
-* Finnish (fi)
-* Persian (fa)
-* Fulah (ff)
-* Võro (fiu-vro)
-* Fijian (fj) (new)
-* Faroese (fo)
-* French (fr)
-* Cajun French (frc)
-* Franco-Provençal (frp)
-* Frisian (fy)
-* Irish (ga)
-* Gagauz (gag) (new)
-* Gön-gnŷ (gan) (new)
-* Scottish Gaelic (gd) (new)
-* Galician (gl)
-* Gilaki (glk) (new)
-* Gothic (got) (new)
-* Ancient Greek (grc) (new)
-* Swiss German (gsw)
-* Hakka (hak)
-* Hawaiian (haw) (new)
-* Hebrew (he)
-* Croatian (hr)
-* Upper Sorbian (hsb)
-* Haitian Creole French (ht)
-* Hungarian (hu)
-* Armenian (hy)
-* Interlingua (ia)
-* Indonesian (id)
-* Interlingue (ie) (new)
-* Igbo (ig) (new)
-* Eastern Canadian (Unified Canadian Aboriginal Syllabics) (ike-cans) (new)
-* Eastern Canadian (Latin) (ike-latn) (new)
-* Ingush (inh) (new)
-* Ido (io) (new)
-* Icelandic (is)
-* Italian (it)
-* Japanese (ja)
-* Jutish (jut) (new)
-* Georgian (ka)
-* Kara-Kalpak (kaa)
-* Kabyle (kab)
-* Kazakh (kk)
-* Kazakh Arabic (kk-arab) (new)
-* Kazakh (China) (kk-cn)
-* Kazakh Cyrillic (kk-cyrl) (new)
-* Kazakh (Kazakhstan) (kk-kz)
-* Kazakh Latin (kk-latn) (new)
-* Kazakh (Turkey) (kk-tr)
-* Kalaallisut (kl) (new)
-* Kannada (kn)
-* Korean (ko)
-* Kölsch (ksh)
-* Kurdish (Arabic) (ku-arab)
-* Kurdish (Latin) (ku-latn)
-* Cornish (kw) (new)
-* Kirghiz (ky) (new)
-* Latin (la)
-* Ladino (lad) (new)
-* Luxembourgish (lb) (new)
-* Lingua Franca Nova (lfn) (new)
-* Lak (lbe) (new)
-* Ganda (lg)
-* Limbugian (li)
-* Líguru (lij) (new)
-* Lozi (loz) (new)
-* Lingala (ln)
-* Lao (lo)
-* Lithuanian (lt)
-* Maithili (mai) (new)
-* Moksha (mdf) (new)
-* Malagasy (mg) (new)
-* Malayalam (ml)
-* Macedonian (mk)
-* Marathi (mr)
-* Malay (ms)
-* Erzya (myv) (new)
-* Nauru (na) (new)
-* Nahuatl (nah)
-* Min-nan (nan)
-* Napolitan (nap)
-* Low Saxon (nds)
-* Dutch Low Saxon (nds-nl)
-* Nepali (ne)
-* Newari (new) (new)
-* Dutch (nl)
-* Norwegian (nynorsk) (nn)
-* Norwegian (bokmål)‬ (no)
-* Novial (nov) (new)
-* Northern Sotho (nso) (new)
-* Occitan (oc)
-* Pangasinan (pag) (new)
-* Pampanga (pam) (new)
-* Papiamento (pap) (new)
-* Deitsch (pdc) (new)
-* Pfälzisch (pfl) (new)
-* Polish (pl)
-* Piemontèis (pms)
-* Pontic (pnt) (new)
-* Pashto (ps)
-* Portugese (pt)
-* Quechua (qu)
-* Rhaeto-Romance (rm) (new)
-* Romanian (ro)
-* Russian (ru)
-* Megleno-Romanian (ruq) (new)
-* Megleno-Romanian (Cyrillic script) (ruq-cyrl) (new)
-* Megleno-Romanian (Greek script) (ruq-grek) (new)
-* Megleno-Romanian (Latin script) (ruq-latn) (new)
-* Sakha (sah)
-* Sardinian (sc)
-* Sicilian (scn)
-* Scots (sco) (new)
-* Sindhi (sd)
-* Sassarese (sdc) (new)
-* Seri (sei) (new)
-* Sango (sg) (new)
-* Tachelhit (shi)
-* Sinhalese (si) (new)
-* Slovak (sk)
-* Samoan (sm) (new)
-* Southern Sami (sma) (new)
-* Serbian (Cyrillic) (sr-ec)
-* Swati (ss) (new)
-* Southern Sotho (st) (new)
-* Saterland Frisian (stq) (new)
-* Sundanese (su)
-* Swedish (sv)
-* Swahili (sw) (new)
-* Tamil (ta)
-* Teluga (te)
-* Tetun (tet) (new)
-* Tajik (tg)
-* Thai (th)
-* Tagalog (tl) (new)
-* Tonga (to) (new)
-* Turkish (tr)
-* Tuvinian (tyv)
-* Uyghur (ug)
-* Uzbek (uz)
-* Venitian (vec)
-* Vietnamese (vi)
-* West Flemish (vls)
-* Volapük (vo)
-* Walloon (wa)
-* Wolof (wo)
-* Wu (wuu) (new)
-* Xhosa (xh) (new)
-* Mingrelian (xmf) (new)
-* Yiddish (yi)
-* Yoruba (yo) (new)
-* Cantonese (yue)
-* Zhuang (za)
-* Zealandic (zea)
-* Chinese (zh)
-* Old Chinese/Late Time Chinese (zh-classical)
-* Chinese (Simplified) (zh-hans)
-* Chinese (Traditional) (zh-hant)
-* Chinese (Taiwan) (zh-tw)
-* Zulu (zu) (new)
+* All skins should have the "mediawiki" class on the body element
+* (bug 13019) Message cache for some extensions not loaded at time of editing
+* (bug 13247) Prettified ISBN links
+* maintenance/refreshLinks.php did not fix page_id 1 with the --new-only option
+* (bug 13110) Don't show "Permission error" page if the edit is already rolled
+ back when using rollback
+* (bug 13012) Use content messages for block options when generating the
+ recentchanges entry
+* (bug 13274) Change links for messages to ucfirst
+* (bug 13273) Un-hardcode some punctuation (add new messages colon-separator,
+ autocomment-prefix)
+* Parse MediaWiki message translations with a correct language setting on preview
+* (bug 13281) Treat X-Forwarded-For, Client-ip and User-Agent headers as
+ case-insensitive names.
+* Adding the fix for lists in RTL wikis to more skins, and fixing the image toc
+* (bug 8157) Remove redirects from Special:Unusedtemplates. Patch by WebBoy.
+* (bug 10721) Duplicate section anchors with differing case now disambiguated
+ for Internet Explorer's sake and standards compliance
+* (bug 13298) Tighter limits on Special:Newpages limits when embedding
+* Email subject in content language instead of sending user's UI language
+* (bug 13251) Allow maintenance rebuild scripts to work with Postgres
+* (bug 2084) Fixed incorrect regex to match redirects
+* (bug 3131) Manually-specified upload destination filename is no longer
+ overwritten by browsing for a file after you wrote it.
+* (bug 7251) Sidebars generated by MediaWiki:Sidebar now have the class
+ 'generated-sidebar'.
+* (bug 13265) Media handler is missing 'image/x-bmp'
+* (bug 13407) MediaWiki:Powersearch is used in two places
+* (bug 13403) Fix cache invalidation of history pages when old revisions change
+* (bug 11563) Deprecated SearchMySQL4 class; merged code to SearchMySQL
+* (bug 12801) Fix link in subtitle message in AJAX search
+* (bug 13428) Fix regression in protection form layout HTML validity
+* (bug 9403) Sanitize newlines from search term input
+* (bug 13429) Separate date and time in message sp-newimages-showfrom
+* (bug 13137) Allow setting 'editprotected' right separately from 'protect',
+ so groups may optionally edit protected pages without having 'protect' perms
+* Disallow deletion of big pages by means of moving a page to its title and
+ using the "delete and move" option.
+* (bug 13466, 13632) White space differences not shown in diffs
+* (bug 1953) Search form now honors namespace selections more reliably
+* (bug 12294) Namespace class renamed to MWNamespace for PHP 5.3 compatibility
+* PHP 5.3 compatibility fix for wfRunHooks() called with no parameters
+* (bug 6447) Trackbacks now work with transactional tables, if enabled
+* (bug 6892, 7147) Trackback error handling, optional fields more robust
+* (bug 6813) Don't break HTML validator when using trackbacks
+* Fix for size checks on SVG images with global 'stroke-width' attribute
+* (bug 11874) Inline CSS with !important no longer borken
+* (bug 1600) Strip extra == section markup == in new-comment field
+* (bug 11325) Wrapped page titles in MonoBook skin spaced more nicely
+* (bug 12077) Fix HTML nesting for TOC
+* (bug 344) Purge cache for talk/article pages when deleting the other tab
+* (bug 13436) Treat image captions correctly when they include option keywords
+ (like ending with "px" or starting with "upright")
+* Trackback display formatting fixed
+* Don't die when single-element arrays are passed to SQL query constructors
+ that have an array index other than 0
+* (bug 13522) Fix fatal error in Parser::extractTagsAndParams
+* (bug 13532) Use proper timestamp call when reverting images
+* (bug 13543) Updated FAQ link in the installer sidebar
+* (bug 13540) Date format in confirmation e-mail now matches message language
+* (bug 13554) PHP Notice in old pre-processor when list item is empty.
+* (bug 13556) Don't show a blank form if no image is attached in Special:Upload
+* (bug 13576) maintenance/rebuildrecentchanges.php fails
+* (bug 13441) Allow Special:Recentchanges to show bots only
+* (bug 13431) Show true message source in Special:Allmessages&ot=php / xml
+* (bug 13463) Login successful page doesn't use user's preferred interface language
+* (bug 13630) Fixed warnings for pass by reference at call time in
+ Special:Revisiondelete when generating the log entry.
+* (bug 12064) BeforePageDisplay hook is now called for all skins
+* (bug 13624) Fix regression with manual thumb= parameter on images
+* (bug 11039) Add missing labels on protection form
+* (bug 13458) Preview/edit toolbar spacing now works consistently
+* (bug 13433) Fix action=render on Image: pages
+* (bug 13678) Fix CSS validation for Monobook
+* (bug 13684) Links in Special:ListGroupRights should be in content language
+* (bug 13690) Fix PHP notice on accessing some URLs
+* Hide (undo) link if user isn't able to edit page
+* Invalidate cache of pages that includes images via redirects on upload
+* (bug 13705) Don't show rollback link in page history on incorrect revisions
+* (bug 13708) Don't set "Search results" title when loading Special:Search
+ without query
+* (bug 13736) Don't show MediaWiki:Anontalkpagetext on non-existant IP addresses
+* (bug 13728) Don't trim initial whitespace during section edits
+* (bug 13727) Don't delete log entries from recentchanges on page deletion
+* (bug 13752) Redirects to sections now work again
+* (bug 13725) Upload form watch checkbox state set correctly with wpDestFile
+* (bug 13756) Don't show the form and navigation links of Special:Newpages if
+ the page is included
+* When hiding things on WhatLinksHere, generated URLs should hide them too
+* Properly escape search terms with regex chars so they appear highlighted in
+ search results
+* (bug 13768) pt_title field encoding fixed
+* Do not display empty columns on Special:UserRights if all groups are
+ changeable or all unchangeable
+* Fix fatal error on calling PAGESINCATEGORY with invalid category name
+* (bug 13793) Special:Whatlinkshere filters wrong - after paginating instead of before
+* (bug 13796) Show links to parent pages even if some of them are missing
+* (bug 13816) Filter by main namespace doesn't work on WhatLinksHere
+* (bug 13822) Fatal error on some pages when calculating subpage subtitle
+* (bug 13824) AJAX search suggestion now works with non-SkinTemplate skins
+* Added 'application/x-dia-diagram' MediaWiki's known MIME types
+* (bug 13866) skins/common/shared.css - invalid attribute fixing
+* Hide edit section links on Special:Undelete
+* (bug 13860) Fix "Justify paragraphs" option for Modern skin
+* (bug 13168) accessibility links in Modern skin link to wrong anchor id
+* (bug 13185) No line break after 'subpages' class in Modern skin
+* (bug 13583) No "poweredby" in Modern skin
+* (bug 13880) "Printable" link in Modern skin now formats as print mode
+* (bug 13885) Bump default $wgSVGMaxSize from 1024 to 2048 pixels
+* (bug 13891) Show categories box even if all categories are hidden and user has
+ "show hidden categories" option on
+* (bug 13915) Undefined variable $wltsfield in includes/SpecialWatchlist.php
+* (bug 13913) Special:Whatlinkshere now has correct HTML markup
+* (bug 13905) Blacklist Mac IE from HttpOnly cookies; it eats them sometimes
+* (bug 13922) Fix bad HTML on empty Special:Prefixindex and Special:Allpages
+* (bug 13924) Fix bad HTML on power search form
+* (bug 13820) Fix updater for rev_parent_id population
+* (bug 13925) Fix bad HTML on search results list
+* (bug 13934) Fixing the link to GNU General Public License Version 2
+* Show correct accesskey prefix for Firefox 3 beta (Alt-Shift-, not Alt-)
+* (bug 13949) Special:PrefixIndex/AllPages paging links contain invalid XML
+* (bug 13770) Use Preprocessor_Hash by default to avoid missing DOM module errors
+* (bug 13982) Disable ccmeonemails preference when user-to-user mails disabled
+* (bug 13615) Update case mappings and normalization to Unicode 5.1.0
+ Note that case mappings will only be used if mbstring extension is not present.
+* (bug 14044) Don't increment page view counters on views from bot users
+* (bug 14042) Calling Database::limitResult() misplaced the comment in the log file
+* (bug 14047) Fix regression in installer which hid DB-specific options
+ Also makes SQLite path configurable in the installer.
+* (bug 13546) Follow image redirects on image page
+* (bug 12644) Template list on edit page now sorted on preview
+* (bug 14058) Support pipe trick for namespaces and interwikis with "-"
+* Message name filter on Special:Allmessages now case-insensitive
+* (bug 13943) Fix image redirect behaviour on image pages
+* (bug 14093) Do 'sysop' => 'protect' magic in Title::isValidMoveOperation
+* (bug 14063) Power search form missing <label> for redirects check
+* (bug 14111) Similar filename warning links now lead to correct page
+* (bug 14082) Fix for complex text input vs AJAX suggestions on some browsers
+* (bug 13693) Categories sometimes claim to have a negative number of members
+* (bug 1701) Korean Hangul syllables now broken down properly in Category lists
+ even if the wiki's overall content language is not Korean
+* (bug 12773) addOnloadHook() now calls functions immediately when scripts are
+ loaded after the primary page completion, instead of dropping them
+* (bug 14199) Fix deletion form for image redirect pages
+* (bug 14220) Disabling $wgCheckFileExtensions now works without also
+ disabling $wgStrictFileExtensions
+* (bug 14241) Pages can no longer be protected to levels you are not in
+* (bug 14296) Fix local name of ang: (Anglo-Saxon)
+* (bug 4871) Hardcoded superscript in time zone preferences moved to message
+* (bug 6957) E-mail confirmation links now using English special page name
+ for better compatibility and keeping the links shorter. Avoids problem
+ with corrupt links in Gmail on IE 6.
+* (bug 14273) Fix for HTTP Accept header parsing with spaces as from Konqueror
+* (bug 14312) Update LanguageKaa.php for handling transform issues with i to İ
+ and I to ı
+* (bug 13826) MediaWiki:Defaultns accepts Wikicode
+* (bug 14324) Creating an account is again possible with $wgEmailConfirmToEdit
+ set to true
+* (bug 13034) Interwiki pages can now be reached using Go search button
+* (bug 14362) Change interwiki names of Erzya and Moksha Wikipedias
+* (bug 14370) When a grouppage-x message does not exist the entry on the
+ ListGroupRights special page now links to the project namespace page for it,
+ not the main namespace page.
+* (bug 11659) Urldecode image names in galleries
+* (bug 14258, 14368) Fix for subpage renames in replication environments
+* (bug 14367) Failed block no longer adds phantom watchlist entry
+* (bug 14385) "Move subpages" option no longer tries to move to invalid titles
+* (bug 14386) Fix subpage namespace oddity when moving a talk page
+* (bug 11771) Signup form now not shown if in read-only mode.
+* (bug 12859) $wgRateLimitsExcludedGroups has been deprecated in favor of
+ $wgGroupPermissions[]['noratelimit'].
+* (Bug 13828) Split parameter $1 of MediaWiki:Missingarticle into $1 (=title)
+ and $2 (=revision numbers)
+* (bug 14401) Fix Safari access key tooltips for Windows and >3.1 Mac versions
+* (bug 14432) Fix notice regression in Special:Newpages feed mode
+* (bug 11951) EditPage::getEditToolbar() is now static.
+* (bug 14392) Fix regression breaking table prefix in installer
+* (bug 11084) $wgDBprefix replacement for updater SQL will now work for
+ extension tables using uppercase letters or digits in their names.
+* (bug 12311) Fix regression with lists at start of undeletion preview
+* (bug 14496) Fix regression with parseinline on Special:Upload.
+* We no longer just give up on a missing upload base directory; it's now
+ created automatically if we have sufficient permissions!
+* (bug 14479) MediaWiki:upload-maxfilesize should have a div id wrapper
+* (bug 14497) Throw visible errors in installer scripts when SQL files
+ fail due to database permission or other error
+* (bug 14500) Site feed (Recentchanges) no longer shows up on the actual
+ recent changes page.
+* (bug 14511) MediaWiki:Delete-legend is no longer double escaped
+* Generate correct section anchors for numeric headers
+* (bug 14520) Don't load nonexistent CSS files for Chick/Myskin/Simple skins
+* (bug 14551) Cancel upload no longer automatically suppresses warnings
+* (bug 13878) Deprecate Article::getDB() in favor of direct wfGetDB() calls
+* (bug 4977) Fix for possible squid purging errors when using HTTP purges
+ and multiple servers
+* (bug 14572) Redirects listed on file links on image pages no longer redirect.
+* (bug 14537) Change interwiki name for Old Church Slavonic (cu)
+* (bug 14583) Fix regression in recent changes "limit to certain categories."
+* (bug 14515) HTML nesting cleanup on edit form
+* (bug 14647) Removed unused 'townBox' CSS classes
+* (bug 14687) OutputPage::addStyle() now adds type="text/css" like it should.
+* OpenSearch cleanup; Firefox now sends you to the search page for empty
+ searches instead of the domain root (which may not even be a wiki).
+* (bug 3481) Pages moved shortly after creation are shown at their new title
+ on Special:Newpages.
+* (bug 12716) Trying to unprotect a title that isn't protected no longer
+ generates a log entry.
+* (bug 14088) Excessively long block expiry times are rejected as invalid,
+ keeps the log page from being distorted.
+* (bug 14708) Emulate INSERT...IGNORE with standard SQL for Postgres backend.
+* (bug 14646) Fix some double-escaping of HTML in feed output
+* (bug 14709) Fix login success message formatting when using cookie check
+* (bug 14710) Remove "donate" link from default sidebar
+* (bug 14745) Image moving works on sites that transform thumbnails via 404
+* (bug 2186) Document.write() in wikibits caused failures when using
+ application/xhtml+xml. The calls to this have been removed.
+* (bug 14764) Fix regression in from Article::lastModified(), failed to work
+ on non-mySQL schemas.
+* (bug 14763) Child classes of Database (DatabasePostgres and DatabaseOracle)
+ had stict standards issues with setFakeSlaveLag() and setFakeMaster().
+* (bug 451) Improve the phrase mappings of the Chinese converter arrays.
+* (bug 12487) Rights log is not fully internationalized
+* (bug 10837) Language variants no longer override other languages than base
+* (bug 14778) 'limit' parameter now applies to history feeds as well as
+ history pages
+* (bug 14845) Bug in prefs javascript: Calling an array item without checking
+ its existance.
+* Accesskeys for minor edit/watch checkboxes on edit now work in Firefox 3
+* (bug 12384) Comments in maintenance/*php
+* (bug 12441) ./maintenance/generateSitemap.php fix -fspath requiring
+ a trailing slash.
+* (bug 12568) configuration script now produce valid XHTML.
+* The accesskey to edit a page is now disabled when editing the page, to pre-
+ vent conflicts with Safari shortcuts.
+
+=== API changes in 1.13 ===
+
+* Fixing main page display in meta=siteinfo
+* (bug 13128) Added patrolled flag to list=recentchanges
+* Implemented {bl,ei,iu}redirect (lists links through redirects as well)
+* (bug 13154) Introduced subpages flag to meta=siteinfo&siprop=namespaces
+* (bug 13157) Added ucuserprefix parameter to list=usercontibs
+* (bug 12394) Added rctitles parameter to list=recentchanges, making rcid
+ retrieval easier
+* (bug 13218) Fix inclusion of " character in hyperlinks
+* Added watch and unwatch parameters to action=delete and action=move
+* Added action=edit
+* (bug 11401) Added xmldoublequote to xml formatter
+* Added rvsection parameter to prop=revisions to allow fetching the content of
+ a certain section only
+* Introduced list=allimages
+* (bug 13371) Build page set from image hashes
+* Mark non-existent messages in meta=allmessages as missing
+* (bug 13390) One invalid title no longer kills an entire API query
+* (bug 13419) Fix gblredirect so it actually works
+* (bug 13418) Disable eiredirect because it's useless
+* (bug 13395) list=allcategories should use category table
+* (bug 13442) Missing pages in prop=langlinks and prop=extlinks are now
+ handled properly.
+* (bug 13444) Add description to list=watchlist
+* (bug 13482) Disabled search types handled properly
+* Added inprop=talkid,subjectid to prop=info
+* Added help text message that specifies whether a module is POST-only
+* Added createonly parameter to action=edit
+* Replaced $wgAPIUCUserPrefixMinLength by the more generic $wgAPIMaxDBRows
+* (bug 11719) Remove trailing blanks in YAML output.
+* (bug 13541) Added siprop=specialpagealiases to meta=siteinfo
+* Added fallback8bitEncoding and readonly fields to
+ meta=siteinfo&siprop=general output
+* (bug 13544) Added prop=revid to action=parse
+* (bug 13603) Added siprop=usergroups to meta=siteinfo
+* Cleaned up redirect resolution
+* Added possibility to obtain all external links through list=exturlusage
+* (bug 13606) Added archivename to iiprop
+* (bug 11633) Explicitly convert redirect titles to strings due to PHP's
+ very weak typing on array keys.
+* (bug 12136) Extend allowed characters in JSON callback to ][.'"_A-Za-z0-9
+* (bug 11673) Return error 'unknown_action' in specified format
+* (bug 13618) Added rcprop=redirect and rcshow=redirect to list=recentchanges
+* (bug 13544) Added oldid parameter to action=parse to allow for parsing of old
+ revisions
+* (bug 13718) Return the proper continue parameter for cmsort=timestamp
+* action=login now returns the correct waiting time in the details property
+* (bug 13792) Broken titles are now silently skipped in search results.
+* (bug 13819) exturlusage paging skipped an item
+* Fixed handling of usernames containing spaces in list=block
+* (bug 13836) Fixed fatal errors resulting from combining iiprop=metadata with
+ format=xml
+* (bug 13735) Added prop=categoryinfo module
+* (bug 13945) Retrieve cascading protection sources via inprop=protection
+* (bug 13965) Hardcoded 51 limit on titles is too limiting
+* (bug 13993) apfrom doesn't work with apdir=descending
+* (bug 14018) Introduced alcontinue to list=alllinks to improve paging
+* (bug 14013) Added rcshow=patrolled to list=recentchanges
+* (bug 14028) Added language attribute to interwiki map in meta=siteinfo
+* (bug 14022) Added usprop=registration and auprop=blockinfo
+* (bug 14021) Removed titles= support from list=backlinks (has been obsolete
+ for ages)
+* (bug 13829) Expose parse tree via action=expandtemplates
+* (bug 13606) Allow deletion of images
+* Added iiprop=mime and aiprop=metadata
+* Handled unrecognized values for parameters more gracefully
+* Handled requesting disallowed tokens more gracefully
+* (bug 14140) URL-encoded page titles are now decoded in edit summaries
+* (bug 14243) Only accept post requests in action=edit; patch by HardDisk
+* action=block now returns an ISO8601 timestamp, like all other modules do
+* Added md5 parameter to action=edit
+* (bug 14335) Logging in to unified account using API not possible
+* Added action=emailuser to send an email to a user
+* (bug 14471) Use HTMLTidy and generate limit report in action=parse
+* (bug 14459) Added prependtext and appendtext parameters to action=edit
+* (bug 14526) Unescaped SQL in list=backlinks
+* Added 'hidden' flag to list=allcategories and prop=categoryinfo output
+* Added nocreate parameter to action=edit
+* (bug 14402) Added maxage and smaxage parameters to api.php
+* Added bkip parameter to list=blocks
+* (bug 14651) apprefix and similar parameters are now canonicalized
+* Added clprop=timestamp to prop=categories
+* (bug 14678) API errors now respects $wgShowExceptionDetails and
+ $wgShowSQLErrors
+* (bug 14723) Added time zone and writing direction to meta=siteinfo
+* Added APIQueryInfoTokens and APIQueryRevisionsTokens hooks so extensions
+ can add their own tokens
+* Added block and unblock tokens to prop=info as well
+* Added paging (limit and continue parameters) to
+ prop={links,templatelinks,langlinks,extlinks,categories,images}
+* Added flag "top" to list=usercontribs if the user is the last contributor to
+ the page
+* list=exturlusage in "list all links" mode can now filter by protocol
+
+=== Languages updated in 1.13 ===
+
+MediaWiki supports over 300 languages. Many localisations are updated
+regularly. Below only new and removed languages are listed.
+
+* Egyptian Spoken Arabic (arz) (new)
+* Southern Balochi (bcc) (new)
+* Middle Dutch (dum) (removed)
+* British English (en-gb) (new)
+* Fiji Hindi (Latin) (hif-latn) (new)
+* Old Norse (non) (removed)
+* Tarifit (rif) (new)
+* Serbian cyrillic iyekvian (sr-jc) (removed)
+* Serbian latin iyekavian (sr-jl) (removed)
+* Silesian (szl) (new)
+* Tajiki (Cyrllic script) (tg-cyrl) (new)
+* Tajiki (Latin script) (tg-latn) (new)
+* Chinese (Macau) (zh-mo) (new)
+* Chinese (Malaysia) (zh-my) (new)
== Compatibility ==
-MediaWiki 1.12 requires PHP 5 (5.1 recommended). PHP 4 is no longer supported.
+MediaWiki 1.13 requires PHP 5 (5.1 recommended). PHP 4 is no longer supported.
PHP 5.0.x fails on 64-bit systems due to serious bugs with array processing:
http://bugs.php.net/bug.php?id=34879
@@ -822,7 +613,7 @@ At this time we still recommend 4.0, but 4.1/5.0 will work fine in most cases.
== Upgrading ==
-1.12 has several database changes since 1.11, and will not work without schema
+1.13 has several database changes since 1.12, and will not work without schema
updates.
If upgrading from before 1.7, you may want to run refreshLinks.php to ensure
@@ -847,7 +638,7 @@ set $wgMimeType = "application/xhtml+xml"; to test for remaining problem
cases, but this is not recommended on live sites. (This must be set for
MathML to display properly in Mozilla.)
-For notes on 1.11.x and older releases, see HISTORY.
+For notes on 1.12.x and older releases, see HISTORY.
=== Online documentation ===
diff --git a/UPGRADE b/UPGRADE
index 5be0014d..f817e738 100644
--- a/UPGRADE
+++ b/UPGRADE
@@ -4,7 +4,7 @@ specific problems, check
* the documentation at http://www.mediawiki.org
* the mediawiki-l mailing list archive at
http://lists.wikimedia.org/pipermail/mediawiki-l/
-* the bug tracker at http://bugzilla.wikimedia.org
+* the bug tracker at https://bugzilla.wikimedia.org
for information and workarounds to common issues.
diff --git a/api.php b/api.php
index ce445ef4..77dc52a4 100644
--- a/api.php
+++ b/api.php
@@ -76,7 +76,13 @@ $processor = new ApiMain($wgRequest, $wgEnableWriteAPI);
// Process data & print results
$processor->execute();
+// Execute any deferred updates
+wfDoUpdates();
+
// Log what the user did, for book-keeping purposes.
wfProfileOut('api.php');
wfLogProfilingData();
+// Shut down the database
+wfGetLBFactory()->shutdown();
+
diff --git a/bin/svnstat b/bin/svnstat
index b134cdc2..5a2c940b 100755
--- a/bin/svnstat
+++ b/bin/svnstat
@@ -1,2 +1,2 @@
#!/bin/sh
-svn stat -v $1 | sed -n 's/^[ A-Z?\*|!]\{1,15\}/r/;s/ \{1,15\}/\/r/;s/ .*//p'
+svn stat -v $1 | sed -n 's/^[ A-Z?\*|!]\{1,15\}[0-9]\{1,10\} \{1,15\}/r/;s/ .*//p'
diff --git a/config/index.php b/config/index.php
index 556819df..a0d7f4fb 100644
--- a/config/index.php
+++ b/config/index.php
@@ -67,11 +67,23 @@ $ourdb['postgres']['compile'] = 'pgsql';
$ourdb['postgres']['bgcolor'] = '#aaccff';
$ourdb['postgres']['rootuser'] = 'postgres';
+$ourdb['sqlite']['fullname'] = 'SQLite';
+$ourdb['sqlite']['havedriver'] = 0;
+$ourdb['sqlite']['compile'] = 'pdo_sqlite';
+$ourdb['sqlite']['bgcolor'] = '#b1ebb1';
+$ourdb['sqlite']['rootuser'] = '';
+
+$ourdb['mssql']['fullname'] = 'MSSQL';
+$ourdb['mssql']['havedriver'] = 0;
+$ourdb['mssql']['compile'] = 'mssql not ready'; # Change to 'mssql' after includes/DatabaseMssql.php added;
+$ourdb['mssql']['bgcolor'] = '#ffc0cb';
+$ourdb['mssql']['rootuser'] = 'administrator';
+
?>
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
-<html>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en" dir="ltr">
<head>
- <meta http-equiv="Content-type" content="text/html; charset=utf-8">
+ <meta http-equiv="Content-type" content="text/html; charset=utf-8" />
<title>MediaWiki <?php echo( $wgVersion ); ?> Installation</title>
<style type="text/css">
@@ -164,15 +176,15 @@ $ourdb['postgres']['rootuser'] = 'postgres';
<!--
function hideall() {
<?php foreach (array_keys($ourdb) as $db) {
- echo "\n document.getElementById('$db').style.display='none';";
+ echo "\n var i = document.getElementById('$db'); if (i) i.style.display='none';";
}
?>
}
function toggleDBarea(id,defaultroot) {
hideall();
- var dbarea = document.getElementById(id).style;
- dbarea.display = (dbarea.display == 'none') ? 'block' : 'none';
+ var dbarea = document.getElementById(id);
+ if (dbarea) dbarea.style.display = (dbarea.style.display == 'none') ? 'block' : 'none';
var db = document.getElementById('RootUser');
if (defaultroot) {
<?php foreach (array_keys($ourdb) as $db) {
@@ -193,19 +205,18 @@ $ourdb['postgres']['rootuser'] = 'postgres';
<h1>MediaWiki <?php print $wgVersion ?> Installation</h1>
<?php
+$mainListOpened = false; # Is the main list (environement checking) opend ? Used by dieout
/* Check for existing configurations and bug out! */
if( file_exists( "../LocalSettings.php" ) ) {
$script = defined('MW_INSTALL_PHP5_EXT') ? 'index.php5' : 'index.php';
- dieout( "<p><strong>Setup has completed, <a href='../$script'>your wiki</a> is configured.</strong></p>
-
- <p>Please delete the /config directory for extra security.</p></div></div></div></div>" );
+ dieout( "<p><strong>Setup has completed, <a href='../$script'>your wiki</a> is configured.</strong></p>
+ <p>Please delete the /config directory for extra security.</p>" );
}
if( file_exists( "./LocalSettings.php" ) ) {
writeSuccessMessage();
-
dieout( '' );
}
@@ -281,6 +292,8 @@ class ConfigData {
<p><em>Please include all of the lines below when reporting installation problems.</em></p>
<ul class="env-check">
<?php
+$mainListOpened = true;
+
$endl = "
";
define( 'MW_NO_OUTPUT_BUFFER', 1 );
@@ -310,7 +323,8 @@ if (!$phpdatabases) {
print "<li>For <b>$full</b>, compile PHP using <b>--with-$comp</b>, "
."or install the $comp.so module</li>\n";
}
- dieout( "</ul></ul>" );
+ echo '</ul>';
+ dieout( '' );
}
print "<li>Found database drivers for:";
@@ -343,7 +357,7 @@ if( wfIniGetBool( "magic_quotes_runtime" ) ) {
$fatal = true;
?><li class='error'><strong>Fatal: <a href='http://www.php.net/manual/en/ref.info.php#ini.magic-quotes-runtime'>magic_quotes_runtime</a> is active!</strong>
This option corrupts data input unpredictably; you cannot install or use
- MediaWiki unless this option is disabled.
+ MediaWiki unless this option is disabled.</li>
<?php
}
@@ -351,7 +365,7 @@ if( wfIniGetBool( "magic_quotes_sybase" ) ) {
$fatal = true;
?><li class='error'><strong>Fatal: <a href='http://www.php.net/manual/en/ref.sybase.php#ini.magic-quotes-sybase'>magic_quotes_sybase</a> is active!</strong>
This option corrupts data input unpredictably; you cannot install or use
- MediaWiki unless this option is disabled.
+ MediaWiki unless this option is disabled.</li>
<?php
}
@@ -359,7 +373,7 @@ if( wfIniGetBool( "mbstring.func_overload" ) ) {
$fatal = true;
?><li class='error'><strong>Fatal: <a href='http://www.php.net/manual/en/ref.mbstring.php#mbstring.overload'>mbstring.func_overload</a> is active!</strong>
This option causes errors and may corrupt data unpredictably;
- you cannot install or use MediaWiki unless this option is disabled.
+ you cannot install or use MediaWiki unless this option is disabled.</li>
<?php
}
@@ -367,13 +381,13 @@ if( wfIniGetBool( "zend.ze1_compatibility_mode" ) ) {
$fatal = true;
?><li class="error"><strong>Fatal: <a href="http://www.php.net/manual/en/ini.core.php">zend.ze1_compatibility_mode</a> is active!</strong>
This option causes horrible bugs with MediaWiki; you cannot install or use
- MediaWiki unless this option is disabled.
+ MediaWiki unless this option is disabled.</li>
<?php
}
if( $fatal ) {
- dieout( "</ul><p>Cannot install MediaWiki.</p>" );
+ dieout( "Cannot install MediaWiki." );
}
if( wfIniGetBool( "safe_mode" ) ) {
@@ -465,11 +479,11 @@ if ( $conf->turck ) {
$conf->xcache = function_exists( 'xcache_get' );
if( $conf->xcache )
- print "<li><a href=\"http://trac.lighttpd.net/xcache/\">XCache</a> installed</li>";
+ print "<li><a href=\"http://trac.lighttpd.net/xcache/\">XCache</a> installed</li>\n";
$conf->apc = function_exists('apc_fetch');
if ($conf->apc ) {
- print "<li><a href=\"http://www.php.net/apc\">APC</a> installed</li>";
+ print "<li><a href=\"http://www.php.net/apc\">APC</a> installed</li>\n";
}
$conf->eaccel = function_exists( 'eaccelerator_get' );
@@ -571,9 +585,7 @@ print "<li style='font-weight:bold;color:green;font-size:110%'>Environment check
: $_SERVER["SERVER_ADMIN"];
$conf->EmergencyContact = importPost( "EmergencyContact", $defaultEmail );
$conf->DBtype = importPost( "DBtype", $DefaultDBtype );
-?>
-<?php
$conf->DBserver = importPost( "DBserver", "localhost" );
$conf->DBname = importPost( "DBname", "wikidb" );
$conf->DBuser = importPost( "DBuser", "wikiuser" );
@@ -590,13 +602,21 @@ print "<li style='font-weight:bold;color:green;font-size:110%'>Environment check
## MySQL specific:
$conf->DBprefix = importPost( "DBprefix" );
$conf->setSchema(
- importPost( "DBschema", "mysql4" ),
+ importPost( "DBschema", "mysql5-binary" ),
importPost( "DBengine", "InnoDB" ) );
## Postgres specific:
$conf->DBport = importPost( "DBport", "5432" );
$conf->DBmwschema = importPost( "DBmwschema", "mediawiki" );
$conf->DBts2schema = importPost( "DBts2schema", "public" );
+
+ ## SQLite specific
+ $conf->SQLiteDataDir = importPost( "SQLiteDataDir", "" );
+
+ ## MSSQL specific
+ // We need a second field so it doesn't overwrite the MySQL one
+ $conf->DBprefix2 = importPost( "DBprefix2" );
+
/* Check for validity */
$errs = array();
@@ -716,13 +736,12 @@ if( $conf->posted && ( 0 == count( $errs ) ) ) {
chdir( ".." );
$ok = eval( $local );
if( $ok === false ) {
- dieout( "Errors in generated configuration; " .
+ dieout( "<p>Errors in generated configuration; " .
"most likely due to a bug in the installer... " .
- "Config file was: " .
+ "Config file was: </p>" .
"<pre>" .
htmlspecialchars( $local ) .
- "</pre>" .
- "</ul>" );
+ "</pre>" );
}
$conf->DBtypename = '';
foreach (array_keys($ourdb) as $db) {
@@ -752,6 +771,11 @@ if( $conf->posted && ( 0 == count( $errs ) ) ) {
$wgDBmwschema = $conf->DBmwschema;
$wgDBts2schema = $conf->DBts2schema;
+ if( $conf->DBprefix2 != '' ) {
+ // For MSSQL
+ $wgDBprefix = $conf->DBprefix2;
+ }
+
$wgCommandLineMode = true;
if (! defined ( 'STDERR' ) )
define( 'STDERR', fopen("php://stderr", "wb"));
@@ -761,7 +785,7 @@ if( $conf->posted && ( 0 == count( $errs ) ) ) {
$wgTitle = Title::newFromText( "Installation script" );
error_reporting( E_ALL );
- print "<li>Loading class: $dbclass";
+ print "<li>Loading class: $dbclass</li>\n";
$dbc = new $dbclass;
if( $conf->DBtype == 'mysql' ) {
@@ -828,11 +852,11 @@ if( $conf->posted && ( 0 == count( $errs ) ) ) {
if( !$ok ) { continue; }
- } else /* not mysql */ {
+ } else { # not mysql
error_reporting( E_ALL );
$wgSuperUser = '';
## Possible connect as a superuser
- if( $useRoot ) {
+ if( $useRoot && $conf->DBtype != 'sqlite' ) {
$wgDBsuperuser = $conf->RootUser;
echo( "<li>Attempting to connect to database \"postgres\" as superuser \"$wgDBsuperuser\"..." );
$wgDatabase = $dbc->newFromParams($wgDBserver, $wgDBsuperuser, $conf->RootPW, "postgres", 1);
@@ -852,8 +876,8 @@ if( $conf->posted && ( 0 == count( $errs ) ) ) {
} else {
$myver = $wgDatabase->getServerVersion();
}
- $wgDatabase->initial_setup('', $wgDBname);
- }
+ if (is_callable(array($wgDatabase, 'initial_setup'))) $wgDatabase->initial_setup('', $wgDBname);
+ }
if ( !$wgDatabase->isOpen() ) {
$errs["DBserver"] = "Couldn't connect to database";
@@ -863,7 +887,8 @@ if( $conf->posted && ( 0 == count( $errs ) ) ) {
print "<li>Connected to $myver";
if ($conf->DBtype == 'mysql') {
if( version_compare( $myver, "4.0.14" ) < 0 ) {
- dieout( " -- mysql 4.0.14 or later required. Aborting." );
+ print "</li>\n";
+ dieout( "-- mysql 4.0.14 or later required. Aborting." );
}
$mysqlNewAuth = version_compare( $myver, "4.1.0", "ge" );
if( $mysqlNewAuth && $mysqlOldClient ) {
@@ -911,7 +936,7 @@ if( $conf->posted && ( 0 == count( $errs ) ) ) {
}
else if ($conf->DBtype == 'postgres') {
if( version_compare( $myver, "PostgreSQL 8.0" ) < 0 ) {
- dieout( " <b>Postgres 8.0 or later is required</b>. Aborting.</li></ul>" );
+ dieout( "<b>Postgres 8.0 or later is required</b>. Aborting." );
}
}
@@ -1006,7 +1031,7 @@ if( $conf->posted && ( 0 == count( $errs ) ) ) {
if ($conf->DBtype == 'mysql') {
dbsource( "../maintenance/tables.sql", $wgDatabase );
dbsource( "../maintenance/interwiki.sql", $wgDatabase );
- } else if ($conf->DBtype == 'postgres') {
+ } elseif (is_callable(array($wgDatabase, 'setup_database'))) {
$wgDatabase->setup_database();
}
else {
@@ -1088,27 +1113,26 @@ if( $conf->posted && ( 0 == count( $errs ) ) ) {
$f = fopen( "LocalSettings.php", 'xt' );
if( $f == false ) {
+ print( "</li>\n" );
dieout( "<p>Couldn't write out LocalSettings.php. Check that the directory permissions are correct and that there isn't already a file of that name here...</p>\n" .
"<p>Here's the file that would have been written, try to paste it into place manually:</p>\n" .
"<pre>\n" . htmlspecialchars( $localSettings ) . "</pre>\n" );
}
if(fwrite( $f, $localSettings ) ) {
fclose( $f );
- print "</li></ul><hr/>\n";
+ print "<hr/>\n";
writeSuccessMessage();
+ print "</li>\n";
} else {
fclose( $f );
- die("<p class='error'>An error occured while writing the config/LocalSettings.php file. Check user rights and disk space then try again.</p>\n");
- print "</li></ul>\n";
+ dieout( "<p class='error'>An error occured while writing the config/LocalSettings.php file. Check user rights and disk space then try again.</p></li>\n" );
}
} while( false );
}
-?>
-</ul>
-
-<?php
+print "</ul>\n";
+$mainListOpened = false;
if( count( $errs ) ) {
/* Display options form */
@@ -1120,39 +1144,30 @@ if( count( $errs ) ) {
<form action="<?php echo defined('MW_INSTALL_PHP5_EXT') ? 'index.php5' : 'index.php'; ?>" name="config" method="post">
-
<h2>Site config</h2>
<div class="config-section">
<div class="config-input">
- <?php
- aField( $conf, "Sitename", "Wiki name:" );
- ?>
+ <?php aField( $conf, "Sitename", "Wiki name:" ); ?>
</div>
<p class="config-desc">
Preferably a short word without punctuation, i.e. "Wikipedia".<br />
Will appear as the namespace name for "meta" pages, and throughout the interface.
</p>
-
- <div class="config-input">
- <?php
- aField( $conf, "EmergencyContact", "Contact e-mail:" );
- ?>
- </div>
+ <div class="config-input"><?php aField( $conf, "EmergencyContact", "Contact e-mail:" ); ?></div>
<p class="config-desc">
Displayed to users in some error messages, used as the return address for password reminders, and used as the default sender address of e-mail notifications.
</p>
<div class="config-input">
<label class='column' for="LanguageCode">Language:</label>
- <select id="LanguageCode" name="LanguageCode">
-
- <?php
+ <select id="LanguageCode" name="LanguageCode"><?php
$list = getLanguageList();
foreach( $list as $code => $name ) {
$sel = ($code == $conf->LanguageCode) ? 'selected="selected"' : '';
- echo "\t\t<option value=\"$code\" $sel>$name</option>\n";
+ echo "\n\t\t<option value=\"$code\" $sel>$name</option>";
}
+ echo "\n";
?>
</select>
</div>
@@ -1174,15 +1189,14 @@ if( count( $errs ) ) {
$icon = urlencode( "$wgServer$wgUploadPath/wiki.png" );
$ccApp = htmlspecialchars( "http://creativecommons.org/license/?partner=$partner&exit_url=$exit&partner_icon_url=$icon" );
print "<a href=\"$ccApp\" target='_blank'>choose</a>";
- ?>
- <?php if( $conf->License == "cc" ) { ?>
+ if( $conf->License == "cc" ) { ?>
<ul>
- <li><?php aField( $conf, "RightsIcon", "<img src=\"" . htmlspecialchars( $conf->RightsIcon ) . "\" alt='(Creative Commons icon)' />", "hidden" ); ?></li>
- <li><?php aField( $conf, "RightsText", htmlspecialchars( $conf->RightsText ), "hidden" ); ?></li>
- <li><?php aField( $conf, "RightsCode", "code: " . htmlspecialchars( $conf->RightsCode ), "hidden" ); ?></li>
- <li><?php aField( $conf, "RightsUrl", "<a href=\"" . htmlspecialchars( $conf->RightsUrl ) . "\">" . htmlspecialchars( $conf->RightsUrl ) . "</a>", "hidden" ); ?></li>
+ <li><?php aField( $conf, "RightsIcon", "<img src=\"" . htmlspecialchars( $conf->RightsIcon ) . "\" alt='(Creative Commons icon)' />", "hidden" ); ?></li>
+ <li><?php aField( $conf, "RightsText", htmlspecialchars( $conf->RightsText ), "hidden" ); ?></li>
+ <li><?php aField( $conf, "RightsCode", "code: " . htmlspecialchars( $conf->RightsCode ), "hidden" ); ?></li>
+ <li><?php aField( $conf, "RightsUrl", "<a href=\"" . htmlspecialchars( $conf->RightsUrl ) . "\">" . htmlspecialchars( $conf->RightsUrl ) . "</a>", "hidden" ); ?></li>
</ul>
- <?php } ?>
+ <?php } ?>
</li>
</ul>
</div>
@@ -1216,22 +1230,22 @@ if( count( $errs ) ) {
if ( $conf->turck ) {
echo "<li>";
aField( $conf, "Shm", "Turck MMCache", "radio", "turck" );
- echo "</li>";
+ echo "</li>\n";
}
if( $conf->xcache ) {
- echo( '<li>' );
+ echo "<li>";
aField( $conf, 'Shm', 'XCache', 'radio', 'xcache' );
- echo( '</li>' );
+ echo "</li>\n";
}
if ( $conf->apc ) {
echo "<li>";
aField( $conf, "Shm", "APC", "radio", "apc" );
- echo "</li>";
+ echo "</li>\n";
}
if ( $conf->eaccel ) {
echo "<li>";
aField( $conf, "Shm", "eAccelerator", "radio", "eaccel" );
- echo "</li>";
+ echo "</li>\n";
}
if ( $conf->dba ) {
echo "<li>";
@@ -1306,7 +1320,7 @@ if( count( $errs ) ) {
</div>
<div class="config-desc">
<p>If this option is enabled, users have to confirm their e-mail address using a magic link sent to them whenever they set or change it, and only authenticated e-mail addresses can receive mails from other users and/or
- change notification mails. Setting this option is <B>recommended</B> for public wikis because of potential abuse of the e-mail features above.</p>
+ change notification mails. Setting this option is <b>recommended</b> for public wikis because of potential abuse of the e-mail features above.</p>
</div>
</div>
@@ -1315,30 +1329,24 @@ if( count( $errs ) ) {
<div class="config-section">
<div class="config-input">
- <label class='column'>Database type:</label>
-<?php if (isset($errs['DBpicktype'])) print "<span class='error'>$errs[DBpicktype]</span>\n"; ?>
- <ul class='plain'><?php database_picker($conf) ?></ul>
+ <label class='column'>Database type:</label>
+<?php if (isset($errs['DBpicktype'])) print "\t<span class='error'>$errs[DBpicktype]</span>\n"; ?>
+ <ul class='plain'><?php
+ database_picker($conf);
+ ?></ul>
</div>
- <div class="config-input" style="clear:left"><?php
- aField( $conf, "DBserver", "Database host:" );
- ?></div>
+ <div class="config-input" style="clear:left">
+ <?php aField( $conf, "DBserver", "Database host:" ); ?>
+ </div>
<p class="config-desc">
If your database server isn't on your web server, enter the name or IP address here.
</p>
- <div class="config-input"><?php
- aField( $conf, "DBname", "Database name:" );
- ?></div>
- <div class="config-input"><?php
- aField( $conf, "DBuser", "DB username:" );
- ?></div>
- <div class="config-input"><?php
- aField( $conf, "DBpassword", "DB password:", "password" );
- ?></div>
- <div class="config-input"><?php
- aField( $conf, "DBpassword2", "DB password confirm:", "password" );
- ?></div>
+ <div class="config-input"><?php aField( $conf, "DBname", "Database name:" ); ?></div>
+ <div class="config-input"><?php aField( $conf, "DBuser", "DB username:" ); ?></div>
+ <div class="config-input"><?php aField( $conf, "DBpassword", "DB password:", "password" ); ?></div>
+ <div class="config-input"><?php aField( $conf, "DBpassword2", "DB password confirm:", "password" ); ?></div>
<p class="config-desc">
If you only have a single user account and database available,
enter those here. If you have database root access (see below)
@@ -1349,19 +1357,11 @@ if( count( $errs ) ) {
<div class="config-input">
<label class="column">Superuser account:</label>
- <input type="checkbox" name="useroot" id="useroot" <?php if( $useRoot ) { ?>checked="checked" <?php } ?>/>
+ <input type="checkbox" name="useroot" id="useroot" <?php if( $useRoot ) { ?>checked="checked" <?php } ?> />
&nbsp;<label for="useroot">Use superuser account</label>
</div>
- <div class="config-input">
- <?php
- aField( $conf, "RootUser", "Superuser name:", "superuser" );
- ?>
- </div>
- <div class="config-input">
- <?php
- aField( $conf, "RootPW", "Superuser password:", "password" );
- ?>
- </div>
+ <div class="config-input"><?php aField( $conf, "RootUser", "Superuser name:", "text" ); ?></div>
+ <div class="config-input"><?php aField( $conf, "RootPW", "Superuser password:", "password" ); ?></div>
<p class="config-desc">
If the database user specified above does not exist, or does not have access to create
@@ -1370,9 +1370,7 @@ if( count( $errs ) ) {
</p>
<?php database_switcher('mysql'); ?>
- <div class="config-input"><?php
- aField( $conf, "DBprefix", "Database table prefix:" );
- ?></div>
+ <div class="config-input"><?php aField( $conf, "DBprefix", "Database table prefix:" ); ?></div>
<div class="config-desc">
<p>If you need to share one database between multiple wikis, or
between MediaWiki and another web application, you may choose to
@@ -1396,33 +1394,57 @@ if( count( $errs ) ) {
<div class="config-input"><label class="column">Database character set</label>
<div>Select one:</div>
<ul class="plain">
- <li><?php aField( $conf, "DBschema", "Backwards-compatible UTF-8", "radio", "mysql4" ); ?></li>
- <li><?php aField( $conf, "DBschema", "Experimental MySQL 4.1/5.0 UTF-8", "radio", "mysql5" ); ?></li>
- <li><?php aField( $conf, "DBschema", "Experimental MySQL 4.1/5.0 binary", "radio", "mysql5-binary" ); ?></li>
+ <li><?php aField( $conf, "DBschema", "MySQL 4.1/5.0 binary", "radio", "mysql5-binary" ); ?></li>
+ <li><?php aField( $conf, "DBschema", "MySQL 4.1/5.0 UTF-8", "radio", "mysql5" ); ?></li>
+ <li><?php aField( $conf, "DBschema", "MySQL 4.0 backwards-compatible UTF-8", "radio", "mysql4" ); ?></li>
</ul>
</div>
<p class="config-desc">
- <b>EXPERIMENTAL:</b> You can enable explicit Unicode charset support
- for MySQL 4.1 and 5.0 servers. This is not well tested and may
- cause things to break. <b>If upgrading an older installation, leave
- in backwards-compatible mode.</b>
+ This option is ignored on upgrade, the same character set will be kept.
+ <br/><br/>
+ <b>WARNING:</b> If you use <b>backwards-compatible UTF-8</b> on MySQL 4.1+, and subsequently back up the database with <tt>mysqldump</tt>, it may destroy all non-ASCII characters, irreversibly corrupting your backups!.
+ <br/><br/>
+ In <b>binary mode</b>, MediaWiki stores UTF-8 text to the database in binary fields. This is more efficient than MySQL's UTF-8 mode, and allows you to use the full range of Unicode characters. In <b>UTF-8 mode</b>, MySQL will know what character set your data is in, and can present and convert it appropriately, but it won't let you store characters above the <a target="_blank" href="http://en.wikipedia.org/wiki/Mapping_of_Unicode_character_planes">Basic Multilingual Plane</a>.
</p>
- </div>
+ </fieldset>
<?php database_switcher('postgres'); ?>
+ <div class="config-input"><?php aField( $conf, "DBport", "Database port:" ); ?></div>
+ <div class="config-input"><?php aField( $conf, "DBmwschema", "Schema for mediawiki:" ); ?></div>
+ <div class="config-input"><?php aField( $conf, "DBts2schema", "Schema for tsearch2:" ); ?></div>
+ <div class="config-desc">
+ <p>The username specified above (at "DB username") will have its search path set to the above schemas,
+ so it is recommended that you create a new user. The above schemas are generally correct:
+ only change them if you are sure you need to.</p>
+ </div>
+ </fieldset>
+
+ <?php database_switcher('sqlite'); ?>
+ <div class="config-desc">
+ <b>NOTE:</b> SQLite only uses the <i>Database name</i> setting above, the user, password and root settings are ignored.
+ </div>
<div class="config-input"><?php
- aField( $conf, "DBport", "Database port:" );
- ?></div>
- <div class="config-input"><?php
- aField( $conf, "DBmwschema", "Schema for mediawiki:" );
+ aField( $conf, "SQLiteDataDir", "SQLite data directory:" );
?></div>
+ <div class="config-desc">
+ <p>SQLite stores table data into files in the filesystem.
+ If you do not provide an explicit path, a "data" directory in
+ the parent of your document root will be used.</p>
+
+ <p>This directory must exist and be writable by the web server.</p>
+ </div>
+ </fieldset>
+
+ <?php database_switcher('mssql'); ?>
<div class="config-input"><?php
- aField( $conf, "DBts2schema", "Schema for tsearch2:" );
+ aField( $conf, "DBprefix2", "Database table prefix:" );
?></div>
<div class="config-desc">
- <p>The username specified above (at "DB username") will have its search path set to the above schemas,
- so it is recommended that you create a new user. The above schemas are generally correct:
- only change them if you are sure you need to.</p>
+ <p>If you need to share one database between multiple wikis, or
+ between MediaWiki and another web application, you may choose to
+ add a prefix to all the table names to avoid conflicts.</p>
+
+ <p>Avoid exotic characters; something like <tt>mw_</tt> is good.</p>
</div>
</fieldset>
@@ -1430,9 +1452,8 @@ if( count( $errs ) ) {
<label class='column'>&nbsp;</label>
<input type="submit" value="Install MediaWiki!" class="btn-install" />
</div>
-
</div>
-
+</form>
<script type="text/javascript">
window.onload = toggleDBarea('<?php echo $conf->DBtype; ?>',
<?php
@@ -1440,9 +1461,6 @@ window.onload = toggleDBarea('<?php echo $conf->DBtype; ?>',
echo strlen(importPost('RootUser', '')) ? 0 : 1;
?>);
</script>
-
-</form>
-
<?php
}
@@ -1568,6 +1586,36 @@ function writeLocalSettings( $conf ) {
$slconf['RightsIcon'] = $conf->RightsIcon;
}
+ if( $conf->DBtype == 'mysql' ) {
+ $dbsettings =
+"# MySQL specific settings
+\$wgDBprefix = \"{$slconf['DBprefix']}\";
+
+# MySQL table options to use during installation or update
+\$wgDBTableOptions = \"{$slconf['DBTableOptions']}\";
+
+# Experimental charset support for MySQL 4.1/5.0.
+\$wgDBmysql5 = {$conf->DBmysql5};";
+ } elseif( $conf->DBtype == 'postgres' ) {
+ $dbsettings =
+"# Postgres specific settings
+\$wgDBport = \"{$slconf['DBport']}\";
+\$wgDBmwschema = \"{$slconf['DBmwschema']}\";
+\$wgDBts2schema = \"{$slconf['DBts2schema']}\";";
+ } elseif( $conf->DBtype == 'sqlite' ) {
+ $dbsettings =
+"# SQLite-specific settings
+\$wgSQLiteDataDir = \"{$slconf['SQLiteDataDir']}\";";
+ } elseif( $conf->DBtype == 'mssql' ) {
+ $dbsettings =
+"# MSSQL specific settings
+\$wgDBprefix = \"{$slconf['DBprefix2']}\";";
+ } else {
+ // ummm... :D
+ $dbsettings = '';
+ }
+
+
$localsettings = "
# This file was automatically generated by the MediaWiki installer.
# If you make manual changes, please keep track in case you need to
@@ -1576,6 +1624,9 @@ function writeLocalSettings( $conf ) {
# See includes/DefaultSettings.php for all configurable settings
# and their default values, but don't forget to make changes in _this_
# file, not there.
+#
+# Further documentation for configuration settings may be found at:
+# http://www.mediawiki.org/wiki/Manual:Configuration_settings
# If you customize your file layout, set \$IP to the directory that contains
# the other MediaWiki files. It will be used as a base to locate files.
@@ -1605,47 +1656,31 @@ if ( \$wgCommandLineMode ) {
## The URL base path to the directory containing the wiki;
## defaults for all runtime URL paths are based off of this.
+## For more information on customizing the URLs please see:
+## http://www.mediawiki.org/wiki/Manual:Short_URL
\$wgScriptPath = \"{$slconf['ScriptPath']}\";
\$wgScriptExtension = \"{$slconf['ScriptExtension']}\";
-## For more information on customizing the URLs please see:
-## http://www.mediawiki.org/wiki/Manual:Short_URL
+## UPO means: this is also a user preference option
\$wgEnableEmail = $enableemail;
-\$wgEnableUserEmail = $enableuseremail;
+\$wgEnableUserEmail = $enableuseremail; # UPO
\$wgEmergencyContact = \"{$slconf['EmergencyContact']}\";
\$wgPasswordSender = \"{$slconf['PasswordSender']}\";
-## For a detailed description of the following switches see
-## http://www.mediawiki.org/wiki/Extension:Email_notification
-## and http://www.mediawiki.org/wiki/Extension:Email_notification
-## There are many more options for fine tuning available see
-## /includes/DefaultSettings.php
-## UPO means: this is also a user preference option
\$wgEnotifUserTalk = $enotifusertalk; # UPO
\$wgEnotifWatchlist = $enotifwatchlist; # UPO
\$wgEmailAuthentication = $eauthent;
+## Database settings
\$wgDBtype = \"{$slconf['DBtype']}\";
\$wgDBserver = \"{$slconf['DBserver']}\";
\$wgDBname = \"{$slconf['DBname']}\";
\$wgDBuser = \"{$slconf['DBuser']}\";
\$wgDBpassword = \"{$slconf['DBpassword']}\";
-# MySQL specific settings
-\$wgDBprefix = \"{$slconf['DBprefix']}\";
-
-# MySQL table options to use during installation or update
-\$wgDBTableOptions = \"{$slconf['DBTableOptions']}\";
-
-# Experimental charset support for MySQL 4.1/5.0.
-\$wgDBmysql5 = {$conf->DBmysql5};
-
-# Postgres specific settings
-\$wgDBport = \"{$slconf['DBport']}\";
-\$wgDBmwschema = \"{$slconf['DBmwschema']}\";
-\$wgDBts2schema = \"{$slconf['DBts2schema']}\";
+{$dbsettings}
## Shared memory settings
\$wgMainCacheType = $cacheType;
@@ -1700,7 +1735,14 @@ if ( \$wgCommandLineMode ) {
}
function dieout( $text ) {
- die( $text . "\n\n</body>\n</html>" );
+ global $mainListOpened;
+ if( $mainListOpened ) echo( "</ul>" );
+ if( $text != '' && substr( $text, 0, 2 ) != '<p' && substr( $text, 0, 2 ) != '<h' ){
+ echo "<p>$text</p>\n";
+ } else {
+ echo $text;
+ }
+ die( "\n\n</div>\n</div>\n</div>\n</div>\n</body>\n</html>" );
}
function importVar( &$var, $name, $default = "" ) {
@@ -1743,10 +1785,8 @@ function aField( &$conf, $field, $text, $type = "text", $value = "", $onclick =
if ($type == 'radio')
$id .= $radioCount++;
- if( $nolabel ) {
- echo "\t\t<label>";
- } else {
- echo "\t\t<label class='column' for=\"$id\">$text</label>\n";
+ if( !$nolabel ) {
+ echo "<label class='column' for=\"$id\">$text</label>";
}
if( $type == "radio" && $value == $conf->$field ) {
@@ -1754,7 +1794,7 @@ function aField( &$conf, $field, $text, $type = "text", $value = "", $onclick =
} else {
$checked = "";
}
- echo "\t\t<input $xtype name=\"$field\" id=\"$id\" class=\"iput-$type\" $checked ";
+ echo "<input $xtype name=\"$field\" id=\"$id\" class=\"iput-$type\" $checked ";
if ($onclick) {
echo " onclick='toggleDBarea(\"$value\",1)' " ;
}
@@ -1766,9 +1806,9 @@ function aField( &$conf, $field, $text, $type = "text", $value = "", $onclick =
}
- echo "\" />\n";
+ echo "\" />";
if( $nolabel ) {
- echo " $text</label>\n";
+ echo "<label for=\"$id\">$text</label>";
}
global $errs;
@@ -1875,12 +1915,12 @@ function database_picker($conf) {
print "\n";
foreach(array_keys($ourdb) as $db) {
if ($ourdb[$db]['havedriver']) {
- print "<li>";
+ print "\t<li>";
aField( $conf, "DBtype", $ourdb[$db]['fullname'], 'radio', $db, 'onclick');
print "</li>\n";
}
}
- print "\n";
+ print "\n\t";
}
function database_switcher($db) {
@@ -1897,7 +1937,7 @@ function printListItem( $item ) {
?>
<div class="license">
- <hr>
+ <hr/>
<p>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
@@ -1930,10 +1970,13 @@ function printListItem( $item ) {
<li><a href="../README">Readme</a></li>
<li><a href="../RELEASE-NOTES">Release notes</a></li>
<li><a href="../docs/">Documentation</a></li>
- <li><a href="http://meta.wikipedia.org/wiki/MediaWiki_User's_Guide">User's Guide</a></li>
- <li><a href="http://meta.wikimedia.org/wiki/MediaWiki_FAQ">FAQ</a></li>
+ <li><a href="http://www.mediawiki.org/wiki/Help:Contents">User's Guide</a></li>
+ <li><a href="http://www.mediawiki.org/wiki/Manual:Contents">Administrator's Guide</a></li>
+ <li><a href="http://www.mediawiki.org/wiki/Manual:FAQ">FAQ</a></li>
</ul>
- <p style="font-size:90%;margin-top:1em">MediaWiki is Copyright &copy; 2001-2008 by Magnus Manske, Brion Vibber, Lee Daniel Crocker, Tim Starling, Erik M&ouml;ller, Gabriel Wicke and others.</p>
+ <p style="font-size:90%;margin-top:1em">MediaWiki is Copyright © 2001-2008 by Magnus Manske, Brion Vibber,
+ Lee Daniel Crocker, Tim Starling, Erik Möller, Gabriel Wicke, Ævar Arnfjörð Bjarmason, Niklas Laxström,
+ Domas Mituzas, Rob Church, Yuri Astrakhan, Aryeh Gregor, Aaron Schulz and others.</p>
</div></div>
</div>
diff --git a/docs/README b/docs/README
index 1ec3986b..69170767 100644
--- a/docs/README
+++ b/docs/README
@@ -1,17 +1,16 @@
-[May 31st 2007]
+[July 22nd 2008]
-The 'docs' directory contain various text files that should help you
-understand the most importants classes in MediaWiki.
+The 'docs' directory contain various text files that should help you understand
+the most important parts of the code of MediaWiki. More in-depth documentation
+can be found at http://www.mediawiki.org/wiki/Manual:Code.
API documentation is automatically generated and updated daily at:
http://svn.wikimedia.org/doc/
-You can get a fresh version using 'make doc' or mwdocgen.php
-in the ../maintenance/ directory.
+You can get a fresh version using 'make doc' or mwdocgen.php in the
+../maintenance/ directory.
-
-For end user / administrators, most of the documentation
-is located online at:
- http://www.mediawiki.org/wiki/Project:Help
-
+For end user / administrators, most of the documentation is located online at:
+ http://www.mediawiki.org/wiki/Help:Contents
+ http://www.mediawiki.org/wiki/Manual:Contents
diff --git a/docs/database.txt b/docs/database.txt
index 80044734..60e268c5 100644
--- a/docs/database.txt
+++ b/docs/database.txt
@@ -158,12 +158,9 @@ enclose small groups of queries in their own transaction. Use the
following syntax:
$dbw = wfGetDB( DB_MASTER );
-$dbw->immediateBegin();
+$dbw->begin();
/* Do queries */
-$dbw->immediateCommit();
-
-There are functions called begin() and commit() but they don't do what
-you would expect. Don't use them.
+$dbw->commit();
Use of locking reads (e.g. the FOR UPDATE clause) is not advised. They
are poorly implemented in InnoDB and will cause regular deadlock errors.
diff --git a/docs/deferred.txt b/docs/deferred.txt
index 06155c56..495e6594 100644
--- a/docs/deferred.txt
+++ b/docs/deferred.txt
@@ -1,27 +1,36 @@
-
deferred.txt
-A few of the database updates required by various functions here
-can be deferred until after the result page is displayed to the
-user. For example, updating the view counts, updating the
-linked-to tables after a save, etc. PHP does not yet have any
-way to tell the server to actually return and disconnect while
-still running these updates (as a Java servelet could), but it
-might have such a feature in the future.
-
-We handle these by creating a deferred-update object (in a real
-O-O language these would be classes that implement an interface)
-and putting those objects on a global list, then executing the
-whole list after the page is displayed. We don't do anything
-smart like collating updates to the same table or such because
-the list is almost always going to have just one item on it, if
-that, so it's not worth the trouble.
-
-
-Since 1.6 there is a 'job queue' in the jobs table, which is used
-to update link tables of transcluding pages after edits; this
-may be extended in the future to more general background tasks.
-
-Job queue items are fetched out of the queue and run either
-at a random rate during regular page views (by default) or by
-a batch process which can be run via maintenance/runJobs.php.
+A few of the database updates required by various functions here can be
+deferred until after the result page is displayed to the user. For example,
+updating the view counts, updating the linked-to tables after a save, etc. PHP
+does not yet have any way to tell the server to actually return and disconnect
+while still running these updates (as a Java servelet could), but it might have
+such a feature in the future.
+
+We handle these by creating a deferred-update object and putting those objects
+on a global list, then executing the whole list after the page is displayed. We
+don't do anything smart like collating updates to the same table or such
+because the list is almost always going to have just one item on it, if that,
+so it's not worth the trouble.
+
+Since 1.6 there is a 'job queue' in the jobs table, which is used to update
+link tables of transcluding pages after edits; this may be extended in the
+future to more general background tasks.
+
+Job queue items are fetched out of the queue and run either at a random rate
+during regular page views (by default) or by a batch process which can be run
+via maintenance/runJobs.php.
+
+Currently there are a few different types of jobs:
+
+ refreshLinks
+ Used to refresh the database tables that store the links between pages.
+ When a page is changed, all pages using that page are also cleared by
+ inserting a new job for all those pages. Each job refreshes only one page.
+
+ htmlCacheUpdate
+ Clear caches when a template is changed to ensure that changes can be seen.
+ Each job clears $wgUpdateRowsPerJob pages (500 by default).
+
+ enotifNotify
+ Used when $wgEnotifUseJobQ is true to send mail using the job queue.
diff --git a/docs/design.txt b/docs/design.txt
index 1a35d5b0..d1904e1e 100644
--- a/docs/design.txt
+++ b/docs/design.txt
@@ -1,128 +1,110 @@
+design.txt
+
This is a brief overview of the new design.
More thorough and up-to-date information is available on the documentation
wiki at http://www.mediawiki.org/
-Primary source files/objects:
-
- index.php
- Main script. It creates the necessary global objects and parses
- the URL to determine what to do, which it then generally passes
- off to somebody else (depending on the action to be taken).
-
- All of the functions to which it might delegate generally do
- their job by sending content to the $wgOut object. After returning,
- the script flushes that out by calling $wgOut->output(). If there
- are any changes that need to be made to the database that can be
- deferred until after page display, those happen at the end.
-
- Note that the order in the includes is touchy; Language uses
- some global functions, etc. Likewise with the creation of the
- global variables. Don't move them around without some forethought.
+Primary classes:
User
- Encapsulates the state of the user viewing/using the site.
- Can be queried for things like the user's settings, name, etc.
- Handles the details of getting and saving to the "user" table
- of the database, and dealing with sessions and cookies.
- More details in USER.TXT.
+ Encapsulates the state of the user viewing/using the site. Can be queried
+ for things like the user's settings, name, etc. Handles the details of
+ getting and saving to the "user" table of the database, and dealing with
+ sessions and cookies.
OutputPage
- Encapsulates the entire HTML page that will be sent in
- response to any server request. It is used by calling its
- functions to add text, headers, etc., in any order, and then
- calling output() to send it all. It could be easily changed
- to send incrementally if that becomes useful, but I prefer
- the flexibility. This should also do the output encoding.
- The system allocates a global one in $wgOut.
+ Encapsulates the entire HTML page that will be sent in response to any
+ server request. It is used by calling its functions to add text, headers,
+ etc., in any order, and then calling output() to send it all. It could be
+ easily changed to send incrementally if that becomes useful, but I prefer
+ the flexibility. This should also do the output encoding. The system
+ allocates a global one in $wgOut.
Title
- Represents the title of an article, and does all the work
- of translating among various forms such as plain text, URL,
- database key, etc. For convenience, and for historical
- reasons, it also represents a few features of articles that
- don't involve their text, such as access rights.
+ Represents the title of an article, and does all the work of translating
+ among various forms such as plain text, URL, database key, etc. For
+ convenience, and for historical reasons, it also represents a few features
+ of articles that don't involve their text, such as access rights.
+ See also title.txt.
Article
- Encapsulates access to the "page" table of the database. The
- object represents a an article, and maintains state such as
- text (in Wikitext format), flags, etc.
+ Encapsulates access to the "page" table of the database. The object
+ represents a an article, and maintains state such as text (in Wikitext
+ format), flags, etc.
Revision
Encapsulates individual page revision data and access to the
- revision/text/blobs storage system. Higher-level code should
- never touch text storage directly; this class mediates it.
+ revision/text/blobs storage system. Higher-level code should never touch
+ text storage directly; this class mediates it.
Skin
- Encapsulates a "look and feel" for the wiki. All of the
- functions that render HTML, and make choices about how to
- render it, are here, and are called from various other
- places when needed (most notably, OutputPage::addWikiText()).
- The StandardSkin object is a complete implementation, and is
- meant to be subclassed with other skins that may override
- some of its functions. The User object contains a reference
- to a skin (according to that user's preference), and so
- rather than having a global skin object we just rely on the
- global User and get the skin with $wgUser->getSkin().
+ Encapsulates a "look and feel" for the wiki. All of the functions that
+ render HTML, and make choices about how to render it, are here, and are
+ called from various other places when needed (most notably,
+ OutputPage::addWikiText()). The StandardSkin object is a complete
+ implementation, and is meant to be subclassed with other skins that may
+ override some of its functions. The User object contains a reference to a
+ skin (according to that user's preference), and so rather than having a
+ global skin object we just rely on the global User and get the skin with
+ $wgUser->getSkin().
+ See also skin.txt.
Language
- Represents the language used for incidental text, and also
- has some character encoding functions and other locale stuff.
- The current user interface language is instantiated as $wgLang,
- and the local content language as $wgContLang; be sure to use
- the *correct* language object depending upon the circumstances.
+ Represents the language used for incidental text, and also has some
+ character encoding functions and other locale stuff. The current user
+ interface language is instantiated as $wgLang, and the local content
+ language as $wgContLang; be sure to use the *correct* language object
+ depending upon the circumstances.
+ See also language.txt.
+
+ Parser
+ Class used to transform wikitext to html.
LinkCache
- Keeps information on existence of articles. See LINKCACHE.TXT.
+ Keeps information on existence of articles. See linkcache.txt.
Naming/coding conventions:
- These are meant to be descriptive, not dictatorial; I won't
- presume to tell you how to program, I'm just describing the
- methods I chose to use for myself. If you do choose to
- follow these guidelines, it will probably be easier for you
- to collaborate with others on the project, but if you want
- to contribute without bothering, by all means do so (and don't
- be surprised if I reformat your code).
-
- - I have the code indented with tabs to save file size and
- so that users can set their tab stops to any depth they like.
- I use 4-space tab stops, which work well. I also use K&R brace
- matching style. I know that's a religious issue for some,
- so if you want to use a style that puts opening braces on the
- next line, that's OK too, but please don't use a style where
- closing braces don't align with either the opening brace on
- its own line or the statement that opened the block--that's
- confusing as hell.
-
- - Certain functions and class members are marked with
- /* private */, rather than being marked as such. This is a
- hold-over from PHP 4, which didn't support proper visibilities.
- You should not access things marked in this manner outside the
- class/inheritance line as this code is subjected to be updated
- in a manner that enforces this at some time in the near future,
- and things will break. New code should use the standard method of
- setting visibilities as normal.
-
- - Member variables are generally "mXxx" to distinguish them.
- This should make it easier to spot errors of forgetting the
- required "$this->", which PHP will happily accept by creating
- a new local variable rather than complaining.
-
- - Globals are particularly evil in PHP; it sets a lot of them
- automatically from cookies, query strings, and such, leading to
- namespace conflicts; when a variable name is used in a function,
- it is silently declared as a new local masking the global, so
- you'll get weird error because you forgot the global declaration;
- lack of static class member variables means you have to use
- globals for them, etc. Evil, evil.
-
- I think I've managed to pare down the number of globals we use
- to a scant few dozen or so, and I've prefixed them all with "wg"
- so you can spot errors better (odds are, if you see a "wg"
- variable being used in a function that doesn't declare it global,
- that's probably an error).
-
- Other conventions: Top-level functions are wfFuncname(), names
- of session variables are wsName, cookies wcName, and form field
- values wpName ("p" for "POST"). \ No newline at end of file
+ These are meant to be descriptive, not dictatorial; I won't presume to tell
+ you how to program, I'm just describing the methods I chose to use for myself.
+ If you do choose to follow these guidelines, it will probably be easier for
+ you to collaborate with others on the project, but if you want to contribute
+ without bothering, by all means do so (and don't be surprised if I reformat
+ your code).
+
+ - I have the code indented with tabs to save file size and so that users can
+ set their tab stops to any depth they like. I use 4-space tab stops, which
+ work well. I also use K&R brace matching style. I know that's a religious
+ issue for some, so if you want to use a style that puts opening braces on
+ the next line, that's OK too, but please don't use a style where closing
+ braces don't align with either the opening brace on its own line or the
+ statement that opened the block--that's confusing as hell.
+
+ - Certain functions and class members are marked with /* private */, rather
+ than being marked as such. This is a hold-over from PHP 4, which didn't
+ support proper visibilities. You should not access things marked in this
+ manner outside the class/inheritance line as this code is subjected to be
+ updated in a manner that enforces this at some time in the near future, and
+ things will break. New code should use the standard method of setting
+ visibilities as normal.
+
+ - Member variables are generally "mXxx" to distinguish them. This should make
+ it easier to spot errors of forgetting the required "$this->", which PHP
+ will happily accept by creating a new local variable rather than complaining.
+
+ - Globals are particularly evil in PHP; it sets a lot of them automatically
+ from cookies, query strings, and such, leading to namespace conflicts; when
+ a variable name is used in a function, it is silently declared as a new
+ local masking the global, so you'll get weird error because you forgot the
+ global declaration; lack of static class member variables means you have to
+ use globals for them, etc. Evil, evil.
+
+ I think I've managed to pare down the number of globals we use to a scant
+ few dozen or so, and I've prefixed them all with "wg" so you can spot errors
+ better (odds are, if you see a "wg" variable being used in a function that
+ doesn't declare it global, that's probably an error).
+
+ Other conventions: Top-level functions are wfFuncname(), names of session
+ variables are wsName, cookies wcName, and form field values wpName ("p" for
+ "POST").
diff --git a/docs/globals.txt b/docs/globals.txt
index 8320eec0..46486dd8 100644
--- a/docs/globals.txt
+++ b/docs/globals.txt
@@ -1,12 +1,10 @@
globals.txt
-Globals are evil. The original MediaWiki code relied on
-globals for processing context far too often. MediaWiki
-development since then has been a story of slowly moving
-context out of global variables and into objects. Storing
-processing context in object member variables allows those
-objects to be reused in a much more flexible way. Consider
-the elegance of:
+Globals are evil. The original MediaWiki code relied on globals for processing
+context far too often. MediaWiki development since then has been a story of
+slowly moving context out of global variables and into objects. Storing
+processing context in object member variables allows those objects to be reused
+in a much more flexible way. Consider the elegance of:
# Generate the article HTML as if viewed by a web request
$article = new Article( Title::newFromText( $t ) );
@@ -27,51 +25,43 @@ versus
$wgTitle = $oldTitle
$wgArticle = $oldArticle
-Some of the current MediaWiki developers have an idle
-fantasy that some day, globals will be eliminated from
-MediaWiki entirely, replaced by an application object which
-would be passed to constructors. Whether that would be an
-efficient, convenient solution remains to be seen, but
-certainly PHP 5 makes such object-oriented programming
-models easier than they were in previous versions.
-
-For the time being though, MediaWiki programmers will have
-to work in an environment with some global context. At the
-time of writing, 418 globals were initialised on startup by
-MediaWiki. 304 of these were configuration settings, which
-are documented in DefaultSettings.php. There is no
-comprehensive documentation for the remaining 114 globals,
-however some of the most important ones are listed below.
-They are typically initialised either in index.php or in
+Some of the current MediaWiki developers have an idle fantasy that some day,
+globals will be eliminated from MediaWiki entirely, replaced by an application
+object which would be passed to constructors. Whether that would be an
+efficient, convenient solution remains to be seen, but certainly PHP 5 makes
+such object-oriented programming models easier than they were in previous
+versions.
+
+For the time being though, MediaWiki programmers will have to work in an
+environment with some global context. At the time of writing, 418 globals were
+initialised on startup by MediaWiki. 304 of these were configuration settings,
+which are documented in DefaultSettings.php. There is no comprehensive
+documentation for the remaining 114 globals, however some of the most important
+ones are listed below. They are typically initialised either in index.php or in
Setup.php.
+For a description of the classes, see design.txt.
+
+$wgTitle
+ Title object created from the request URL.
+
+$wgArticle
+ Article object corresponding to $wgTitle.
$wgOut
OutputPage object for HTTP response.
$wgUser
- User object for the user associated with the current
- request.
-
-$wgTitle
- Title object created from the request URL.
+ User object for the user associated with the current request.
$wgLang
- Language object selected by user preferences
+ Language object selected by user preferences.
$wgContLang
- Language object associated with the wiki being
- viewed.
-
-$wgArticle
- Article object corresponding to $wgTitle.
+ Language object associated with the wiki being viewed.
$wgParser
- Parser object. Parser extensions register their
- hooks here.
-
-$wgLoadBalancer
- A LoadBalancer object, manages database connections.
+ Parser object. Parser extensions register their hooks here.
$wgRequest
WebRequest object, to get request data
@@ -81,4 +71,3 @@ $wgMemc, $messageMemc, $parserMemc
$wgMessageCache
Message cache, to manage interface messages
-
diff --git a/docs/hooks.txt b/docs/hooks.txt
index 9e27a8d0..286ed7e2 100644
--- a/docs/hooks.txt
+++ b/docs/hooks.txt
@@ -1,39 +1,38 @@
hooks.txt
-This document describes how event hooks work in MediaWiki; how to add
-hooks for an event; and how to run hooks for an event.
+This document describes how event hooks work in MediaWiki; how to add hooks for
+an event; and how to run hooks for an event.
==Glossary==
event
- Something that happens with the wiki. For example: a user logs
- in. A wiki page is saved. A wiki page is deleted. Often there are
- two events associated with a single action: one before the code
- is run to make the event happen, and one after. Each event has a
- name, preferably in CamelCase. For example, 'UserLogin',
- 'ArticleSave', 'ArticleSaveComplete', 'ArticleDelete'.
+ Something that happens with the wiki. For example: a user logs in. A wiki
+ page is saved. A wiki page is deleted. Often there are two events
+ associated with a single action: one before the code is run to make the
+ event happen, and one after. Each event has a name, preferably in
+ CamelCase. For example, 'UserLogin', 'ArticleSave', 'ArticleSaveComplete',
+ 'ArticleDelete'.
hook
- A clump of code and data that should be run when an event
- happens. This can be either a function and a chunk of data, or an
- object and a method.
+ A clump of code and data that should be run when an event happens. This can
+ be either a function and a chunk of data, or an object and a method.
hook function
The function part of a hook.
==Rationale==
-Hooks allow us to decouple optionally-run code from code that is run
-for everyone. It allows MediaWiki hackers, third-party developers and
-local administrators to define code that will be run at certain points
-in the mainline code, and to modify the data run by that mainline
-code. Hooks can keep mainline code simple, and make it easier to
-write extensions. Hooks are a principled alternative to local patches.
+Hooks allow us to decouple optionally-run code from code that is run for
+everyone. It allows MediaWiki hackers, third-party developers and local
+administrators to define code that will be run at certain points in the mainline
+code, and to modify the data run by that mainline code. Hooks can keep mainline
+code simple, and make it easier to write extensions. Hooks are a principled
+alternative to local patches.
-Consider, for example, two options in MediaWiki. One reverses the
-order of a title before displaying the article; the other converts the
-title to all uppercase letters. Currently, in MediaWiki code, we
-would handle this as follows (note: not real code, here):
+Consider, for example, two options in MediaWiki. One reverses the order of a
+title before displaying the article; the other converts the title to all
+uppercase letters. Currently, in MediaWiki code, we would handle this as follows
+(note: not real code, here):
function showAnArticle($article) {
global $wgReverseTitle, $wgCapitalizeTitle;
@@ -49,31 +48,30 @@ would handle this as follows (note: not real code, here):
# code to actually show the article goes here
}
-An extension writer, or a local admin, will often add custom code to
-the function -- with or without a global variable. For example,
-someone wanting email notification when an article is shown may add:
+An extension writer, or a local admin, will often add custom code to the
+function -- with or without a global variable. For example, someone wanting
+email notification when an article is shown may add:
function showAnArticle($article) {
- global $wgReverseTitle, $wgCapitalizeTitle;
+ global $wgReverseTitle, $wgCapitalizeTitle, $wgNotifyArticle;
- if ($wgReverseTitle) {
- wfReverseTitle($article);
- }
+ if ($wgReverseTitle) {
+ wfReverseTitle($article);
+ }
- if ($wgCapitalizeTitle) {
- wfCapitalizeTitle($article);
- }
+ if ($wgCapitalizeTitle) {
+ wfCapitalizeTitle($article);
+ }
- # code to actually show the article goes here
+ # code to actually show the article goes here
- if ($wgNotifyArticle) {
- wfNotifyArticleShow($article));
- }
+ if ($wgNotifyArticle) {
+ wfNotifyArticleShow($article));
+ }
}
-Using a hook-running strategy, we can avoid having all this
-option-specific stuff in our mainline code. Using hooks, the function
-becomes:
+Using a hook-running strategy, we can avoid having all this option-specific
+stuff in our mainline code. Using hooks, the function becomes:
function showAnArticle($article) {
@@ -85,16 +83,15 @@ becomes:
}
}
-We've cleaned up the code here by removing clumps of weird,
-infrequently used code and moving them off somewhere else. It's much
-easier for someone working with this code to see what's _really_ going
-on, and make changes or fix bugs.
+We've cleaned up the code here by removing clumps of weird, infrequently used
+code and moving them off somewhere else. It's much easier for someone working
+with this code to see what's _really_ going on, and make changes or fix bugs.
-In addition, we can take all the code that deals with the little-used
-title-reversing options (say) and put it in one place. Instead of
-having little title-reversing if-blocks spread all over the codebase
-in showAnArticle, deleteAnArticle, exportArticle, etc., we can
-concentrate it all in an extension file:
+In addition, we can take all the code that deals with the little-used
+title-reversing options (say) and put it in one place. Instead of having little
+title-reversing if-blocks spread all over the codebase in showAnArticle,
+deleteAnArticle, exportArticle, etc., we can concentrate it all in an extension
+file:
function reverseArticleTitle($article) {
# ...
@@ -104,8 +101,8 @@ concentrate it all in an extension file:
# ...
}
-The setup function for the extension just has to add its hook
-functions to the appropriate events:
+The setup function for the extension just has to add its hook functions to the
+appropriate events:
setupTitleReversingExtension() {
global $wgHooks;
@@ -115,23 +112,21 @@ functions to the appropriate events:
$wgHooks['ArticleExport'][] = 'reverseForExport';
}
-Having all this code related to the title-reversion option in one
-place means that it's easier to read and understand; you don't have to
-do a grep-find to see where the $wgReverseTitle variable is used, say.
+Having all this code related to the title-reversion option in one place means
+that it's easier to read and understand; you don't have to do a grep-find to see
+where the $wgReverseTitle variable is used, say.
-If the code is well enough isolated, it can even be excluded when not
-used -- making for some slight savings in memory and load-up
-performance at runtime. Admins who want to have all the reversed
-titles can add:
+If the code is well enough isolated, it can even be excluded when not used --
+making for some slight savings in memory and load-up performance at runtime.
+Admins who want to have all the reversed titles can add:
require_once('extensions/ReverseTitle.php');
-...to their LocalSettings.php file; those of us who don't want or need
-it can just leave it out.
+...to their LocalSettings.php file; those of us who don't want or need it can
+just leave it out.
-The extensions don't even have to be shipped with MediaWiki; they
-could be provided by a third-party developer or written by the admin
-him/herself.
+The extensions don't even have to be shipped with MediaWiki; they could be
+provided by a third-party developer or written by the admin him/herself.
==Writing hooks==
@@ -140,8 +135,8 @@ A hook is a chunk of code run at some particular event. It consists of:
* a function with some optional accompanying data, or
* an object with a method and some optional accompanying data.
-Hooks are registered by adding them to the global $wgHooks array for a
-given event. All the following are valid ways to define hooks:
+Hooks are registered by adding them to the global $wgHooks array for a given
+event. All the following are valid ways to define hooks:
$wgHooks['EventName'][] = 'someFunction'; # function, no data
$wgHooks['EventName'][] = array('someFunction', $someData);
@@ -152,10 +147,9 @@ given event. All the following are valid ways to define hooks:
$wgHooks['EventName'][] = array($object, 'someMethod', $someData);
$wgHooks['EventName'][] = array($object); # weird but OK
-When an event occurs, the function (or object method) will be called
-with the optional data provided as well as event-specific parameters.
-The above examples would result in the following code being executed
-when 'EventName' happened:
+When an event occurs, the function (or object method) will be called with the
+optional data provided as well as event-specific parameters. The above examples
+would result in the following code being executed when 'EventName' happened:
# function, no data
someFunction($param1, $param2)
@@ -169,31 +163,30 @@ when 'EventName' happened:
# object with method and data
$object->someMethod($someData, $param1, $param2)
-Note that when an object is the hook, and there's no specified method,
-the default method called is 'onEventName'. For different events this
-would be different: 'onArticleSave', 'onUserLogin', etc.
+Note that when an object is the hook, and there's no specified method, the
+default method called is 'onEventName'. For different events this would be
+different: 'onArticleSave', 'onUserLogin', etc.
-The extra data is useful if we want to use the same function or object
-for different purposes. For example:
+The extra data is useful if we want to use the same function or object for
+different purposes. For example:
$wgHooks['ArticleSaveComplete'][] = array('ircNotify', 'TimStarling');
$wgHooks['ArticleSaveComplete'][] = array('ircNotify', 'brion');
-This code would result in ircNotify being run twice when an article is
-saved: once for 'TimStarling', and once for 'brion'.
+This code would result in ircNotify being run twice when an article is saved:
+once for 'TimStarling', and once for 'brion'.
Hooks can return three possible values:
* true: the hook has operated successfully
- * "some string": an error occurred; processing should
- stop and the error should be shown to the user
- * false: the hook has successfully done the work
- necessary and the calling function should skip
+ * "some string": an error occurred; processing should stop and the error
+ should be shown to the user
+ * false: the hook has successfully done the work necessary and the calling
+ function should skip
-The last result would be for cases where the hook function replaces
-the main functionality. For example, if you wanted to authenticate
-users to a custom system (LDAP, another PHP program, whatever), you
-could do:
+The last result would be for cases where the hook function replaces the main
+functionality. For example, if you wanted to authenticate users to a custom
+system (LDAP, another PHP program, whatever), you could do:
$wgHooks['UserLogin'][] = array('ldapLogin', $ldapServer);
@@ -202,13 +195,13 @@ could do:
return false;
}
-Returning false makes less sense for events where the action is
-complete, and will normally be ignored.
+Returning false makes less sense for events where the action is complete, and
+will normally be ignored.
==Using hooks==
-A calling function or method uses the wfRunHooks() function to run
-the hooks related to a particular event, like so:
+A calling function or method uses the wfRunHooks() function to run the hooks
+related to a particular event, like so:
class Article {
# ...
@@ -221,22 +214,25 @@ the hooks related to a particular event, like so:
}
}
-wfRunHooks() returns true if the calling function should continue
-processing (the hooks ran OK, or there are no hooks to run), or false
-if it shouldn't (an error occurred, or one of the hooks handled the
-action already). Checking the return value matters more for "before"
-hooks than for "complete" hooks.
+wfRunHooks() returns true if the calling function should continue processing
+(the hooks ran OK, or there are no hooks to run), or false if it shouldn't (an
+error occurred, or one of the hooks handled the action already). Checking the
+return value matters more for "before" hooks than for "complete" hooks.
Note that hook parameters are passed in an array; this is a necessary
-inconvenience to make it possible to pass reference values (that can
-be changed) into the hook code. Also note that earlier versions of
-wfRunHooks took a variable number of arguments; the array() calling
-protocol came about after MediaWiki 1.4rc1.
+inconvenience to make it possible to pass reference values (that can be changed)
+into the hook code. Also note that earlier versions of wfRunHooks took a
+variable number of arguments; the array() calling protocol came about after
+MediaWiki 1.4rc1.
==Events and parameters==
-This is a list of known events and parameters; please add to it if
-you're going to add events to the MediaWiki code.
+This is a list of known events and parameters; please add to it if you're going
+to add events to the MediaWiki code.
+
+'AbortAutoblock': Return false to cancel an autoblock.
+$autoblockip: The IP going to be autoblocked.
+$block: The block from which the autoblock is coming.
'AbortLogin': Return false to cancel account login.
$user: the User object being authenticated against
@@ -250,6 +246,7 @@ $old: old title
$nt: new title
$user: user who is doing the move
$err: error message
+$reason: the reason for the move (added in 1.13)
'AbortNewAccount': Return false to cancel account creation.
$user: the User object about to be created (read-only, incomplete)
@@ -268,6 +265,36 @@ before showing the edit form ( EditPage::edit() ). This is triggered
on &action=edit.
$EditPage : the EditPage object
+'APIEditBeforeSave': before saving a page with api.php?action=edit,
+after processing request parameters. Return false to let the request
+fail, returning an error message or an <edit result="Failure"> 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
+
+'APIQueryInfoTokens': use this hook to add custom tokens to prop=info.
+Every token has an action, which will be used in the intoken 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)
+where $pageid is the page ID of the page the token is requested for
+and $title is the associated Title 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': 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 (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, $rev)
+where $pageid is the page ID of the page associated to the revision the
+token is requested for, $title the associated Title object and $rev the
+associated Revision object. In the hook, just add your callback to the
+$tokenFunctions array and return true (returning false makes no sense)
+$tokenFunctions: array(action => callback)
+
'ArticleAfterFetchContent': 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
@@ -276,11 +303,14 @@ $content: the content (string) of the article
$article: the article (object) being deleted
$user: the user (object) deleting the article
$reason: the reason (string) the article is being deleted
+$error: if the deletion was prohibited, the (raw HTML) error message to display
+ (added in 1.13)
'ArticleDeleteComplete': after an article is deleted
$article: the article that was deleted
$user: the user that deleted the article
$reason: the reason the article was deleted
+$id: id of the article that was deleted
'ArticleEditUpdateNewTalk': before updating user_newtalk when a user talk page was changed
$article: article (object) of the user talk page
@@ -292,7 +322,7 @@ $article: article (object) being modified
$title: title (object) used to create the article object
$article: article (object) that will be returned
-'ArticleInsertComplete': After an article is created
+'ArticleInsertComplete': After a new article is created
$article: Article created
$user: User creating the article
$text: New content
@@ -332,7 +362,11 @@ $moveonly: boolean whether it was for move only or not
'ArticlePurge': before executing "&action=purge"
$article: article (object) to purge
-'ArticleRevisionUndeleted' after an article revision is restored
+'ArticleRevisionVisiblitySet': called when changing visibility of one or more
+revision 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)
@@ -391,13 +425,14 @@ $create: Whether or not the restoration caused the page to be created
'ArticleViewRedirect': before setting "Redirected from ..." subtitle when follwed an redirect
$article: target article (object)
+'AuthPluginAutoCreate': Called when creating a local account for an user logged
+in from an external authentication method
+$user: User object created locally
+
'AuthPluginSetup': update or replace authentication plugin object ($wgAuth)
Gives a chance for an extension to set it programattically to a variable class.
&$auth: the $wgAuth object, probably a stub
-'AutoAuthenticate': called to authenticate users on external/environmental means
-$user: writes user object to this parameter
-
'AutopromoteCondition': check autopromote condition for user.
$type: condition type
$args: arguments
@@ -417,7 +452,8 @@ rendered inline in wiki pages or galleries in category pages.
&$time: image timestamp
'BeforePageDisplay': Prior to outputting a page
-$out: OutputPage object
+&$out: OutputPage object
+&$skin: Skin object
'BeforeParserFetchTemplateAndtitle': before a template is fetched by Parser
&$parser: Parser object
@@ -454,6 +490,18 @@ $user: the user who did the block (not the one being blocked)
$isbn: ISBN to show information for
$output: OutputPage object in use
+'BrokenLink': Before the HTML is created for a broken (i.e. red) link
+&$linker: Linker instance
+$nt: the page title
+$query: the URL query string passed in
+&$u: the URL of this link
+&$style: the inline CSS style
+&$prefix: a prefix prepended to the linked text
+&$text: the text placed by the user in the wiki-link
+&$inside: any additional alphanumeric characters placed after the wiki-link,
+that are made part of the link text
+&$trail: text placed immediately after the HTML link
+
'CategoryPageView': before viewing a categorypage in CategoryPage::view
$catpage: CategoryPage instance
@@ -465,6 +513,15 @@ $catpage: CategoryPage instance
$unpatrolled: Whether or not we are showing unpatrolled changes.
$watched: Whether or not the change is watched by the user.
+'ContribsPager::getQueryInfo': Before the contributions query is about to run
+&$pager: Pager object for contributions
+&queryInfo: The query for the contribs Pager
+
+'ContributionsLineEnding': Called before a contributions HTML line is finished
+$page: SpecialPage object for contributions
+$ret: the HTML line
+$row: the DB row for this line
+
'ContributionsToolLinks': Change tool links above Special:Contributions
$id: User identifier
$title: User page title
@@ -492,11 +549,13 @@ $editor: Edit form (see includes/EditPage.php)
$text: Contents of the edit box
$section: Section being edited
&$error: Error message to return
+$summary: Edit summary for page
'EditFilterMerged': 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
'EditFormPreloadText': Allows population of the edit form when creating new pages
&$text: Text to preload with
@@ -519,6 +578,14 @@ Alternatively, modifying $error and returning true will cause the contents of $e
to be echoed at the top of the edit form as wikitext. Return true without altering
$error to allow the edit to proceed.
+'EditPageBeforeConflictDiff': allows modifying the EditPage object and output
+when there's an edit conflict. Return false to halt normal diff output; in
+this case you're responsible for computing and outputting the entire "conflict"
+part, i.e., the "difference between revisions" and "your text" headers and
+sections.
+&$editor: EditPage instance
+&$out: OutputPage instance
+
'EditPageBeforeEditButtons': allows modifying the edit buttons below the textarea in the edit form
&$editpage: The current EditPage object
&$buttons: Array of edit buttons "Save", "Preview", "Live", and "Diff"
@@ -562,12 +629,35 @@ $text: text of the mail
&$list: List object (defaults to NULL, change it to an object instance and return
false override the list derivative used)
+'FileDeleteComplete': When a file is deleted
+$file: reference to the deleted file
+$oldimage: in case of the deletion of an old image, the name of the old file
+$article: in case all revisions of the file are deleted a reference to the article
+ associated with the file.
+$user: user who performed the deletion
+$reason: reason
+
'FileUpload': When a file upload occurs
$file : Image object representing the file that was uploaded
+'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
+
+'GetAutoPromoteGroups': When determining which autopromote groups a user is entitled to be in.
+&$user: user to promote.
+&$promote: groups that will be added.
+
'GetBlockedStatus': after loading blocking status of an user from the database
$user: user (object) being checked
+'GetCacheVaryCookies': get cookies that should vary cache options
+$out: OutputPage object
+&$cookies: array of cookies name, add a value to it if you want to add a cookie
+ that have to vary cache options
+
'GetFullURL': modify fully-qualified URLs used in redirects/export/offsite data
$title: Title object of page
$url: string value as output (out parameter, can modify)
@@ -602,10 +692,41 @@ $result: User permissions error to add. If none, return true.
'getUserPermissionsErrorsExpensive': Absolutely the same, but is called only
if expensive checks are enabled.
-'ImageOpenShowImageInlineBefore': Call potential extension just before showing the image on an image page
+'ImageBeforeProduceHTML': Called before producing the HTML created by a wiki
+ image insertion. You can skip the default logic entirely by returning
+ false, or just modify a few things using call-by-reference.
+&$this: Skin object
+&$title: Title object of the image
+&$file: File object, or false if it doesn't exist
+&$frameParams: Various parameters with special meanings; see documentation in
+ includes/Linker.php for Linker::makeImageLink2
+&$handlerParams: Various parameters with special meanings; see documentation in
+ includes/Linker.php for Linker::makeImageLink2
+&$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)
$output: $wgOut
+'ImagePageFileHistoryLine': called when a file history line is contructed
+$file: the file
+$line: the HTML of the history line
+$css: the line CSS class
+
+'ImagePageFindFile': called when fetching the file associated with an image page
+$page: ImagePage object
+&$file: File object
+&$displayFile: displayed File object
+
+'InitializeArticleMaybeRedirect': MediaWiki check to see if title is a redirect
+$title: Title object ($wgTitle)
+$request: WebRequest
+$ignoreRedirect: boolean to skip redirect check
+$target: Title/string of redirect target
+
'InitPreferencesForm': called at the end of PreferencesForm's constructor
$form: the PreferencesForm
$request: the web request to initialized from
@@ -641,6 +762,16 @@ $lang: laguage code (string)
$specialPageAliases: associative array of magic words synonyms
$lang: laguage code (string)
+'LinkerMakeExternalImage': At the end of Linker::makeExternalImage() just before the return
+&$url: the image url
+&$alt: the image's alt text
+&$img: the new image HTML (if returning false)
+
+'LinkerMakeExternalLink': At the end of Linker::makeExternalLink() just before the return
+&$url: the link url
+&$text: the link text
+&$link: the new link HTML (if returning false)
+
'LinksUpdate': At the beginning of LinksUpdate::doUpdate() just before the actual update
&$linksUpdate: the LinkUpdate object
@@ -654,6 +785,14 @@ $lang: laguage code (string)
'LoadExtensionSchemaUpdates': called by maintenance/updaters.inc when upgrading database schema
+'LocalFile::getHistory': called before file history query performed
+$file: the file
+$tables: tables
+$fields: select fields
+$conds: conditions
+$opts: query options
+$join_conds: JOIN conditions
+
'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
@@ -715,14 +854,35 @@ $article: $wgArticle
$title: $wgTitle
$user: $wgUser
$request: $wgRequest
+$this: 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
'MonoBookTemplateToolboxEnd': Called by Monobook skin after toolbox links have been rendered (useful for adding more)
+Note: this is only run for the Monobook skin. To add items to the toolbox
+for all 'SkinTemplate'-type skins, use the SkinTemplateToolboxEnd hook
+instead.
$tools: array of tools
+'NewRevisionFromEditComplete': called when a revision was inserted due to an edit
+$article: the article edited
+$rev: the new revision
+$baseID: the revision ID this was based off, if any
+
+'NormalizeMessageKey': Called before the software gets the text of a message
+ (stuff in the MediaWiki: namespace), useful for changing WHAT message gets displayed
+&$key: the message being looked up. Change this to something else to change what message gets displayed (string)
+&$useDB: whether or not to look up the message in the database (bool)
+&$langCode: the language code to get the message for (string) - or -
+ whether to use the content language (true) or site language (false) (bool)
+&$transform: whether or not to expand variables and templates in the message (bool)
+
+'OpenSearchUrls': Called when constructing the OpenSearch description XML.
+Hooks can alter or append to the array of URLs for search & suggestion formats.
+&$urls: array of associative arrays with Url element attributes
+
'OutputPageBeforeHTML': a page has been processed by the parser and
the resulting HTML is about to be displayed.
$parserOutput: the parserOutput (object) that corresponds to the page
@@ -732,6 +892,12 @@ $text: the text that will be displayed, in HTML (string)
$out: OutputPage instance (object)
$parserOutput: parserOutput instance being added in $out
+'OutputPageMakeCategoryLinks': links are about to be generated for the page's categories.
+ Implementations should return false if they generate the category links, so the default link generation is skipped.
+$out: OutputPage instance (object)
+$categories: associative array, keys are category names, values are category types ("normal" or "hidden")
+$links: array, intended to hold the result. Must be an associative array with category types as keys and arrays of HTML links as values.
+
'PageHistoryBeforeList': When a history page list is about to be constructed.
$article: the article that the history is loading for
@@ -739,6 +905,10 @@ $article: the article that the history is loading for
$row: the revision row for this line
$s: the string representing this parsed line
+'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.
@@ -767,8 +937,8 @@ $text: actual text
'ParserClearState': called at the end of Parser::clearState()
$parser: Parser object being cleared
-'ParserFirstCallInit': called when the ther parser initialises for the first time
-$parser: Parser object being cleared
+'ParserFirstCallInit': called when the parser initialises for the first time
+&$parser: Parser object being cleared
'ParserGetVariableValueSwitch': called when the parser need the value of a custom magic word
$parser: Parser object
@@ -788,6 +958,11 @@ $varCache: varaiable cache (array)
$parser: Parser object
$limitReport: text that will be included (without comment tags)
+'ParserMakeImageParams': Called before the parser make an image link, use this to modify the parameters of the image.
+$title: title object representing the file
+$file: file object that will be used to create the image
+&$params: 2-D array of parameters
+
'ParserTestParser': called when creating a new instance of Parser in maintenance/parserTests.inc
$parser: Parser object created
@@ -815,7 +990,7 @@ $form : PreferencesForm object
'PrefixSearchBackend': Override the title prefix search used for OpenSearch and
AJAX search suggestions. Put results into &$results outparam and return false.
-$ns : int namespace key to search in
+$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)
@@ -845,11 +1020,21 @@ $out: output page to render to, probably $wgOut
$form: the PreferencesForm
$user: the User object to load preferences from
+'RevisionInsertComplete': called after a revision is inserted into the DB
+&$revision: the Revision
+$data: the data stored in old_text. The meaning depends on $flags: if external
+ is set, it's the URL of the revision text in external storage; otherwise,
+ it's the revision text itself. In either case, if gzip is set, the revision
+ text is gzipped.
+$flags: a comma-delimited list of strings representing the options used. May
+ include: utf8 (this will always be set for new revisions); gzip; external.
+
'SavePreferences': called at the end of PreferencesForm::savePreferences;
returning false prevents the preferences from being saved.
$form: the PreferencesForm
$user: the User object to save preferences to
-$message: change this to set an error message (ignored if the hook does notreturn fals)
+$message: change this to set an error message (ignored if the hook does not return false)
+$old: old preferences of the user
'SearchUpdate': Prior to search update completion
$id : Page id
@@ -926,9 +1111,32 @@ $checkEdit: Whether or not the action=edit query should be added if appropriate.
$sktemplate: SkinTemplate object
$content_actions: array of tabs
+'SkinTemplateToolboxEnd': Called by SkinTemplate skins after toolbox links have been rendered (useful for adding more)
+$tools: array of tools
+
'SpecialContributionsBeforeMainOutput': Before the form on Special:Contributions
$id: User identifier
+'SpecialListusersDefaultQuery': called right before the end of UsersPager::getDefaultQuery()
+$pager: The UsersPager instance
+$query: The query array to be returned
+
+'SpecialListusersFormatRow': called right before the end of UsersPager::formatRow()
+$item: HTML to be returned. Will be wrapped in <li></li> after the hook finishes
+$row: Database row object
+
+'SpecialListusersHeader': called before closing the <fieldset> in UsersPager::getPageHeader()
+$pager: The UsersPager instance
+$out: The header HTML
+
+'SpecialListusersHeaderForm': called before adding the submit button in UsersPager::getPageHeader()
+$pager: The UsersPager instance
+$out: The header HTML
+
+'SpecialListusersQueryInfo': called right before the end of UsersPager::getQueryInfo()
+$pager: The UsersPager instance
+$query: The query array to be returned
+
'SpecialMovepageAfterMove': called after moving a page
$movePage: MovePageForm object
$oldTitle: old title (object)
@@ -955,9 +1163,27 @@ $funct: function called to execute the special page
'SpecialPage_initList': called when setting up SpecialPage::$mList, use this hook to remove a core special page
$list: list (array) of core special pages
+'SpecialRecentChangesPanel': called when building form options in SpecialRecentChanges
+&$extraOpts: array of added items, to which can be added
+$opts: FormOptions for this request
+
+'SpecialRecentChangesQuery': called when building sql query for SpecialRecentChanges
+&$conds: array of where conditionals for query
+&$tables: array of tables to be queried
+&$join_conds: join conditions for the tables
+$opts: FormOptions for this request
+
'SpecialSearchNogomatch': called when user clicked the "Go" button but the target doesn't exist
$title: title object generated from the text entred by the user
+'SpecialSearchResults': called before search result display when there are matches
+$term: string of search term
+&$titleMatches: empty or SearchResultSet object
+&$textMatches: empty or SearchResultSet object
+
+'SpecialSearchNoResults': called before search result display when there are no matches
+$term: string of search term
+
'SpecialVersionExtensionTypes': called when generating the extensions credits, use this to change the tables headers
$extTypes: associative array of extensions types
@@ -1006,7 +1232,11 @@ string $tempName: filesystem path to the temporary file for checks
string &$error: output: HTML error to show if upload canceled by returning false
'UploadComplete': Upon completion of a file upload
-$image: Image object representing the file that was uploaded
+$uploadForm: Upload form object. File can be accessed by $uploadForm->mLocalFile.
+
+'UserArrayFromResult': called when creating an UserArray object from a database result
+&$userArray: set this to an object to override the default object returned
+$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.
@@ -1031,8 +1261,35 @@ $template: SimpleTemplate instance for the form
$user: User to get groups for
&$groups: Current effective groups
+'UserGetAllRights': after calculating a list of all available rights
+&$rights: Array of rights, which may be added to.
+
+'UserGetEmail': called when getting an user email address
+$user: User object
+&$email: email, change this to override local email
+
+'UserGetEmailAuthenticationTimestamp': called when getting the timestamp of email authentification
+$user: User object
+&$timestamp: timestamp, change this to override local email authentification timestamp
+
+'UserGetImplicitGroups': Called in User::getImplicitGroups()
+&$groups: List of implicit (automatically-assigned) groups
+
+'UserGetRights': Called in User::getRights()
+$user: User to get rights for
+&$rights: Current rights
+
+'UserLoadDefaults': called when loading a default user
+$user: user object
+$name: user name
+
+'UserLoadFromSession': called to authenticate users on external/environmental means
+$user: user object being loaded
+&$result: set this to a boolean value to abort the normal authentification process
+
'UserLoginComplete': after a user has logged in
$user: the user object that was created on login
+$inject_html: Any HTML to inject after the "logged in" message.
'UserLoginForm': change to manipulate the login form
$template: SimpleTemplate instance for the form
@@ -1042,23 +1299,34 @@ $user: the user object that is about to be logged out
'UserLogoutComplete': after a user has logged out
$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)
'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
-
-'UserGetImplicitGroups': Called in User::getImplicitGroups()
-&$groups: List of implicit (automatically-assigned) groups
-
-'UserGetRights': Called in User::getRights()
-$user: User to get rights for
-&$rights: Current rights
'UserRetrieveNewTalks': called when retrieving "You have new messages!" message(s)
$user: user retrieving new talks messages
$talks: array of new talks page(s)
+'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
+&$cookies: cookies array mapping cookie name to its value
+
+'UserSetEmail': called when changing user email address
+$user: User object
+&$email: new email, change this to override new email address
+
+'UserSetEmailAuthenticationTimestamp': called when setting the timestamp of email authentification
+$user: User object
+&$timestamp: new timestamp, change this to override local email authentification timestamp
+
'UserToggles': called when initialising User::$mToggles, use this to add new toggles
$toggles: array of toggles to add
diff --git a/docs/html/README b/docs/html/README
index d25b803d..90de167f 100644
--- a/docs/html/README
+++ b/docs/html/README
@@ -1,4 +1,4 @@
-This directory is for the auto-generated phpdoc documentation.
+This directory is for the auto-generated doxygen documentation.
Run 'php mwdocgen.php' in the maintenance subdirectory to build the docs.
-Get phpDocumentor from http://phpdoc.org/
+Get Doxygen from http://www.doxygen.org/
diff --git a/docs/language.txt b/docs/language.txt
index 9d6a0db3..1df98810 100644
--- a/docs/language.txt
+++ b/docs/language.txt
@@ -1,24 +1,21 @@
language.txt
-The Language object handles all readable text produced by the
-software. The most used function is getMessage(), usually
-called with the wrapper function wfMsg() which calls that method
-on the global language object. It just returns a piece of text
-given a text key. It is recommended that you use each key only
-once--bits of text in different contexts that happen to be
-identical in English may not be in other languages, so it's
-better to add new keys than to reuse them a lot. Likewise,
-if there is text that gets combined with things like names and
-titles, it is better to put markers like "$1" inside a piece
-of text and use str_replace() than to compose such messages in
-code, because their order may change in other languages too.
+The Language object handles all readable text produced by the software. The most
+used function is getMessage(), usually called with the wrapper function wfMsg()
+which calls that method on the global language object. It just returns a piece
+of text given a text key. It is recommended that you use each key only
+once--bits of text in different contexts that happen to be identical in English
+may not be in other languages, so it's better to add new keys than to reuse them
+a lot. Likewise, if there is text that gets combined with things like names and
+titles, it is better to put markers like "$1" inside a piece of text and use
+str_replace() than to compose such messages in code, because their order may
+change in other languages too.
-While the system is running, there will be one global language
-object, which will be a subtype of Language. The methods in
-these objects will return the native text requested if available,
-otherwise they fall back to sending English text (which is why
-the LanguageEn object has no code at all--it just inherits the
-English defaults of the Language base class).
+While the system is running, there will be one global language object, which
+will be a subtype of Language. The methods in these objects will return the
+native text requested if available, otherwise they fall back to sending English
+text (which is why the LanguageEn object has no code at all--it just inherits
+the English defaults of the Language base class).
-The names of the namespaces are also contained in the language
-object, though the numbers are fixed.
+The names of the namespaces are also contained in the language object, though
+the numbers are fixed.
diff --git a/docs/linkcache.txt b/docs/linkcache.txt
index 3e9799c3..266f200d 100644
--- a/docs/linkcache.txt
+++ b/docs/linkcache.txt
@@ -1,18 +1,24 @@
linkcache.txt
-The LinkCache class maintains a list of article titles and
-the information about whether or not the article exists in
-the database. This is used to mark up links when displaying
-a page. If the same link appears more than once on any page,
-then it only has to be looked up once. In most cases, link
-lookups are done in batches with the LinkBatch class, or the
-equivalent in Parser::replaceLinkHolders(), so the link
-cache is mostly useful for short snippets of parsed text
-(such as the site notice), and for links in the navigation
-areas of the skin.
+The LinkCache class maintains a list of article titles and the information about
+whether or not the article exists in the database. This is used to mark up links
+when displaying a page. If the same link appears more than once on any page,
+then it only has to be looked up once. In most cases, link lookups are done in
+batches with the LinkBatch class, or the equivalent in Parser::replaceLinkHolders(),
+so the link cache is mostly useful for short snippets of parsed text (such as
+the site notice), and for links in the navigation areas of the skin.
-The link cache was formerly used to track links used in a
-document for the purposes of updating the link tables. This
-application is now deprecated.
+The link cache was formerly used to track links used in a document for the
+purposes of updating the link tables. This application is now deprecated.
+To create a batch, you can use the following code:
+$pages = array( 'Main Page', 'Project:Help', /* ... */ );
+$titles = array();
+
+foreach( $pages as $page ){
+ $titles[] = Title::newFromText( $page );
+}
+
+$batch = new LinkBatch( $titles );
+$batch->execute(); \ No newline at end of file
diff --git a/docs/magicword.txt b/docs/magicword.txt
index 74e49cff..6ecdb569 100644
--- a/docs/magicword.txt
+++ b/docs/magicword.txt
@@ -1,44 +1,88 @@
magicword.txt
-Magic Words are some phrases used in the wikitext. They are defined in several arrays:
-* $magicWords (includes/MagicWord.php) includes their internal names ('MAG_XXX').
-* $wgVariableIDs (includes/MagicWord.php) includes their IDs (MAG_XXX, which are constants),
- after their internal names are used for "define()".
-* Localized arrays (languages/LanguageXX.php) include their different names to be used by the users.
+Magic Words are some phrases used in the wikitext. They are used for two things:
+* Variables (like {{PAGENAME}}, {{SERVER}}, ...): part of wikitext, that looks
+ like templates but that don't accept any parameter.
+* Parser functions (like {{fullurl:...}}, {{#special:...}}): behaves like
+ functions and accepts parameters.
-The localized arrays keys are the internal IDs, and the values are an array, whose include their
-case-sensitivity and their alias forms. The first form defined is used by the program, for example,
-when moving a page and its old name should include #REDIRECT.
+The localized arrays keys are the internal name, and the values are an array,
+whose include their case-sensitivity and their alias forms. The first form
+defined is used by the program, for example, when moving a page and its old name
+should include #REDIRECT.
-Adding magic words should be done using several hooks:
-* "MagicWordMagicWords" should be used to add the internal name ('MAG_XXX') to $magicWords.
-* "MagicWordwgVariableIDs" should be used to add the ID (MAG_XXX constant) to $wgVariableIDs.
-* "LanguageGetMagic" should be used to add the different names of the magic word. Use both
- the localized name and the English name. Get the language code by the parameter $langCode;
+They can be added in several arrays:
+* LanguageGetMagic hook, by adding a new key in $magicWords array. You can get
+ language code in the $lang parameter. Use both the localized name and the
+ English name.
+* By adding a file to $wgExtensionMessagesFiles and defining there $magicWords.
+ This array is associative with the language code in the first dimension key
+ and then a "normal" array of magic words.
+* Localized arrays (languages/messages/LanguageXX.php) include their different
+ names to be used by the users.
-For example:
+To add a new variable, you should use the "MagicWordwgVariableIDs" hook to add
+the internal name to the $magicWords array. You'll need to define the value of
+the variable with the "ParserGetVariableValueSwitch" hook.
+
+For example to add a new variable:
-$wgHooks['MagicWordMagicWords'][] = 'wfAddCustomMagicWord';
$wgHooks['MagicWordwgVariableIDs'][] = 'wfAddCustomMagicWordID';
$wgHooks['LanguageGetMagic'][] = 'wfAddCustomMagicWordLang';
+$wgHooks['ParserGetVariableValueSwitch'][] = 'wfGetCustomMagicWordValue';
-function wfAddCustomMagicWord( &$magicWords ) {
- $magicWords[] = 'MAG_CUSTOM';
+function wfAddCustomMagicWordID( &$magicWords ) {
+ $magicWords[] = 'mag_custom';
return true;
}
-function wfAddCustomMagicWordID( &$magicWords ) {
- $magicWords[] = MAG_CUSTOM;
+function wfAddCustomMagicWordLang( &$magicWords, $langCode ) {
+ switch ( $langCode ) {
+ case 'es':
+ $magicWords['mag_custom'] = array( 1, "ADUANERO", "CUSTOM" );
+ break;
+ default:
+ $magicWords['mag_custom'] = array( 1, "CUSTOM" );
+ }
return true;
}
+function wfGetCustomMagicWordValue( &$parser, &$varCache, &$index, &$ret ){
+ if( $index == 'mag_custom' ){
+ $ret = $varCache['mag_custom'] = "Custom value";
+ }
+ return true;
+}
+
+And to add a new parser function:
+
+$wgHooks['LanguageGetMagic'][] = 'wfAddCustomMagicWordLang';
+$wgHooks['ParserFirstCallInit'][] = 'wfRegisterCustomMagicWord';
+
function wfAddCustomMagicWordLang( &$magicWords, $langCode ) {
switch ( $langCode ) {
case 'es':
- $magicWords[MAG_CUSTOM] = array( 0, "#aduanero", "#custom" );
+ $magicWords['mag_custom'] = array( 0, "aduanero", "custom" );
break;
default:
- $magicWords[MAG_CUSTOM] = array( 0, "#custom" );
+ $magicWords['mag_custom'] = array( 0, "custom" );
}
return true;
}
+
+function wfRegisterCustomMagicWord( &$parser ){
+ $parser->setFunctionHook( 'mag_custom', 'wfGetCustomMagicWordValue' );
+ return true;
+}
+
+function wfGetCustomMagicWordValue( &$parser, $var1, $var2 ){
+ return "custom: var1 is $var1, var2 is $var2";
+}
+
+Note: the 'ParserFirstCallInit' hook is only aviable since 1.12. To work with
+an older version, you'll need to use an extension function.
+
+Online documentation (contains more informations):
+Magic words: http://www.mediawiki.org/wiki/Manual:Magic_words
+Variables: http://www.mediawiki.org/wiki/Manual:Variable
+Parser functions: http://www.mediawiki.org/wiki/Manual:Parser_functions \ No newline at end of file
diff --git a/docs/memcached.txt b/docs/memcached.txt
index 3addd965..b31554cc 100644
--- a/docs/memcached.txt
+++ b/docs/memcached.txt
@@ -1,15 +1,19 @@
-memcached support for MediaWiki:
-
-From ca August 2003, MediaWiki has optional support for memcached, a
-"high-performance, distributed memory object caching system".
-For general information on it, see: http://www.danga.com/memcached/
+MediaWiki has optional support for memcached, a "high-performance,
+distributed memory object caching system". For general information
+on it, see: http://www.danga.com/memcached/
Memcached is likely more trouble than a small site will need, but
for a larger site with heavy load, like Wikipedia, it should help
lighten the load on the database servers by caching data and objects
in memory.
-== Requirements ==
+== Installation ==
+
+Packages are available for Fedora, Debian, Ubuntu and probably other
+Linux distributions. If you there's no package available for your
+distribution, you can compile it from source.
+
+== Compilation ==
* PHP must be compiled with --enable-sockets
@@ -35,18 +39,21 @@ server is appropriately firewalled, and that the port(s) used for
memcached servers are not publicly accessible. Otherwise, anyone on
the internet can put data into and read data from your cache.
-An attacker familiar with MediaWiki internals could use this to give
-themselves developer access and delete all data from the wiki's
-database, as well as getting all users' password hashes and e-mail
-addresses.
+An attacker familiar with MediaWiki internals could use this to steal
+passwords and email addresses, or to make themselves a sysop and
+install malicious javascript on the site. There may be other types
+of vulnerability, no audit has been done -- so be safe and keep it
+behind a firewall.
********************* W A R N I N G ! ! ! ! ! ***********************
== Setup ==
-If you want to start small, just run one memcached on your web
-server:
+If you installed memcached using a distro, the daemon should be started
+automatically using /etc/init.d/memcached.
- memcached -d -l 127.0.0.1 -p 11000 -m 64
+To start the daemon manually, use something like:
+
+ memcached -d -l 127.0.0.1 -p 11211 -m 64
(to run in daemon mode, accessible only via loopback interface,
on port 11000, using up to 64MB of memory)
@@ -54,7 +61,7 @@ on port 11000, using up to 64MB of memory)
In your LocalSettings.php file, set:
$wgMainCacheType = CACHE_MEMCACHED;
- $wgMemCachedServers = array( "127.0.0.1:11000" );
+ $wgMemCachedServers = array( "127.0.0.1:11211" );
The wiki should then use memcached to cache various data. To use
multiple servers (physically separate boxes or multiple caches
@@ -70,61 +77,175 @@ usage evenly), make its entry a subarray:
== PHP client for memcached ==
-As of this writing, MediaWiki includes version 1.0.10 of the PHP
-memcached client by Ryan Gilfether <hotrodder@rocketmail.com>.
-You'll find some documentation for it in the 'php-memcached'
-subdirectory under the present one.
-
-We intend to track updates, but if you want to check for the lastest
-released version, see http://www.danga.com/memcached/apis.bml
+MediaWiki uses a fork of Ryan T. Dean's pure-PHP memcached client.
+The newer PECL module is not yet supported.
-If you don't set $wgUseMemCached, we still create a MemCacheClient,
+MediaWiki uses three object for object caching:
+* $wgMemc, controlled by $wgMainCacheType
+* $parserMemc, controlled by $wgParserCacheType
+* $messageMemc, controlled by $wgMessageCacheType
+If you set CACHE_NONE to one of the three control variable, (default
+value for $wgMainCacheType), MediaWiki still create a MemCacheClient,
but requests to it are no-ops and we always fall through to the
database. If the cache daemon can't be contacted, it should also
disable itself fairly smoothly.
+By default, $wgMemc is used but when it is $parserMemc or $messageMemc
+this is mentionned below.
+
== Keys used ==
-User:
- key: $wgDBname:user:id:$sId
- ex: wikidb:user:id:51
- stores: instance of class User
- set in: User::loadFromSession()
- cleared by: User::saveSettings(), UserTalkUpdate::doUpdate()
-
+(incomplete, out of date)
+
+Ajax Search:
+ key: $wgDBname:ajaxsearch:md5( $search )
+ ex: wikidb:ajaxsearch:9565814d5d564fa898dd6111b94fae0b
+ stores: array with the result of research of a given text
+ cleared by: nothing
+ expiry: 30 minutes
+
+Date Formatter:
+ key: $wgDBname:dateformatter
+ ex: wikidb:dateformatter
+ stores: a single instance of the DateFormatter class
+ cleared by: nothing
+ expiry: one hour
+
+Difference Engine:
+ key: $wgDBname:diff:version:{MW_DIFF_VERSION}:oldid:$old:newid:$new
+ ex: wikidb:diff:version:1.11a:oldid:1:newid:2
+ stores: body of a difference
+ cleared by: nothing
+ expiry: one week
+
+Interwiki:
+ key: $wgDBname:interwiki:$prefix
+ ex: wikidb:interwiki:w
+ stores: object from the interwiki table of the database
+ expiry: $wgInterwikiExpiry
+ cleared by: nothing
+
+Lag time of the databases:
+ key: $wgDBname:lag_times
+ ex: wikidb:lag_times
+ stores: array mapping the database id to its lag time
+ expriy: 5 secondes
+ cleared by: nothing
+
+Localisation:
+ key: $wgDBname:localisation:$lang
+ ex: wikidb:localisation:de
+ stores: array of localisation settings
+ set in: Language::loadLocalisation()
+ expiry: none
+ cleared by: Language::loadLocalisation()
+
+Message Cache:
+ stored in: $messageMemc
+ key: $wgDBname:messages, $wgDBname:messages-hash, $wgDBname:messages-status
+ ex: wikidb:messages, wikidb:messages-hash, wikidb:messages-status
+ stores: an array where the keys are DB keys and the values are messages
+ set in: wfMsg(), Article::editUpdates() both call wfLoadAllMessages()
+ expriy: $wgMsgCacheExpiry
+ cleared by: nothing
+
Newtalk:
key: $wgDBname:newtalk:ip:$ip
ex: wikidb:newtalk:ip:123.45.67.89
stores: integer, 0 or 1
set in: User::loadFromDatabase()
cleared by: User::saveSettings() # ?
- expiry set to 30 minutes
-
-LinkCache:
- key: $wgDBname:lc:title:$title
- ex: wikidb:lc:title:Wikipedia:Welcome,_Newcomers!
- stores: cur_id of page, or 0 if page does not exist
- set in: LinkCache::addLink()
- cleared by: LinkCache::clearBadLink()
- should be cleared on page deletion and rename
-MediaWiki namespace:
- key: $wgDBname:messages
- ex: wikidb:messages
- stores: an array where the keys are DB keys and the values are messages
- set in: wfMsg(), Article::editUpdates() both call wfLoadAllMessages()
+ expiry: 30 minutes
+
+Parser Cache:
+ stored in: $parserMemc
+ controlled by: $wgEnableParserCache
+ key: $wgDBname:pcache:idhash:$pageid-$renderkey!$hash$edit
+ $pageid: id of the page
+ $renderkey: 1 if action=render, 0 otherwise
+ $hash: hash of user options, see User::getPageRenderingHash()
+ $edit: '!edit=0' if the user can't edit the page, '' otherwise
+ ex: wikidb:pcache:idhash:1-0!1!0!!en!2
+ stores: ParserOutput object
+ modified by: Article::editUpdates()
+ expriy: $wgParserCacheExpireTime or one hour if it contains specific magic
+ words
+
+Ping limiter:
+ controlled by: $wgRateLimits
+ key: $wgDBname:limiter:action:$action:ip:$ip,
+ $wgDBname:limiter:action:$action:user:$id,
+ mediawiki:limiter:action:$action:ip:$ip and
+ mediawiki:limiter:action:$action:subnet:$sub
+ ex: wikidb:limiter:action:edit:ip:123.45.67.89,
+ wikidb:limiter:action:edit:user:1012
+ mediawiki:limiter:action:edit:ip:123.45.67.89 and
+ mediawiki:limiter:action:$action:subnet:123.45.67
+ stores: number of action made by user/ip/subnet
cleared by: nothing
+ expiry: expiry set for the action and group in $wgRateLimits
-Watchlist:
- key: $wgDBname:watchlist:id:$userID
- ex: wikidb:watchlist:id:4635
- stores: HTML string
- cleared by: nothing, expiry time $wgWLCacheTimeout (1 hour)
- note: emergency optimisation only
-
-IP blocks:
- key: $wgDBname:ipblocks
- ex: wikidb:ipblocks
- stores: array of arrays, for the BlockCache class
- cleared by: BlockCache:clear()
+
+Proxy Check: (deprecated)
+ key: $wgDBname:proxy:ip:$ip
+ ex: wikidb:proxy:ip:123.45.67.89
+ stores: 1 if the ip is a proxy
+ cleared by: nothing
+ expiry: $wgProxyMemcExpiry
+
+Revision text:
+ key: $wgDBname:revisiontext:textid:$id
+ ex: wikidb:revisiontext:textid:1012
+ stores: text of a revision
+ cleared by: nothing
+ expriry: $wgRevisionCacheExpiry
+
+Sessions:
+ controlled by: $wgSessionsInMemcached
+ key: $wgBDname:session:$id
+ ex: wikidb:session:38d7c5b8d3bfc51egf40c69bc40f8be3
+ stores: $SESSION, useful when using a multi-sever wiki
+ expriy: one hour
+ cleared by: session_destroy()
+
+Sidebar:
+ stored in: $parserMemc
+ controlled by: $wgEnableSidebarCache
+ key: $wgDBname:sidebar
+ ex: wikidb:sidebar
+ stores: the html output of the sidebar
+ expriy: $wgSidebarCacheExpiry
+ cleared by: MessageCache::replace()
+
+Special:Allpages:
+ key: $wgDBname:allpages:ns:$ns
+ ex: wikidb:allpages:ns:0
+ stores: array of pages in a namespace
+ expiry: one hour
+ cleared by: nothing
+
+Special:Recentchanges (feed):
+ stored in: $messageMemc
+ key: $wgDBname:rcfeed:$format:limit:$imit:minor:$hideminor and
+ rcfeed:$format:timestamp
+ ex: wikidb:rcfeed:rss:limit:50:minor:0 and rcfeed:rss:timestamp
+ stores: xml output of feed
+ expiry: one day
+ clear by: calling Special:Recentchanges?action=purge
+
+Statistics:
+ controlled by: $wgStatsMethod
+ key: $wgDBname:stats:$key
+ ex: wikibd:stats:request_with_session
+ stores: counter for statistics (see maintenance/stats.php script)
+ expiry: none (?)
+ cleared by: maintenance/clear_stats.php script
+
+User:
+ key: $wgDBname:user:id:$sId
+ ex: wikidb:user:id:51
+ stores: instance of class User
+ set in: User::saveToCache()
+ cleared by: User::saveSettings(), User::clearSharedCache()
-... more to come ... \ No newline at end of file
+... more to come ...
diff --git a/docs/scripts.txt b/docs/scripts.txt
new file mode 100644
index 00000000..f8228a46
--- /dev/null
+++ b/docs/scripts.txt
@@ -0,0 +1,63 @@
+scripts.txt
+
+MediaWiki primary scripts are in the root directory of the software. Users
+should only use these scripts to access the wiki. There are also some .php that
+aren't primary scripts but helper files and won't work if they are accessed
+directly by the web.
+
+Primary scripts:
+
+ index.php
+ Main access point. It handles the most of requests.
+ See http://www.mediawiki.org/wiki/Manual:Index.php
+
+ api.php
+ Script to provide an API for bots to fetch content and informations about
+ the site and also modify it. See http://www.mediawiki.org/wiki/API
+ for more informations.
+
+ img_auth.php
+ Script that only serve images to logged in users. To configure the wiki
+ to use that script, see http://www.mediawiki.org/wiki/Manual:Image_Authorisation.
+
+ opensearch_desc.php
+ Returns a OpenSearch description document (see http://www.opensearch.org/)
+ that points to the search engines of the wiki.
+
+ profileinfo.php
+ Allow users to see the profiling information that are stored in the
+ database.
+
+ To save the profiling information in the database (required to use this
+ script), you have to modify StartProfiler.php to use the Profiler class and
+ not the stub profiler which is enabled by default.
+ You will also need to set $wgProfileToDatabase to true in LocalSettings.php
+ to force the profiler to save the informations in the database and apply the
+ maintenance/archives/patch-profiling.sql patch to the database.
+
+ To enable the profileinfo.php itself, you'll need to create the
+ AdminSettings.php file (see AdminSettings.sample for more information) and
+ set $wgEnableProfileInfo to true in that file. See also
+ http://www.mediawiki.org/wiki/How_to_debug#Profiling.
+
+ redirect.php
+ Script that only redirect to the article passed in the wpDropdown parameter
+ of the request. Used by the nostalgia skin to access special pages with the
+ dropdown box at the top of the page.
+
+ thumb.php
+ Script used to resize images if it is configured to be done when the web
+ browser requests the image and not when generating the page. This script can
+ be used as a 404 handler to generate image thumbs when they don't exist.
+
+ trackback.php
+ Allow to add a new trackback to the database. This script returns XML
+ and require a POST request to work, thus it should only be accessed by some
+ specific programs and won't work with normal web browsers.
+
+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 the config/index.php5 script.
+
diff --git a/docs/skin.txt b/docs/skin.txt
index 82a5b72e..524a0397 100644
--- a/docs/skin.txt
+++ b/docs/skin.txt
@@ -1,48 +1,84 @@
-
skin.txt
-This document describes the overall architecture of MediaWiki's HTML rendering
-code as well as some history about the skin system. It is placed here rather
-than in comments in the code itself to help reduce the code size.
+MediaWiki's default skin is called Monobook, after the black-and-white photo of
+a book, in the page background. This skin has been the default since MediaWiki
+1.3 (2004). It is used on Wikipedia, and is popular on other sites.
+
+There are three legacy skins which were introduced before MediaWiki 1.3:
+
+* Standard (a.k.a. Classic): The old default skin written by Lee Crocker
+during the phase 3 rewrite, in 2002.
+
+* Nostalgia: A skin which looks like Wikipedia did in its first year (2001).
+This skin is now used for the old Wikipedia snapshot at
+http://nostalgia.wikipedia.org/
+
+* Cologne Blue: A nicer-looking alternative to Standard.
+
+
+And there are four Monobook-derived skins which have been introduced since 1.3:
+
+* MySkin: Monobook without the CSS. The idea is that you customise it using user
+or site CSS (see below)
+
+* Chick: A lightweight Monobook skin with no sidebar, the sidebar links are
+given at the bottom of the page instead, as in the unstyled MySkin.
+
+* Simple: A lightweight skin with a simple white-background sidebar and no
+top bar.
+
+* Modern: An attractive blue/grey theme with sidebar and top bar.
+
+
+== Custom CSS/JS ==
+
+It is possible to customise the site CSS and JavaScript without editing any
+source files. This is done by editing some pages on the wiki:
+
+* [[MediaWiki:Common.css]] -- for skin-independent CSS
+* [[MediaWiki:Monobook.css]], [[MediaWiki:Simple.css]], etc. -- for
+skin-dependent CSS
+* [[MediaWiki:Common.js]], [[MediaWiki:Monobook.js]], etc. -- for custom
+site JavaScript
+
+These can also be customised on a per-user basis, by editing
+[[User:<name>/monobook.css]], [[User:<name>/monobook.js]], etc.
+
+This feature has led to a wide variety of "user styles" becoming available,
+which change the appearance of Monobook or MySkin:
+
+http://meta.wikimedia.org/wiki/Gallery_of_user_styles
-== Version 1.4 ==
+If you want a different look for your wiki, that gallery is a good place to start.
-MediaWiki still use the PHPTal skin system introduced in version 1.3 but some
-changes have been made to the file organisation.
+== Drop-in custom skins ==
-PHP class and PHPTal templates have been moved to /skins/ (respectivly from
-/includes/ and /templates/). This way skin designer and end user just stick to
-one directory.
+If you put a file in MediaWiki's skins directory, ending in .php, the name of
+the file will automatically be added as a skin name, and the file will be
+expected to contain a class called Skin<name> with the skin class. You can then
+make that skin the default by adding to LocalSettings.php:
-Two samples are provided to start with, one for PHPTal use (SkinPHPTal.sample)
-and one without (Skin.sample).
+$wgDefaultSkin = '<name>';
+You can also disable dropped-in or core skins using:
-== Version 1.3 ==
+$wgSkipSkins[] = '<name>';
-The following might help a bit though.
+This technique is used by the more ambitious MediaWiki site operators, to
+create complex custom skins for their wikis. It should be preferred over
+editing the core Monobook skin directly.
-Firstly, there's Skin.php; this file will check various settings, and it
-contains a base class from which new skins can be derived.
+See http://www.mediawiki.org/wiki/Manual:Skinning for more information.
-Before version 1.3, each skin had its own PHP file (with a sub-class to Skin)
-to generate the output. The files are:
- * SkinCologneBlue.php
- * SkinNostalgia.php
- * SkinStandard.php
- * SkinWikimediaWiki.php
-If you want to change those skins, you have to edit these PHP files.
-
-Since 1.3 a new special skin file is available: SkinPHPTal.php. It makes use of
-the PHPTal template engine and allows you to separate code and layout of the
-pages. The default 1.3 skin is MonoBook and it uses the SkinPHPTAL class.
+== Extension skins ==
-To change the layout, just edit the PHPTal template (templates/xhtml_slim.pt)
-as well as the stylesheets (stylesheets/monobook/*).
+It is now possible (since MediaWiki 1.12) to write a skin as a standard
+MediaWiki extension, enabled via LocalSettings.php. This is done by adding
+it to $wgValidSkinNames, for example:
+$wgValidSkinNames['mycoolskin'] = 'My cool skin';
-== pre 1.3 version ==
+and then registering a class in $wgAutoloadClasses called SkinMycoolskin, which
+derives from Skin. This technique is apparently not yet used (as of 2008)
+outside the DumpHTML extension.
-Unfortunately there isn't any documentation, and the code's in a bit of a mess
-right now during the transition from the old skin code to the new template-based
-skin code in 1.3.
diff --git a/docs/title.txt b/docs/title.txt
index fd449c54..d2d91c9c 100644
--- a/docs/title.txt
+++ b/docs/title.txt
@@ -1,76 +1,67 @@
title.txt
-The MediaWiki software's "Title" class represents article
-titles, which are used for many purposes: as the human-readable
-text title of the article, in the URL used to access the article,
-the wikitext link to the article, the key into the article
-database, and so on. The class in instantiated from one of
-these forms and can be queried for the others, and for other
-attributes of the title. This is intended to be an
-immutable "value" class, so there are no mutator functions.
+The MediaWiki software's "Title" class represents article titles, which are used
+for many purposes: as the human-readable text title of the article, in the URL
+used to access the article, the wikitext link to the article, the key into the
+article database, and so on. The class in instantiated from one of these forms
+and can be queried for the others, and for other attributes of the title. This
+is intended to be an immutable "value" class, so there are no mutator functions.
-To get a new instance, call one of the static factory
-methods Title::newFromURL(), Title::newFromDBKey(),
-or Title::newFromText(). Once instantiated, the
-other non-static accessor methods can be used, such as
-getText(), getDBKey(), getNamespace(), etc.
+To get a new instance, call Title::newFromText(). Once instantiated, the
+non-static accessor methods can be used, such as getText(), getDBKey(),
+getNamespace(), etc. Note that Title::newFromText() may return false if the text
+is illegal according to the rules below.
-The prefix rules: a title consists of an optional interwiki
-prefix (such as "m:" for meta or "de:" for German), followed
-by an optional namespace, followed by the remainder of the
-title. Both interwiki prefixes and namespace prefixes have
-the same rules: they contain only letters, digits, space, and
-underscore, must start with a letter, are case insensitive,
-and spaces and underscores are interchangeable. Prefixes end
-with a ":". A prefix is only recognized if it is one of those
-specifically allowed by the software. For example, "de:name"
-is a link to the article "name" in the German Wikipedia, because
-"de" is recognized as one of the allowable interwikis. The
-title "talk:name" is a link to the article "name" in the "talk"
-namespace of the current wiki, because "talk" is a recognized
-namespace. Both may be present, and if so, the interwiki must
-come first, for example, "m:talk:name". If a title begins with
-a colon as its first character, no prefixes are scanned for,
-and the colon is just removed. Note that because of these
-rules, it is possible to have articles with colons in their
-names. "E. Coli 0157:H7" is a valid title, as is "2001: A Space
-Odyssey", because "E. Coli 0157" and "2001" are not valid
-interwikis or namespaces.
+The prefix rules: a title consists of an optional interwiki prefix (such as "m:"
+for meta or "de:" for German), followed by an optional namespace, followed by
+the remainder of the title. Both interwiki prefixes and namespace prefixes have
+the same rules: they contain only letters, digits, space, and underscore, must
+start with a letter, are case insensitive, and spaces and underscores are
+interchangeable. Prefixes end with a ":". A prefix is only recognized if it is
+one of those specifically allowed by the software. For example, "de:name" is a
+link to the article "name" in the German Wikipedia, because "de" is recognized
+as one of the allowable interwikis. The title "talk:name" is a link to the
+article "name" in the "talk" namespace of the current wiki, because "talk" is a
+recognized namespace. Both may be present, and if so, the interwiki must
+come first, for example, "m:talk:name". If a title begins with a colon as its
+first character, no prefixes are scanned for, and the colon is just removed.
+Note that because of these rules, it is possible to have articles with colons in
+their names. "E. Coli 0157:H7" is a valid title, as is "2001: A Space Odyssey",
+because "E. Coli 0157" and "2001" are not valid interwikis or namespaces.
-It is not possible to have an article whose bare name includes
-a namespace or interwiki prefix.
+It is not possible to have an article whose bare name includes a namespace or
+interwiki prefix.
-An initial colon in a title listed in wiki text may however
-suppress special handling for interlanguage links, image links,
-and category links.
+An initial colon in a title listed in wiki text may however suppress special
+handling for interlanguage links, image links, and category links. It is also
+used to indicate the main namespace in template inclusions.
-Character mapping rules: Once prefixes have been stripped, the
-rest of the title processed this way: spaces and underscores are
-treated as equivalent and each is converted to the other in the
-appropriate context (underscore in URL and database keys, spaces
-in plain text). "Extended" characters in the 0x80..0xFF range
-are allowed in all places, and are valid characters. They are
-encoded in URLs. Other characters may be ASCII letters, digits,
-hyphen, comma, period, apostrophe, parentheses, and colon. No
-other ASCII characters are allowed, and will be deleted if found
-(they will probably cause a browser to misinterpret the URL).
-Extended characters are _not_ urlencoded when used as text or
-database keys.
+Once prefixes have been stripped, the rest of the title processed this way:
-Character encoding rules: TODO
+* Spaces and underscores are treated as equivalent and each is converted to the
+ other in the appropriate context (underscore in URL and database keys, spaces
+ in plain text).
+* Multiple consecutive spaces are converted to a single space.
+* Leading or trailing space is removed.
+* If $wgCapitalLinks is enabled (the default), the first letter is capitalised,
+ using the capitalisation function of the content language object.
+* The unicode characters LRM (U+200E) and RLM (U+200F) are silently stripped.
+* Invalid UTF-8 sequences or instances of the replacement character (U+FFFD) are
+ considered illegal.
+* A percent sign followed by two hexadecimal characters is illegal
+* Anything that looks like an XML/HTML character reference is illegal
+* Any character not matched by the $wgLegalTitleChars regex is illegal
+* Zero-length titles (after whitespace stripping) are illegal
-Canonical forms: the canonical form of a title will always be
-returned by the object. In this form, the first (and only the
-first) character of the namespace and title will be uppercased;
-the rest of the namespace will be lowercased, while the title
-will be left as is. The text form will use spaces, the URL and
-DBkey forms will use underscores. Interwiki prefixes are all
-lowercase. The namespace will use underscores when returned
-alone; it will use spaces only when attached to the text title.
+All titles except special pages must be less than 255 bytes when encoded with
+UTF-8, because that is the size of the database field. Special page titles may
+be up to 512 bytes.
-getArticleID() needs some explanation: for "internal" articles,
-it should return the "page_id" field if the article exists, else
-it returns 0. For all external articles it returns 0. All of
-the IDs for all instances of Title created during a request are
-cached, so they can be looked up quickly while rendering wiki
-text with lots of internal links.
+Note that Unicode Normal Form C (NFC) is enforced by MediaWiki's user interface
+input functions, and so titles will typically be in this form.
+
+getArticleID() needs some explanation: for "internal" articles, it should return
+the "page_id" field if the article exists, else it returns 0. For all external
+articles it returns 0. All of the IDs for all instances of Title created during
+a request are cached, so they can be looked up quickly while rendering wiki text
+with lots of internal links. See linkcache.txt.
diff --git a/includes/AjaxDispatcher.php b/includes/AjaxDispatcher.php
index 7b85ed20..c489cf1c 100644
--- a/includes/AjaxDispatcher.php
+++ b/includes/AjaxDispatcher.php
@@ -1,5 +1,9 @@
<?php
/**
+ * @defgroup Ajax Ajax
+ *
+ * @file
+ * @ingroup Ajax
* Handle ajax requests and send them to the proper handler.
*/
@@ -11,7 +15,7 @@ require_once( 'AjaxFunctions.php' );
/**
* Object-Oriented Ajax functions.
- * @addtogroup Ajax
+ * @ingroup Ajax
*/
class AjaxDispatcher {
/** The way the request was made, either a 'get' or a 'post' */
@@ -58,6 +62,7 @@ class AjaxDispatcher {
break;
default:
+ wfProfileOut( __METHOD__ );
return;
# Or we could throw an exception:
#throw new MWException( __METHOD__ . ' called without any data (mode empty).' );
@@ -81,9 +86,13 @@ class AjaxDispatcher {
wfProfileIn( __METHOD__ );
if (! in_array( $this->func_name, $wgAjaxExportList ) ) {
+ wfDebug( __METHOD__ . ' Bad Request for unknown function ' . $this->func_name . "\n" );
+
wfHttpError( 400, 'Bad Request',
"unknown function " . (string) $this->func_name );
} else {
+ wfDebug( __METHOD__ . ' dispatching ' . $this->func_name . "\n" );
+
if ( strpos( $this->func_name, '::' ) !== false ) {
$func = explode( '::', $this->func_name, 2 );
} else {
@@ -93,6 +102,10 @@ class AjaxDispatcher {
$result = call_user_func_array($func, $this->args);
if ( $result === false || $result === NULL ) {
+ 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" );
}
@@ -103,9 +116,15 @@ class AjaxDispatcher {
$result->sendHeaders();
$result->printText();
+
+ 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" );
+
if (!headers_sent()) {
wfHttpError( 500, 'Internal Error',
$e->getMessage() );
@@ -119,5 +138,3 @@ class AjaxDispatcher {
$wgOut = null;
}
}
-
-
diff --git a/includes/AjaxFunctions.php b/includes/AjaxFunctions.php
index ffd3168a..9daca9e5 100644
--- a/includes/AjaxFunctions.php
+++ b/includes/AjaxFunctions.php
@@ -1,8 +1,7 @@
<?php
-
-/**
- * @package MediaWiki
- * @addtogroup Ajax
+/**
+ * @file
+ * @ingroup Ajax
*/
if( !defined( 'MEDIAWIKI' ) ) {
@@ -56,7 +55,7 @@ function js_unescape($source, $iconv_to = 'UTF-8') {
/**
* Function coverts number of utf char into that character.
- * Function taken from: http://sk2.php.net/manual/en/function.utf8-encode.php#49336
+ * Function taken from: http://www.php.net/manual/en/function.utf8-encode.php#49336
*
* @param $num Integer
* @return utf8char
@@ -76,7 +75,7 @@ function code2utf($num){
define( 'AJAX_SEARCH_VERSION', 2 ); //AJAX search cache version
function wfSajaxSearch( $term ) {
- global $wgContLang, $wgOut, $wgUser, $wgCapitalLinks, $wgMemc;
+ global $wgContLang, $wgUser, $wgCapitalLinks, $wgMemc;
$limit = 16;
$sk = $wgUser->getSkin();
$output = '';
@@ -84,7 +83,7 @@ function wfSajaxSearch( $term ) {
$term = trim( $term );
$term = $wgContLang->checkTitleEncoding( $wgContLang->recodeInput( js_unescape( $term ) ) );
if ( $wgCapitalLinks )
- $term = $wgContLang->ucfirst( $term );
+ $term = $wgContLang->ucfirst( $term );
$term_title = Title::newFromText( $term );
$memckey = $term_title ? wfMemcKey( 'ajaxsearch', md5( $term_title->getFullText() ) ) : wfMemcKey( 'ajaxsearch', md5( $term ) );
@@ -97,12 +96,12 @@ function wfSajaxSearch( $term ) {
$r = $more = '';
$canSearch = true;
-
+
$results = PrefixSearch::titleSearch( $term, $limit + 1 );
foreach( array_slice( $results, 0, $limit ) as $titleText ) {
$r .= '<li>' . $sk->makeKnownLink( $titleText ) . "</li>\n";
}
-
+
// Hack to check for specials
if( $results ) {
$t = Title::newFromText( $results[0] );
@@ -128,9 +127,10 @@ function wfSajaxSearch( $term ) {
$valid = (bool) $term_title;
$term_url = urlencode( $term );
- $term_diplay = htmlspecialchars( $valid ? $term_title->getFullText() : $term );
+ $term_normalized = $valid ? $term_title->getFullText() : $term;
+ $term_display = htmlspecialchars( $term );
$subtitlemsg = ( $valid ? 'searchsubtitle' : 'searchsubtitleinvalid' );
- $subtitle = wfMsgWikiHtml( $subtitlemsg, $term_diplay );
+ $subtitle = wfMsgExt( $subtitlemsg, array( 'parse' ), wfEscapeWikiText( $term_normalized ) );
$html = '<div id="searchTargetHide"><a onclick="Searching_Hide_Results();">'
. wfMsgHtml( 'hideresults' ) . '</a></div>'
. '<h1 class="firstHeading">'.wfMsgHtml('search')
@@ -138,15 +138,15 @@ function wfSajaxSearch( $term ) {
if( $canSearch ) {
$html .= '<ul><li>'
. $sk->makeKnownLink( $wgContLang->specialPage( 'Search' ),
- wfMsgHtml( 'searchcontaining', $term_diplay ),
+ wfMsgHtml( 'searchcontaining', $term_display ),
"search={$term_url}&fulltext=Search" )
. '</li><li>' . $sk->makeKnownLink( $wgContLang->specialPage( 'Search' ),
- wfMsgHtml( 'searchnamed', $term_diplay ) ,
+ wfMsgHtml( 'searchnamed', $term_display ) ,
"search={$term_url}&go=Go" )
. "</li></ul>";
}
if( $r ) {
- $html .= "<h2>" . wfMsgHtml( 'articletitles', $term_diplay ) . "</h2>"
+ $html .= "<h2>" . wfMsgHtml( 'articletitles', $term_display ) . "</h2>"
. '<ul>' .$r .'</ul>' . $more;
}
@@ -161,7 +161,7 @@ function wfSajaxSearch( $term ) {
* Called for AJAX watch/unwatch requests.
* @param $pagename Prefixed title string for page to watch/unwatch
* @param $watch String 'w' to watch, 'u' to unwatch
- * @return String '<w#>' or '<u#>' on successful watch or unwatch,
+ * @return String '<w#>' or '<u#>' on successful watch or unwatch,
* respectively, followed by an HTML message to display in the alert box; or
* '<err#>' on error
*/
@@ -169,7 +169,7 @@ function wfAjaxWatch($pagename = "", $watch = "") {
if(wfReadOnly()) {
// redirect to action=(un)watch, which will display the database lock
// message
- return '<err#>';
+ return '<err#>';
}
if('w' !== $watch && 'u' !== $watch) {
@@ -206,4 +206,3 @@ function wfAjaxWatch($pagename = "", $watch = "") {
return '<u#>'.wfMsgExt( 'removedwatchtext', array( 'parse' ), $title->getPrefixedText() );
}
}
-
diff --git a/includes/AjaxResponse.php b/includes/AjaxResponse.php
index 8fa08539..c79e928b 100644
--- a/includes/AjaxResponse.php
+++ b/includes/AjaxResponse.php
@@ -1,11 +1,16 @@
<?php
+/**
+ * @file
+ * @ingroup Ajax
+ */
+
if( !defined( 'MEDIAWIKI' ) ) {
die( 1 );
}
/**
* @todo document
- * @addtogroup Ajax
+ * @ingroup Ajax
*/
class AjaxResponse {
@@ -99,7 +104,7 @@ class AjaxResponse {
if ( $this->mCacheDuration ) {
- # If squid caches are configured, tell them to cache the response,
+ # If squid caches are configured, tell them to cache the response,
# and tell the client to always check with the squid. Otherwise,
# tell the client to use a cached copy, without a way to purge it.
@@ -220,4 +225,3 @@ class AjaxResponse {
return true;
}
}
-
diff --git a/includes/Article.php b/includes/Article.php
index 0544db7d..4d8277bb 100644
--- a/includes/Article.php
+++ b/includes/Article.php
@@ -1,6 +1,7 @@
<?php
/**
* File for articles
+ * @file
*/
/**
@@ -34,6 +35,8 @@ class Article {
var $mTouched; //!<
var $mUser; //!<
var $mUserText; //!<
+ var $mRedirectTarget; //!<
+ var $mIsRedirect;
/**@}}*/
/**
@@ -57,12 +60,69 @@ class Article {
}
/**
+ * If this page is a redirect, get its target
+ *
+ * The target will be fetched from the redirect table if possible.
+ * If this page doesn't have an entry there, call insertRedirect()
+ * @return mixed Title object, or null if this page is not a redirect
+ */
+ public function getRedirectTarget() {
+ if(!$this->mTitle || !$this->mTitle->isRedirect())
+ return null;
+ if(!is_null($this->mRedirectTarget))
+ return $this->mRedirectTarget;
+
+ # Query the redirect table
+ $dbr = wfGetDB(DB_SLAVE);
+ $res = $dbr->select('redirect',
+ array('rd_namespace', 'rd_title'),
+ array('rd_from' => $this->getID()),
+ __METHOD__
+ );
+ $row = $dbr->fetchObject($res);
+ if($row)
+ return $this->mRedirectTarget = Title::makeTitle($row->rd_namespace, $row->rd_title);
+
+ # This page doesn't have an entry in the redirect table
+ return $this->mRedirectTarget = $this->insertRedirect();
+ }
+
+ /**
+ * Insert an entry for this page into the redirect table.
+ *
+ * Don't call this function directly unless you know what you're doing.
+ * @return Title object
+ */
+ public function insertRedirect() {
+ $retval = Title::newFromRedirect($this->getContent());
+ if(!$retval)
+ return null;
+ $dbw = wfGetDB(DB_MASTER);
+ $dbw->replace('redirect', array('rd_from'), array(
+ 'rd_from' => $this->getID(),
+ 'rd_namespace' => $retval->getNamespace(),
+ 'rd_title' => $retval->getDBKey()
+ ), __METHOD__);
+ return $retval;
+ }
+
+ /**
+ * Get the Title object this page redirects to
+ *
* @return mixed false, Title of in-wiki target, or string with URL
*/
- function followRedirect() {
+ public function followRedirect() {
$text = $this->getContent();
+ return self::followRedirectText( $text );
+ }
+
+ /**
+ * Get the Title object this text redirects to
+ *
+ * @return mixed false, Title of in-wiki target, or string with URL
+ */
+ public function followRedirectText( $text ) {
$rt = Title::newFromRedirect( $text );
-
# process if title object is valid and not special:userlogout
if( $rt ) {
if( $rt->getInterwiki() != '' ) {
@@ -92,7 +152,6 @@ class Article {
return $rt;
}
}
-
// No or invalid redirect
return false;
}
@@ -114,6 +173,7 @@ class Article {
$this->mCurID = $this->mUser = $this->mCounter = -1; # Not loaded
$this->mRedirectedFrom = null; # Title object if set
+ $this->mRedirectTarget = null; # Title object if set
$this->mUserText =
$this->mTimestamp = $this->mComment = '';
$this->mGoodAdjustment = $this->mTotalAdjustment = 0;
@@ -138,7 +198,7 @@ class Article {
* @return Return the text of this revision
*/
function getContent() {
- global $wgUser, $wgOut;
+ global $wgUser, $wgOut, $wgMessageCache;
wfProfileIn( __METHOD__ );
@@ -147,12 +207,13 @@ class Article {
$wgOut->setRobotpolicy( 'noindex,nofollow' );
if ( $this->mTitle->getNamespace() == NS_MEDIAWIKI ) {
+ $wgMessageCache->loadAllMessages();
$ret = wfMsgWeirdKey ( $this->mTitle->getText() ) ;
} else {
$ret = wfMsg( $wgUser->isLoggedIn() ? 'noarticletext' : 'noarticletextanon' );
}
- return "<div class='noarticletext'>$ret</div>";
+ return "<div class='noarticletext'>\n$ret\n</div>";
} else {
$this->loadContent();
wfProfileOut( __METHOD__ );
@@ -298,13 +359,13 @@ class Article {
*/
function loadPageData( $data = 'fromdb' ) {
if ( $data === 'fromdb' ) {
- $dbr = $this->getDB();
+ $dbr = wfGetDB( DB_MASTER );
$data = $this->pageDataFromId( $dbr, $this->getId() );
}
- $lc =& LinkCache::singleton();
+ $lc = LinkCache::singleton();
if ( $data ) {
- $lc->addGoodLinkObj( $data->page_id, $this->mTitle );
+ $lc->addGoodLinkObj( $data->page_id, $this->mTitle, $data->page_len, $data->page_is_redirect );
$this->mTitle->mArticleID = $data->page_id;
@@ -336,15 +397,13 @@ class Article {
return $this->mContent;
}
- $dbr = $this->getDB();
+ $dbr = wfGetDB( DB_MASTER );
# Pre-fill content with error message so that if something
# fails we'll have something telling us what we intended.
$t = $this->mTitle->getPrefixedText();
- if( $oldid ) {
- $t .= ',oldid='.$oldid;
- }
- $this->mContent = wfMsg( 'missingarticle', $t ) ;
+ $d = $oldid ? wfMsgExt( 'missingarticle-rev', array( 'escape' ), $oldid ) : '';
+ $this->mContent = wfMsg( 'missing-article', $t, $d ) ;
if( $oldid ) {
$revision = Revision::newFromId( $oldid );
@@ -377,15 +436,14 @@ class Article {
// FIXME: Horrible, horrible! This content-loading interface just plain sucks.
// We should instead work with the Revision object when we need it...
- $this->mContent = $revision->userCan( Revision::DELETED_TEXT ) ? $revision->getRawText() : "";
- //$this->mContent = $revision->getText();
+ $this->mContent = $revision->revText(); // Loads if user is allowed
$this->mUser = $revision->getUser();
$this->mUserText = $revision->getUserText();
$this->mComment = $revision->getComment();
$this->mTimestamp = wfTimestamp( TS_MW, $revision->getTimestamp() );
- $this->mRevIdFetched = $revision->getID();
+ $this->mRevIdFetched = $revision->getId();
$this->mContentLoaded = true;
$this->mRevision =& $revision;
@@ -407,8 +465,10 @@ class Article {
* Get the database which should be used for reads
*
* @return Database
+ * @deprecated - just call wfGetDB( DB_MASTER ) instead
*/
function getDB() {
+ wfDeprecated( __METHOD__ );
return wfGetDB( DB_MASTER );
}
@@ -490,6 +550,10 @@ class Article {
*/
function isRedirect( $text = false ) {
if ( $text === false ) {
+ if ( $this->mDataLoaded )
+ return $this->mIsRedirect;
+
+ // Apparently loadPageData was never called
$this->loadContent();
$titleObj = Title::newFromRedirect( $this->fetchContent() );
} else {
@@ -526,14 +590,14 @@ class Article {
$id = $this->getID();
if ( 0 == $id ) return;
- $this->mLastRevision = Revision::loadFromPageId( $this->getDB(), $id );
+ $this->mLastRevision = Revision::loadFromPageId( wfGetDB( DB_MASTER ), $id );
if( !is_null( $this->mLastRevision ) ) {
$this->mUser = $this->mLastRevision->getUser();
$this->mUserText = $this->mLastRevision->getUserText();
$this->mTimestamp = $this->mLastRevision->getTimestamp();
$this->mComment = $this->mLastRevision->getComment();
$this->mMinorEdit = $this->mLastRevision->isMinor();
- $this->mRevIdFetched = $this->mLastRevision->getID();
+ $this->mRevIdFetched = $this->mLastRevision->getId();
}
}
@@ -571,7 +635,6 @@ class Article {
}
/**
- * @todo Document, fixme $offset never used.
* @param $limit Integer: default 0.
* @param $offset Integer: default 0.
*/
@@ -593,6 +656,8 @@ class Article {
ORDER BY timestamp DESC";
if ($limit > 0) { $sql .= ' LIMIT '.$limit; }
+ if ($offset > 0) { $sql .= ' OFFSET '.$offset; }
+
$sql .= ' '. $this->getSelectOptions();
$res = $dbr->query($sql, __METHOD__);
@@ -609,7 +674,7 @@ class Article {
* This is the default action of the script: just view the page of
* the given title.
*/
- function view() {
+ function view() {
global $wgUser, $wgOut, $wgRequest, $wgContLang;
global $wgEnableParserCache, $wgStylePath, $wgParser;
global $wgUseTrackbacks, $wgNamespaceRobotPolicies, $wgArticleRobotPolicies;
@@ -618,7 +683,7 @@ class Article {
wfProfileIn( __METHOD__ );
- $parserCache =& ParserCache::singleton();
+ $parserCache = ParserCache::singleton();
$ns = $this->mTitle->getNamespace(); # shortcut
# Get variables from query string
@@ -689,12 +754,7 @@ class Article {
}
# Should the parser cache be used?
- $pcache = $wgEnableParserCache
- && intval( $wgUser->getOption( 'stubthreshold' ) ) == 0
- && $this->exists()
- && empty( $oldid )
- && !$this->mTitle->isCssOrJsPage()
- && !$this->mTitle->isCssJsSubpage();
+ $pcache = $this->useParserCache( $oldid );
wfDebug( 'Article::view using parser cache: ' . ($pcache ? 'yes' : 'no' ) . "\n" );
if ( $wgUser->getOption( 'stubthreshold' ) ) {
wfIncrStats( 'pcache_miss_stub' );
@@ -705,7 +765,6 @@ class Article {
// This is an internally redirected page view.
// We'll need a backlink to the source page for navigation.
if ( wfRunHooks( 'ArticleViewRedirect', array( &$this ) ) ) {
- $sk = $wgUser->getSkin();
$redir = $sk->makeKnownLinkObj( $this->mRedirectedFrom, '', 'redirect=no' );
$s = wfMsg( 'redirectedfrom', $redir );
$wgOut->setSubtitle( $s );
@@ -722,7 +781,6 @@ class Article {
// If it was reported from a trusted site, supply a backlink.
global $wgRedirectSources;
if( $wgRedirectSources && preg_match( $wgRedirectSources, $rdfrom ) ) {
- $sk = $wgUser->getSkin();
$redir = $sk->makeExternalLink( $rdfrom, $rdfrom );
$s = wfMsg( 'redirectedfrom', $redir );
$wgOut->setSubtitle( $s );
@@ -740,16 +798,17 @@ class Article {
$outputDone = true;
}
}
+ # Fetch content and check for errors
if ( !$outputDone ) {
$text = $this->getContent();
if ( $text === false ) {
# Failed to load, replace text with error message
$t = $this->mTitle->getPrefixedText();
if( $oldid ) {
- $t .= ',oldid='.$oldid;
- $text = wfMsg( 'missingarticle', $t );
+ $d = wfMsgExt( 'missingarticle-rev', array( 'escape' ), $oldid );
+ $text = wfMsg( 'missing-article', $t, $d );
} else {
- $text = wfMsg( 'noarticletext', $t );
+ $text = wfMsg( 'noarticletext' );
}
}
@@ -757,11 +816,11 @@ class Article {
if ( !$this->mTitle->userCanRead() ) {
$wgOut->loginToUse();
$wgOut->output();
+ wfProfileOut( __METHOD__ );
exit;
}
# We're looking at an old revision
-
if ( !empty( $oldid ) ) {
$wgOut->setRobotpolicy( 'noindex,nofollow' );
if( is_null( $this->mRevision ) ) {
@@ -772,6 +831,7 @@ class Article {
if( !$this->mRevision->userCan( Revision::DELETED_TEXT ) ) {
$wgOut->addWikiMsg( 'rev-deleted-text-permission' );
$wgOut->setPageTitle( $this->mTitle->getPrefixedText() );
+ wfProfileOut( __METHOD__ );
return;
} else {
$wgOut->addWikiMsg( 'rev-deleted-text-view' );
@@ -779,16 +839,13 @@ class Article {
}
}
}
-
}
- }
- if( !$outputDone ) {
- $wgOut->setRevisionId( $this->getRevIdFetched() );
+ $wgOut->setRevisionId( $this->getRevIdFetched() );
+
// Pages containing custom CSS or JavaScript get special treatment
if( $this->mTitle->isCssOrJsPage() || $this->mTitle->isCssJsSubpage() ) {
$wgOut->addHtml( wfMsgExt( 'clearyourcache', 'parse' ) );
-
// Give hooks a chance to customise the output
if( wfRunHooks( 'ShowRawCssJs', array( $this->mContent, $this->mTitle, $wgOut ) ) ) {
// Wrap the whole lot in a <pre> and don't parse
@@ -798,22 +855,9 @@ class Article {
$wgOut->addHtml( htmlspecialchars( $this->mContent ) );
$wgOut->addHtml( "\n</pre>\n" );
}
-
- }
-
- elseif ( $rt = Title::newFromRedirect( $text ) ) {
- # Display redirect
- $imageDir = $wgContLang->isRTL() ? 'rtl' : 'ltr';
- $imageUrl = $wgStylePath.'/common/images/redirect' . $imageDir . '.png';
- # Don't overwrite the subtitle if this was an old revision
- if( !$wasRedirected && $this->isCurrent() ) {
- $wgOut->setSubtitle( wfMsgHtml( 'redirectpagesub' ) );
- }
- $link = $sk->makeLinkObj( $rt, $rt->getFullText() );
-
- $wgOut->addHTML( '<img src="'.$imageUrl.'" alt="#REDIRECT " />' .
- '<span class="redirectText">'.$link.'</span>' );
-
+ } else if ( $rt = Title::newFromRedirect( $text ) ) {
+ # Don't append the subtitle if this was an old revision
+ $this->viewRedirect( $rt, !$wasRedirected && $this->isCurrent() );
$parseout = $wgParser->parse($text, $this->mTitle, ParserOptions::newFromUser($wgUser));
$wgOut->addParserOutputNoText( $parseout );
} else if ( $pcache ) {
@@ -840,7 +884,6 @@ class Article {
if( !$this->isCurrent() ) {
$wgOut->parserOptions()->setEditSection( $oldEditSectionSetting );
}
-
}
}
/* title may have been set from the cache */
@@ -850,8 +893,7 @@ class Article {
}
# check if we're displaying a [[User talk:x.x.x.x]] anonymous talk page
- if( $ns == NS_USER_TALK &&
- User::isIP( $this->mTitle->getText() ) ) {
+ if( $ns == NS_USER_TALK && IP::isValid( $this->mTitle->getText() ) ) {
$wgOut->addWikiMsg('anontalkpagetext');
}
@@ -875,6 +917,41 @@ class Article {
$this->viewUpdates();
wfProfileOut( __METHOD__ );
}
+
+ /*
+ * Should the parser cache be used?
+ */
+ protected function useParserCache( $oldid ) {
+ global $wgUser, $wgEnableParserCache;
+
+ return $wgEnableParserCache
+ && intval( $wgUser->getOption( 'stubthreshold' ) ) == 0
+ && $this->exists()
+ && empty( $oldid )
+ && !$this->mTitle->isCssOrJsPage()
+ && !$this->mTitle->isCssJsSubpage();
+ }
+
+ protected function viewRedirect( $target, $appendSubtitle = true, $forceKnown = false ) {
+ global $wgParser, $wgOut, $wgContLang, $wgStylePath, $wgUser;
+
+ # Display redirect
+ $imageDir = $wgContLang->isRTL() ? 'rtl' : 'ltr';
+ $imageUrl = $wgStylePath.'/common/images/redirect' . $imageDir . '.png';
+
+ if( $appendSubtitle ) {
+ $wgOut->appendSubtitle( wfMsgHtml( 'redirectpagesub' ) );
+ }
+ $sk = $wgUser->getSkin();
+ if ( $forceKnown )
+ $link = $sk->makeKnownLinkObj( $target, htmlspecialchars( $target->getFullText() ) );
+ else
+ $link = $sk->makeLinkObj( $target, htmlspecialchars( $target->getFullText() ) );
+
+ $wgOut->addHTML( '<img src="'.$imageUrl.'" alt="#REDIRECT " />' .
+ '<span class="redirectText">'.$link.'</span>' );
+
+ }
function addTrackbacks() {
global $wgOut, $wgUser;
@@ -897,6 +974,7 @@ class Article {
. $o->tb_id . "&token=" . urlencode( $wgUser->editToken() ) );
$rmvtxt = wfMsg( 'trackbackremove', htmlspecialchars( $delurl ) );
}
+ $tbtext .= "\n";
$tbtext .= wfMsg(strlen($o->tb_ex) ? 'trackbackexcerpt' : 'trackback',
$o->tb_title,
$o->tb_url,
@@ -1067,7 +1145,6 @@ class Article {
$result = $dbw->affectedRows() != 0;
if ($result) {
- // FIXME: Should the result from updateRedirectOn() be returned instead?
$this->updateRedirectOn( $dbw, $rt, $lastRevIsRedirect );
}
@@ -1112,6 +1189,8 @@ class Article {
$dbw->delete( 'redirect', $where, __METHOD__);
}
+ if( $this->getTitle()->getNamespace() == NS_IMAGE )
+ RepoGroup::singleton()->getLocalRepo()->invalidateImageRedirect( $this->getTitle() );
wfProfileOut( __METHOD__ );
return ( $dbw->affectedRows() != 0 );
}
@@ -1252,10 +1331,10 @@ class Article {
}
}
- $extraq = ''; // Give extensions a chance to modify URL query on update
- wfRunHooks( 'ArticleUpdateBeforeRedirect', array( $this, &$sectionanchor, &$extraq ) );
+ $extraQuery = ''; // Give extensions a chance to modify URL query on update
+ wfRunHooks( 'ArticleUpdateBeforeRedirect', array( $this, &$sectionanchor, &$extraQuery ) );
- $this->doRedirect( $this->isRedirect( $text ), $sectionanchor, $extraq );
+ $this->doRedirect( $this->isRedirect( $text ), $sectionanchor, $extraQuery );
}
return $good;
}
@@ -1291,11 +1370,12 @@ class Article {
* EDIT_NEW is specified and the article does exist, a duplicate key error will cause an exception
* to be thrown from the Database. These two conditions are also possible with auto-detection due
* to MediaWiki's performance-optimised locking strategy.
+ * @param $baseRevId, the revision ID this edit was based off, if any
*
* @return bool success
*/
- function doEdit( $text, $summary, $flags = 0 ) {
- global $wgUser, $wgDBtransactions;
+ function doEdit( $text, $summary, $flags = 0, $baseRevId = false ) {
+ global $wgUser, $wgDBtransactions, $wgUseAutomaticEditSummaries;
wfProfileIn( __METHOD__ );
$good = true;
@@ -1325,9 +1405,10 @@ class Article {
$oldtext = $this->getContent();
$oldsize = strlen( $oldtext );
- # Provide autosummaries if one is not provided.
- if ($flags & EDIT_AUTOSUMMARY && $summary == '')
+ # Provide autosummaries if one is not provided and autosummaries are enabled.
+ if( $wgUseAutomaticEditSummaries && $flags & EDIT_AUTOSUMMARY && $summary == '' ) {
$summary = $this->getAutosummary( $oldtext, $text, $flags );
+ }
$editInfo = $this->prepareTextForEdit( $text );
$text = $editInfo->pst;
@@ -1346,7 +1427,7 @@ class Article {
$lastRevision = 0;
$revisionId = 0;
-
+
$changed = ( strcmp( $text, $oldtext ) != 0 );
if ( $changed ) {
@@ -1368,7 +1449,8 @@ class Article {
'page' => $this->getId(),
'comment' => $summary,
'minor_edit' => $isminor,
- 'text' => $text
+ 'text' => $text,
+ 'parent_id' => $lastRevision
) );
$dbw->begin();
@@ -1382,6 +1464,8 @@ class Article {
$good = false;
$dbw->rollback();
} else {
+ wfRunHooks( 'NewRevisionFromEditComplete', array( $this, $revision, $baseRevId ) );
+
# Update recentchanges
if( !( $flags & EDIT_SUPPRESS_RC ) ) {
$rcid = RecentChange::notifyEdit( $now, $this->mTitle, $isminor, $wgUser, $summary,
@@ -1414,7 +1498,7 @@ class Article {
# Invalidate cache of this article and all pages using this article
# as a template. Partly deferred.
Article::onArticleEdit( $this->mTitle );
-
+
# Update links tables, site stats, etc.
$this->editUpdates( $text, $summary, $isminor, $now, $revisionId, $changed );
}
@@ -1446,6 +1530,8 @@ class Article {
# Update the page record with revision data
$this->updateRevisionOn( $dbw, $revision, 0 );
+
+ wfRunHooks( 'NewRevisionFromEditComplete', array($this, $revision, false) );
if( !( $flags & EDIT_SUPPRESS_RC ) ) {
$rcid = RecentChange::notifyNew( $now, $this->mTitle, $isminor, $wgUser, $summary, $bot,
@@ -1495,15 +1581,16 @@ class Article {
*
* @param boolean $noRedir Add redirect=no
* @param string $sectionAnchor section to redirect to, including "#"
+ * @param string $extraQuery, extra query params
*/
- function doRedirect( $noRedir = false, $sectionAnchor = '', $extraq = '' ) {
+ function doRedirect( $noRedir = false, $sectionAnchor = '', $extraQuery = '' ) {
global $wgOut;
if ( $noRedir ) {
$query = 'redirect=no';
- if( $extraq )
+ if( $extraQuery )
$query .= "&$query";
} else {
- $query = $extraq;
+ $query = $extraQuery;
}
$wgOut->redirect( $this->mTitle->getFullURL( $query ) . $sectionAnchor );
}
@@ -1518,8 +1605,8 @@ class Article {
# Check patrol config options
if ( !($wgUseNPPatrol || $wgUseRCPatrol)) {
- $wgOut->errorPage( 'rcpatroldisabled', 'rcpatroldisabledtext' );
- return;
+ $wgOut->showErrorPage( 'rcpatroldisabled', 'rcpatroldisabledtext' );
+ return;
}
# If we haven't been given an rc_id value, we can't do anything
@@ -1527,18 +1614,18 @@ class Article {
$rc = $rcid ? RecentChange::newFromId($rcid) : null;
if ( is_null ( $rc ) )
{
- $wgOut->errorPage( 'markedaspatrollederror', 'markedaspatrollederrortext' );
+ $wgOut->showErrorPage( 'markedaspatrollederror', 'markedaspatrollederrortext' );
return;
}
- if ( !$wgUseRCPatrol && $rc->mAttribs['rc_type'] != RC_NEW) {
+ if ( !$wgUseRCPatrol && $rc->getAttribute( 'rc_type' ) != RC_NEW) {
// Only new pages can be patrolled if the general patrolling is off....???
// @fixme -- is this necessary? Shouldn't we only bother controlling the
// front end here?
- $wgOut->errorPage( 'rcpatroldisabled', 'rcpatroldisabledtext' );
+ $wgOut->showErrorPage( 'rcpatroldisabled', 'rcpatroldisabledtext' );
return;
}
-
+
# Check permissions
$permission_errors = $this->mTitle->getUserPermissionsErrors( 'patrol', $wgUser );
@@ -1554,7 +1641,7 @@ class Article {
}
#It would be nice to see where the user had actually come from, but for now just guess
- $returnto = $rc->mAttribs['rc_type'] == RC_NEW ? 'Newpages' : 'Recentchanges';
+ $returnto = $rc->getAttribute( 'rc_type' ) == RC_NEW ? 'Newpages' : 'Recentchanges';
$return = Title::makeTitle( NS_SPECIAL, $returnto );
# If it's left up to us, check that the user is allowed to patrol this edit
@@ -1575,10 +1662,14 @@ class Article {
}
}
- # Mark the edit as patrolled
- RecentChange::markPatrolled( $rcid );
- PatrolLog::record( $rcid );
- wfRunHooks( 'MarkPatrolledComplete', array( &$rcid, &$wgUser, false ) );
+ # Check that the revision isn't patrolled already
+ # Prevents duplicate log entries
+ if( !$rc->getAttribute( 'rc_patrolled' ) ) {
+ # Mark the edit as patrolled
+ RecentChange::markPatrolled( $rcid );
+ PatrolLog::record( $rcid );
+ wfRunHooks( 'MarkPatrolledComplete', array( &$rcid, &$wgUser, false ) );
+ }
# Inform the user
$wgOut->setPageTitle( wfMsg( 'markedaspatrolled' ) );
@@ -1724,8 +1815,8 @@ class Article {
$updated = Article::flattenRestrictions( $limit );
$changed = ( $current != $updated );
- $changed = $changed || ($this->mTitle->areRestrictionsCascading() != $cascade);
- $changed = $changed || ($this->mTitle->mRestrictionsExpiry != $expiry);
+ $changed = $changed || ($updated && $this->mTitle->areRestrictionsCascading() != $cascade);
+ $changed = $changed || ($updated && $this->mTitle->mRestrictionsExpiry != $expiry);
$protect = ( $updated != '' );
# If nothing's changed, do nothing
@@ -1751,12 +1842,16 @@ class Article {
}
$comment = $wgContLang->ucfirst( wfMsgForContent( $comment_type, $this->mTitle->getPrefixedText() ) );
- foreach( $limit as $action => $restrictions ) {
- # Check if the group level required to edit also can protect pages
- # Otherwise, people who cannot normally protect can "protect" pages via transclusion
- $cascade = ( $cascade && isset($wgGroupPermissions[$restrictions]['protect']) && $wgGroupPermissions[$restrictions]['protect'] );
+ # Only restrictions with the 'protect' right can cascade...
+ # Otherwise, people who cannot normally protect can "protect" pages via transclusion
+ foreach( $limit as $action => $restriction ) {
+ # FIXME: can $restriction be an array or what? (same as fixme above)
+ if( $restriction != 'protect' && $restriction != 'sysop' ) {
+ $cascade = false;
+ break;
+ }
}
-
+
$cascade_description = '';
if ($cascade) {
$cascade_description = ' ['.wfMsg('protect-summary-cascade').']';
@@ -1770,8 +1865,7 @@ class Article {
$comment .= "$expiry_description";
if ( $cascade )
$comment .= "$cascade_description";
-
- $rowsAffected = false;
+
# Update restrictions table
foreach( $limit as $action => $restrictions ) {
if ($restrictions != '' ) {
@@ -1779,18 +1873,11 @@ class Article {
array( 'pr_page' => $id, 'pr_type' => $action
, 'pr_level' => $restrictions, 'pr_cascade' => $cascade ? 1 : 0
, 'pr_expiry' => $encodedExpiry ), __METHOD__ );
- if($dbw->affectedRows() != 0)
- $rowsAffected = true;
} else {
$dbw->delete( 'page_restrictions', array( 'pr_page' => $id,
'pr_type' => $action ), __METHOD__ );
- if($dbw->affectedRows() != 0)
- $rowsAffected = true;
}
}
- if(!$rowsAffected)
- // No change
- return true;
# Insert a null revision
$nullRevision = Revision::newNullRevision( $dbw, $id, $comment, true );
@@ -1806,15 +1893,15 @@ class Article {
'page_id' => $id
), 'Article::protect'
);
+
+ wfRunHooks( 'NewRevisionFromEditComplete', array($this, $nullRevision, false) );
wfRunHooks( 'ArticleProtectComplete', array( &$this, &$wgUser, $limit, $reason ) );
# Update the protection log
$log = new LogPage( 'protect' );
-
-
-
if( $protect ) {
- $log->addEntry( $modified ? 'modify' : 'protect', $this->mTitle, trim( $reason . " [$updated]$cascade_description$expiry_description" ) );
+ $log->addEntry( $modified ? 'modify' : 'protect', $this->mTitle,
+ trim( $reason . " [$updated]$cascade_description$expiry_description" ) );
} else {
$log->addEntry( 'unprotect', $this->mTitle, $reason );
}
@@ -1845,7 +1932,7 @@ class Article {
}
return implode( ':', $bits );
}
-
+
/**
* Auto-generates a deletion reason
* @param bool &$hasHistory Whether the page has a history
@@ -1907,7 +1994,7 @@ class Article {
else
$reason = wfMsgForContent('excontent', '$1');
}
-
+
// Replace newlines with spaces to prevent uglyness
$contents = preg_replace("/[\n\r]/", ' ', $contents);
// Calculate the maximum amount of chars to get
@@ -1930,18 +2017,20 @@ class Article {
$confirm = $wgRequest->wasPosted() &&
$wgUser->matchEditToken( $wgRequest->getVal( 'wpEditToken' ) );
-
+
$this->DeleteReasonList = $wgRequest->getText( 'wpDeleteReasonList', 'other' );
$this->DeleteReason = $wgRequest->getText( 'wpReason' );
-
+
$reason = $this->DeleteReasonList;
-
+
if ( $reason != 'other' && $this->DeleteReason != '') {
// Entry from drop down menu + additional comment
$reason .= ': ' . $this->DeleteReason;
} elseif ( $reason == 'other' ) {
$reason = $this->DeleteReason;
}
+ # Flag to hide all contents of the archived revisions
+ $suppress = $wgRequest->getVal( 'wpSuppress' ) && $wgUser->isAllowed('suppressrevision');
# This code desperately needs to be totally rewritten
@@ -1950,7 +2039,7 @@ class Article {
$wgOut->readOnlyPage();
return;
}
-
+
# Check permissions
$permission_errors = $this->mTitle->getUserPermissionsErrors( 'delete', $wgUser );
@@ -1980,7 +2069,7 @@ class Article {
}
if( $confirm ) {
- $this->doDelete( $reason );
+ $this->doDelete( $reason, $suppress );
if( $wgRequest->getCheck( 'wpWatch' ) ) {
$this->doWatch();
} elseif( $this->mTitle->userIsWatching() ) {
@@ -2003,10 +2092,10 @@ class Article {
array( 'delete-warning-toobig', $wgLang->formatNum( $wgDeleteRevisionsLimit ) ) );
}
}
-
- return $this->confirmDelete( '', $reason );
+
+ return $this->confirmDelete( $reason );
}
-
+
/**
* @return bool whether or not the page surpasses $wgDeleteRevisionsLimit revisions
*/
@@ -2018,7 +2107,7 @@ class Article {
}
return false;
}
-
+
/**
* @return int approximate revision count
*/
@@ -2079,10 +2168,9 @@ class Article {
/**
* Output deletion confirmation dialog
- * @param $par string FIXME: do we need this parameter? One Call from Article::delete with '' only.
* @param $reason string Prefilled reason
*/
- function confirmDelete( $par, $reason ) {
+ function confirmDelete( $reason ) {
global $wgOut, $wgUser, $wgContLang;
$align = $wgContLang->isRtl() ? 'left' : 'right';
@@ -2092,9 +2180,17 @@ class Article {
$wgOut->setRobotpolicy( 'noindex,nofollow' );
$wgOut->addWikiMsg( 'confirmdeletetext' );
- $form = Xml::openElement( 'form', array( 'method' => 'post', 'action' => $this->mTitle->getLocalURL( 'action=delete' . $par ), 'id' => 'deleteconfirm' ) ) .
- Xml::openElement( 'fieldset' ) .
- Xml::element( 'legend', array(), wfMsg( 'delete-legend' ) ) .
+ if( $wgUser->isAllowed( 'suppressrevision' ) ) {
+ $suppress = "<tr id=\"wpDeleteSuppressRow\" name=\"wpDeleteSuppressRow\"><td></td><td>";
+ $suppress .= Xml::checkLabel( wfMsg( 'revdelete-suppress' ), 'wpSuppress', 'wpSuppress', false, array( 'tabindex' => '2' ) );
+ $suppress .= "</td></tr>";
+ } else {
+ $suppress = '';
+ }
+
+ $form = Xml::openElement( 'form', array( 'method' => 'post', 'action' => $this->mTitle->getLocalURL( 'action=delete' ), 'id' => 'deleteconfirm' ) ) .
+ Xml::openElement( 'fieldset', array( 'id' => 'mw-delete-table' ) ) .
+ Xml::tags( 'legend', null, wfMsgExt( 'delete-legend', array( 'parsemag', 'escapenoentities' ) ) ) .
Xml::openElement( 'table' ) .
"<tr id=\"wpDeleteReasonListRow\">
<td align='$align'>" .
@@ -2102,7 +2198,7 @@ class Article {
"</td>
<td>" .
Xml::listDropDown( 'wpDeleteReasonList',
- wfMsgForContent( 'deletereason-dropdown' ),
+ wfMsgForContent( 'deletereason-dropdown' ),
wfMsgForContent( 'deletereasonotherlist' ), '', 'wpReasonDropDown', 1 ) .
"</td>
</tr>
@@ -2120,6 +2216,7 @@ class Article {
Xml::checkLabel( wfMsg( 'watchthis' ), 'wpWatch', 'wpWatch', $wgUser->getBoolOption( 'watchdeletion' ) || $this->mTitle->userIsWatching(), array( 'tabindex' => '3' ) ) .
"</td>
</tr>
+ $suppress
<tr>
<td></td>
<td>" .
@@ -2131,6 +2228,12 @@ class Article {
Xml::hidden( 'wpEditToken', $wgUser->editToken() ) .
Xml::closeElement( 'form' );
+ if ( $wgUser->isAllowed( 'editinterface' ) ) {
+ $skin = $wgUser->getSkin();
+ $link = $skin->makeLink ( 'MediaWiki:Deletereason-dropdown', wfMsgHtml( 'delete-edit-reasonlist' ) );
+ $form .= '<p class="mw-delete-editreasons">' . $link . '</p>';
+ }
+
$wgOut->addHTML( $form );
$this->showLogExtract( $wgOut );
}
@@ -2140,25 +2243,24 @@ class Article {
* Show relevant lines from the deletion log
*/
function showLogExtract( $out ) {
- $out->addHtml( '<h2>' . htmlspecialchars( LogPage::logName( 'delete' ) ) . '</h2>' );
- $logViewer = new LogViewer(
- new LogReader(
- new FauxRequest(
- array( 'page' => $this->mTitle->getPrefixedText(),
- 'type' => 'delete' ) ) ) );
- $logViewer->showList( $out );
+ $out->addHtml( Xml::element( 'h2', null, LogPage::logName( 'delete' ) ) );
+ LogEventsList::showLogExtract( $out, 'delete', $this->mTitle->getPrefixedText() );
}
/**
* Perform a deletion and output success or failure messages
*/
- function doDelete( $reason ) {
+ function doDelete( $reason, $suppress = false ) {
global $wgOut, $wgUser;
wfDebug( __METHOD__."\n" );
+
+ $id = $this->getId();
+
+ $error = '';
- if (wfRunHooks('ArticleDelete', array(&$this, &$wgUser, &$reason))) {
- if ( $this->doDeleteArticle( $reason ) ) {
+ if (wfRunHooks('ArticleDelete', array(&$this, &$wgUser, &$reason, &$error))) {
+ if ( $this->doDeleteArticle( $reason, $suppress ) ) {
$deleted = $this->mTitle->getPrefixedText();
$wgOut->setPagetitle( wfMsg( 'actioncomplete' ) );
@@ -2168,9 +2270,12 @@ class Article {
$wgOut->addWikiMsg( 'deletedtext', $deleted, $loglink );
$wgOut->returnToMain( false );
- wfRunHooks('ArticleDeleteComplete', array(&$this, &$wgUser, $reason));
+ wfRunHooks('ArticleDeleteComplete', array(&$this, &$wgUser, $reason, $id));
} else {
- $wgOut->showFatalError( wfMsg( 'cannotdelete' ) );
+ if ($error = '')
+ $wgOut->showFatalError( wfMsg( 'cannotdelete' ) );
+ else
+ $wgOut->showFatalError( $error );
}
}
}
@@ -2180,7 +2285,7 @@ class Article {
* Deletes the article with database consistency, writes logs, purges caches
* Returns success
*/
- function doDeleteArticle( $reason ) {
+ function doDeleteArticle( $reason, $suppress = false ) {
global $wgUseSquid, $wgDeferredUpdateList;
global $wgUseTrackbacks;
@@ -2198,6 +2303,19 @@ class Article {
$u = new SiteStatsUpdate( 0, 1, -(int)$this->isCountable( $this->getContent() ), -1 );
array_push( $wgDeferredUpdateList, $u );
+ // Bitfields to further suppress the content
+ if ( $suppress ) {
+ $bitfield = 0;
+ // This should be 15...
+ $bitfield |= Revision::DELETED_TEXT;
+ $bitfield |= Revision::DELETED_COMMENT;
+ $bitfield |= Revision::DELETED_USER;
+ $bitfield |= Revision::DELETED_RESTRICTED;
+ } else {
+ $bitfield = 'rev_deleted';
+ }
+
+ $dbw->begin();
// For now, shunt the revision data into the archive table.
// Text is *not* removed from the text table; bulk storage
// is left intact to avoid breaking block-compression or
@@ -2221,8 +2339,9 @@ class Article {
'ar_text_id' => 'rev_text_id',
'ar_text' => '\'\'', // Be explicit to appease
'ar_flags' => '\'\'', // MySQL's "strict mode"...
- 'ar_len' => 'rev_len',
+ 'ar_len' => 'rev_len',
'ar_page_id' => 'page_id',
+ 'ar_deleted' => $bitfield
), array(
'page_id' => $id,
'page_id = rev_page'
@@ -2232,12 +2351,25 @@ class Article {
# Delete restrictions for it
$dbw->delete( 'page_restrictions', array ( 'pr_page' => $id ), __METHOD__ );
+ # Fix category table counts
+ $cats = array();
+ $res = $dbw->select( 'categorylinks', 'cl_to',
+ array( 'cl_from' => $id ), __METHOD__ );
+ foreach( $res as $row ) {
+ $cats []= $row->cl_to;
+ }
+ $this->updateCategoryCounts( array(), $cats );
+
# Now that it's safely backed up, delete it
$dbw->delete( 'page', array( 'page_id' => $id ), __METHOD__);
+ $ok = ( $dbw->affectedRows() > 0 ); // getArticleId() uses slave, could be laggy
+ if( !$ok ) {
+ $dbw->rollback();
+ return false;
+ }
# If using cascading deletes, we can skip some explicit deletes
if ( !$dbw->cascadingDeletes() ) {
-
$dbw->delete( 'revision', array( 'rev_page' => $id ), __METHOD__ );
if ($wgUseTrackbacks)
@@ -2257,19 +2389,26 @@ class Article {
if ( !$dbw->cleanupTriggers() ) {
# Clean up recentchanges entries...
- $dbw->delete( 'recentchanges', array( 'rc_namespace' => $ns, 'rc_title' => $t ), __METHOD__ );
+ $dbw->delete( 'recentchanges',
+ array( 'rc_namespace' => $ns, 'rc_title' => $t, 'rc_type != '.RC_LOG ),
+ __METHOD__ );
}
+ $dbw->commit();
# Clear caches
Article::onArticleDelete( $this->mTitle );
- # Log the deletion
- $log = new LogPage( 'delete' );
- $log->addEntry( 'delete', $this->mTitle, $reason );
-
# Clear the cached article id so the interface doesn't act like we exist
$this->mTitle->resetArticleID( 0 );
$this->mTitle->mArticleID = 0;
+
+ # Log the deletion, if the page was suppressed, log it at Oversight instead
+ $logtype = $suppress ? 'suppress' : 'delete';
+ $log = new LogPage( $logtype );
+
+ # Make sure logging got through
+ $log->addEntry( 'delete', $this->mTitle, $reason, array() );
+
return true;
}
@@ -2280,15 +2419,15 @@ class Article {
* performs permissions checks on $wgUser, then calls commitRollback()
* to do the dirty work
*
- * @param string $fromP - Name of the user whose edits to rollback.
+ * @param string $fromP - Name of the user whose edits to rollback.
* @param string $summary - Custom summary. Set to default summary if empty.
* @param string $token - Rollback token.
* @param bool $bot - If true, mark all reverted edits as bot.
- *
+ *
* @param array $resultDetails contains result-specific array of additional values
* 'alreadyrolled' : 'current' (rev)
* success : 'summary' (str), 'current' (rev), 'target' (rev)
- *
+ *
* @return array of errors, each error formatted as
* array(messagekey, param1, param2, ...).
* On success, the array is empty. This array can also be passed to
@@ -2310,10 +2449,10 @@ class Article {
# If there were errors, bail out now
if(!empty($errors))
return $errors;
-
+
return $this->commitRollback($fromP, $summary, $bot, $resultDetails);
}
-
+
/**
* Backend implementation of doRollback(), please refer there for parameter
* and return value documentation
@@ -2322,9 +2461,9 @@ class Article {
* rollback to the DB Therefore, you should only call this function direct-
* ly if you want to use custom permissions checks. If you don't, use
* doRollback() instead.
- */
+ */
public function commitRollback($fromP, $summary, $bot, &$resultDetails) {
- global $wgUseRCPatrol, $wgUser;
+ global $wgUseRCPatrol, $wgUser, $wgLang;
$dbw = wfGetDB( DB_MASTER );
if( wfReadOnly() ) {
@@ -2352,7 +2491,7 @@ class Article {
$user = intval( $current->getUser() );
$user_text = $dbw->addQuotes( $current->getUserText() );
$s = $dbw->selectRow( 'revision',
- array( 'rev_id', 'rev_timestamp' ),
+ array( 'rev_id', 'rev_timestamp', 'rev_deleted' ),
array( 'rev_page' => $current->getPage(),
"rev_user <> {$user} OR rev_user_text <> {$user_text}"
), __METHOD__,
@@ -2362,8 +2501,11 @@ class Article {
if( $s === false ) {
# No one else ever edited this page
return array(array('cantrollback'));
+ } else if( $s->rev_deleted & REVISION::DELETED_TEXT || $s->rev_deleted & REVISION::DELETED_USER ) {
+ # Only admins can see this text
+ return array(array('notvisiblerev'));
}
-
+
$set = array();
if ( $bot && $wgUser->isAllowed('markbotedits') ) {
# Mark all reverted edits as bot
@@ -2386,15 +2528,17 @@ class Article {
# Generate the edit summary if necessary
$target = Revision::newFromId( $s->rev_id );
- if( empty( $summary ) )
- {
- global $wgLang;
- $summary = wfMsgForContent( 'revertpage',
- $target->getUserText(), $from,
- $s->rev_id, $wgLang->timeanddate(wfTimestamp(TS_MW, $s->rev_timestamp), true),
- $current->getId(), $wgLang->timeanddate($current->getTimestamp())
- );
+ if( empty( $summary ) ){
+ $summary = wfMsgForContent( 'revertpage' );
}
+
+ # Allow the custom summary to use the same args as the default message
+ $args = array(
+ $target->getUserText(), $from, $s->rev_id,
+ $wgLang->timeanddate(wfTimestamp(TS_MW, $s->rev_timestamp), true),
+ $current->getId(), $wgLang->timeanddate($current->getTimestamp())
+ );
+ $summary = wfMsgReplaceArgs( $summary, $args );
# Save
$flags = EDIT_UPDATE;
@@ -2404,7 +2548,7 @@ class Article {
if( $bot && ($wgUser->isAllowed('markbotedits') || $wgUser->isAllowed('bot')) )
$flags |= EDIT_FORCE_BOT;
- $this->doEdit( $target->getText(), $summary, $flags );
+ $this->doEdit( $target->getText(), $summary, $flags, $target->getId() );
wfRunHooks( 'ArticleRollbackComplete', array( $this, $wgUser, $target ) );
@@ -2439,6 +2583,19 @@ class Article {
$wgOut->rateLimited();
return;
}
+ if( isset( $result[0][0] ) && ( $result[0][0] == 'alreadyrolled' || $result[0][0] == 'cantrollback' ) ){
+ $wgOut->setPageTitle( wfMsg( 'rollbackfailed' ) );
+ $errArray = $result[0];
+ $errMsg = array_shift( $errArray );
+ $wgOut->addWikiMsgArray( $errMsg, $errArray );
+ if( isset( $details['current'] ) ){
+ $current = $details['current'];
+ if( $current->getComment() != '' ) {
+ $wgOut->addWikiMsgArray( 'editcomment', array( $wgUser->getSkin()->formatComment( $current->getComment() ) ), array( 'replaceafter' ) );
+ }
+ }
+ return;
+ }
# Display permissions errors before read-only message -- there's no
# point in misleading the user into thinking the inability to rollback
# is only temporary.
@@ -2469,6 +2626,11 @@ class Article {
. $wgUser->getSkin()->userToolLinks( $target->getUser(), $target->getUserText() );
$wgOut->addHtml( wfMsgExt( 'rollback-success', array( 'parse', 'replaceafter' ), $old, $new ) );
$wgOut->returnToMain( false, $this->mTitle );
+
+ if( !$wgRequest->getBool( 'hidediff', false ) ) {
+ $de = new DifferenceEngine( $this->mTitle, $current->getId(), 'next', false, true );
+ $de->showDiff( '', '' );
+ }
}
@@ -2477,11 +2639,12 @@ class Article {
* @private
*/
function viewUpdates() {
- global $wgDeferredUpdateList;
+ global $wgDeferredUpdateList, $wgUser;
if ( 0 != $this->getID() ) {
+ # Don't update page view counters on views from bot users (bug 14044)
global $wgDisableCounters;
- if( !$wgDisableCounters ) {
+ if( !$wgDisableCounters && !$wgUser->isAllowed( 'bot' ) ) {
Article::incViewCount( $this->getID() );
$u = new SiteStatsUpdate( 1, 0, 0 );
array_push( $wgDeferredUpdateList, $u );
@@ -2489,7 +2652,6 @@ class Article {
}
# Update newtalk / watchlist notification status
- global $wgUser;
$wgUser->clearNotification( $this->mTitle );
}
@@ -2546,7 +2708,7 @@ class Article {
# Save it to the parser cache
if ( $wgEnableParserCache ) {
- $parserCache =& ParserCache::singleton();
+ $parserCache = ParserCache::singleton();
$parserCache->save( $editInfo->output, $this, $wgUser );
}
@@ -2646,7 +2808,7 @@ class Article {
$sk = $wgUser->getSkin();
$lnk = $current
? wfMsg( 'currentrevisionlink' )
- : $lnk = $sk->makeKnownLinkObj( $this->mTitle, wfMsg( 'currentrevisionlink' ) );
+ : $sk->makeKnownLinkObj( $this->mTitle, wfMsg( 'currentrevisionlink' ) );
$curdiff = $current
? wfMsg( 'diff' )
: $sk->makeKnownLinkObj( $this->mTitle, wfMsg( 'diff' ), 'diff=cur&oldid='.$oldid );
@@ -2664,16 +2826,38 @@ class Article {
? wfMsg( 'diff' )
: $sk->makeKnownLinkObj( $this->mTitle, wfMsg( 'diff' ), 'diff=next&oldid='.$oldid );
- $userlinks = $sk->userLink( $revision->getUser(), $revision->getUserText() )
- . $sk->userToolLinks( $revision->getUser(), $revision->getUserText() );
+ $cdel='';
+ if( $wgUser->isAllowed( 'deleterevision' ) ) {
+ $revdel = SpecialPage::getTitleFor( 'Revisiondelete' );
+ if( $revision->isCurrent() ) {
+ // We don't handle top deleted edits too well
+ $cdel = wfMsgHtml('rev-delundel');
+ } else if( !$revision->userCan( Revision::DELETED_RESTRICTED ) ) {
+ // If revision was hidden from sysops
+ $cdel = wfMsgHtml('rev-delundel');
+ } else {
+ $cdel = $sk->makeKnownLinkObj( $revdel,
+ wfMsgHtml('rev-delundel'),
+ 'target=' . urlencode( $this->mTitle->getPrefixedDbkey() ) .
+ '&oldid=' . urlencode( $oldid ) );
+ // Bolden oversighted content
+ if( $revision->isDeleted( Revision::DELETED_RESTRICTED ) )
+ $cdel = "<strong>$cdel</strong>";
+ }
+ $cdel = "(<small>$cdel</small>) ";
+ }
+ # Show user links if allowed to see them. Normally they
+ # are hidden regardless, but since we can already see the text here...
+ $userlinks = $sk->revUserTools( $revision, false );
$m = wfMsg( 'revision-info-current' );
$infomsg = $current && !wfEmptyMsg( 'revision-info-current', $m ) && $m != '-'
? 'revision-info-current'
: 'revision-info';
-
+
$r = "\n\t\t\t\t<div id=\"mw-{$infomsg}\">" . wfMsg( $infomsg, $td, $userlinks ) . "</div>\n" .
- "\n\t\t\t\t<div id=\"mw-revision-nav\">" . wfMsg( 'revision-nav', $prevdiff, $prevlink, $lnk, $curdiff, $nextlink, $nextdiff ) . "</div>\n\t\t\t";
+
+ "\n\t\t\t\t<div id=\"mw-revision-nav\">" . $cdel . wfMsg( 'revision-nav', $prevdiff, $prevlink, $lnk, $curdiff, $nextlink, $nextdiff ) . "</div>\n\t\t\t";
$wgOut->setSubtitle( $r );
}
@@ -2731,9 +2915,9 @@ class Article {
$printable = $wgRequest->getVal( 'printable' );
$page = $wgRequest->getVal( 'page' );
- //check for non-standard user language; this covers uselang,
+ //check for non-standard user language; this covers uselang,
//and extensions for auto-detecting user language.
- $ulang = $wgLang->getCode();
+ $ulang = $wgLang->getCode();
$clang = $wgContLang->getCode();
$cacheable = $wgUseFileCache
@@ -2814,6 +2998,8 @@ class Article {
$revision->insertOn( $dbw );
$this->updateRevisionOn( $dbw, $revision );
$dbw->commit();
+
+ wfRunHooks( 'NewRevisionFromEditComplete', array($this, $revision, false) );
wfProfileOut( __METHOD__ );
}
@@ -2911,6 +3097,15 @@ class Article {
static function onArticleDelete( $title ) {
global $wgUseFileCache, $wgMessageCache;
+ // Update existence markers on article/talk tabs...
+ if( $title->isTalkPage() ) {
+ $other = $title->getSubjectPage();
+ } else {
+ $other = $title->getTalkPage();
+ }
+ $other->invalidateCache();
+ $other->purgeSquid();
+
$title->touchLinks();
$title->purgeSquid();
@@ -2920,13 +3115,20 @@ class Article {
@unlink( $cm->fileCacheName() );
}
- if( $title->getNamespace() == NS_MEDIAWIKI) {
+ # Messages
+ if( $title->getNamespace() == NS_MEDIAWIKI ) {
$wgMessageCache->replace( $title->getDBkey(), false );
}
+ # Images
if( $title->getNamespace() == NS_IMAGE ) {
$update = new HTMLCacheUpdate( $title, 'imagelinks' );
$update->doUpdate();
}
+ # User talk pages
+ if( $title->getNamespace() == NS_USER_TALK ) {
+ $user = User::newFromName( $title->getText(), false );
+ $user->setNewtalk( false );
+ }
}
/**
@@ -2940,7 +3142,7 @@ class Article {
// Invalidate the caches of all pages which redirect here
$wgDeferredUpdateList[] = new HTMLCacheUpdate( $title, 'redirect' );
-
+
# Purge squid for this page only
$title->purgeSquid();
@@ -2954,6 +3156,15 @@ class Article {
/**#@-*/
/**
+ * Overriden by ImagePage class, only present here to avoid a fatal error
+ * Called for ?action=revert
+ */
+ public function revert(){
+ global $wgOut;
+ $wgOut->showErrorPage( 'nosuchaction', 'nosuchactiontext' );
+ }
+
+ /**
* Info about this page
* Called for ?action=info when $wgAllowPageInfo is on.
*
@@ -3080,38 +3291,33 @@ class Article {
}
/**
- * Return an auto-generated summary if the text provided is a redirect.
+ * Returns a list of hidden categories this page is a member of.
+ * Uses the page_props and categorylinks tables.
*
- * @param string $text The wikitext to check
- * @return string '' or an appropriate summary
+ * @return array Array of Title objects
*/
- public static function getRedirectAutosummary( $text ) {
- $rt = Title::newFromRedirect( $text );
- if( is_object( $rt ) )
- return wfMsgForContent( 'autoredircomment', $rt->getFullText() );
- else
- return '';
- }
+ function getHiddenCategories() {
+ $result = array();
+ $id = $this->mTitle->getArticleID();
+ if( $id == 0 ) {
+ return array();
+ }
- /**
- * Return an auto-generated summary if the new text is much shorter than
- * the old text.
- *
- * @param string $oldtext The previous text of the page
- * @param string $text The submitted text of the page
- * @return string An appropriate autosummary, or an empty string.
- */
- public static function getBlankingAutosummary( $oldtext, $text ) {
- if ($oldtext!='' && $text=='') {
- return wfMsgForContent('autosumm-blank');
- } elseif (strlen($oldtext) > 10 * strlen($text) && strlen($text) < 500) {
- #Removing more than 90% of the article
- global $wgContLang;
- $truncatedtext = $wgContLang->truncate($text, max(0, 200 - strlen(wfMsgForContent('autosumm-replace'))), '...');
- return wfMsgForContent('autosumm-replace', $truncatedtext);
- } else {
- return '';
+ $dbr = wfGetDB( DB_SLAVE );
+ $res = $dbr->select( array( 'categorylinks', 'page_props', 'page' ),
+ array( 'cl_to' ),
+ array( 'cl_from' => $id, 'pp_page=page_id', 'pp_propname' => 'hiddencat',
+ 'page_namespace' => NS_CATEGORY, 'page_title=cl_to'),
+ 'Article:getHiddenCategories' );
+ if ( false !== $res ) {
+ if ( $dbr->numRows( $res ) ) {
+ while ( $row = $dbr->fetchObject( $res ) ) {
+ $result[] = Title::makeTitle( NS_CATEGORY, $row->cl_to );
+ }
+ }
}
+ $dbr->freeResult( $res );
+ return $result;
}
/**
@@ -3122,38 +3328,42 @@ class Article {
* @return string An appropriate autosummary, or an empty string.
*/
public static function getAutosummary( $oldtext, $newtext, $flags ) {
+ # Decide what kind of autosummary is needed.
- # This code is UGLY UGLY UGLY.
- # Somebody PLEASE come up with a more elegant way to do it.
-
- #Redirect autosummaries
- $summary = self::getRedirectAutosummary( $newtext );
-
- if ($summary)
- return $summary;
-
- #Blanking autosummaries
- if (!($flags & EDIT_NEW))
- $summary = self::getBlankingAutosummary( $oldtext, $newtext );
-
- if ($summary)
- return $summary;
+ # Redirect autosummaries
+ $rt = Title::newFromRedirect( $newtext );
+ if( is_object( $rt ) ) {
+ return wfMsgForContent( 'autoredircomment', $rt->getFullText() );
+ }
- #New page autosummaries
- if ($flags & EDIT_NEW && strlen($newtext)) {
- #If they're making a new article, give its text, truncated, in the summary.
+ # New page autosummaries
+ if( $flags & EDIT_NEW && strlen( $newtext ) ) {
+ # If they're making a new article, give its text, truncated, in the summary.
global $wgContLang;
$truncatedtext = $wgContLang->truncate(
str_replace("\n", ' ', $newtext),
max( 0, 200 - strlen( wfMsgForContent( 'autosumm-new') ) ),
'...' );
- $summary = wfMsgForContent( 'autosumm-new', $truncatedtext );
+ return wfMsgForContent( 'autosumm-new', $truncatedtext );
}
- if ($summary)
- return $summary;
+ # Blanking autosummaries
+ if( $oldtext != '' && $newtext == '' ) {
+ return wfMsgForContent('autosumm-blank');
+ } elseif( strlen( $oldtext ) > 10 * strlen( $newtext ) && strlen( $newtext ) < 500) {
+ # Removing more than 90% of the article
+ global $wgContLang;
+ $truncatedtext = $wgContLang->truncate(
+ $newtext,
+ max( 0, 200 - strlen( wfMsgForContent( 'autosumm-replace' ) ) ),
+ '...'
+ );
+ return wfMsgForContent( 'autosumm-replace', $truncatedtext );
+ }
- return $summary;
+ # If we reach this point, there's no applicable autosummary for our case, so our
+ # autosummary is empty.
+ return '';
}
/**
@@ -3175,7 +3385,7 @@ class Article {
$popts->setTidy(false);
$popts->enableLimitReport( false );
if ( $wgEnableParserCache && $cache && $this && $parserOutput->getCacheTime() != -1 ) {
- $parserCache =& ParserCache::singleton();
+ $parserCache = ParserCache::singleton();
$parserCache->save( $parserOutput, $this, $wgUser );
}
@@ -3235,4 +3445,60 @@ class Article {
$wgOut->addParserOutput( $parserOutput );
}
+ /**
+ * Update all the appropriate counts in the category table, given that
+ * we've added the categories $added and deleted the categories $deleted.
+ *
+ * @param $added array The names of categories that were added
+ * @param $deleted array The names of categories that were deleted
+ * @return null
+ */
+ public function updateCategoryCounts( $added, $deleted ) {
+ $ns = $this->mTitle->getNamespace();
+ $dbw = wfGetDB( DB_MASTER );
+
+ # First make sure the rows exist. If one of the "deleted" ones didn't
+ # exist, we might legitimately not create it, but it's simpler to just
+ # create it and then give it a negative value, since the value is bogus
+ # anyway.
+ #
+ # Sometimes I wish we had INSERT ... ON DUPLICATE KEY UPDATE.
+ $insertCats = array_merge( $added, $deleted );
+ if( !$insertCats ) {
+ # Okay, nothing to do
+ return;
+ }
+ $insertRows = array();
+ foreach( $insertCats as $cat ) {
+ $insertRows[] = array( 'cat_title' => $cat );
+ }
+ $dbw->insert( 'category', $insertRows, __METHOD__, 'IGNORE' );
+
+ $addFields = array( 'cat_pages = cat_pages + 1' );
+ $removeFields = array( 'cat_pages = cat_pages - 1' );
+ if( $ns == NS_CATEGORY ) {
+ $addFields[] = 'cat_subcats = cat_subcats + 1';
+ $removeFields[] = 'cat_subcats = cat_subcats - 1';
+ } elseif( $ns == NS_IMAGE ) {
+ $addFields[] = 'cat_files = cat_files + 1';
+ $removeFields[] = 'cat_files = cat_files - 1';
+ }
+
+ if ( $added ) {
+ $dbw->update(
+ 'category',
+ $addFields,
+ array( 'cat_title' => $added ),
+ __METHOD__
+ );
+ }
+ if ( $deleted ) {
+ $dbw->update(
+ 'category',
+ $removeFields,
+ array( 'cat_title' => $deleted ),
+ __METHOD__
+ );
+ }
+ }
}
diff --git a/includes/AuthPlugin.php b/includes/AuthPlugin.php
index 2ad137e2..7717e001 100644
--- a/includes/AuthPlugin.php
+++ b/includes/AuthPlugin.php
@@ -230,7 +230,7 @@ class AuthPlugin {
* @param $autocreate bool True if user is being autocreated on login
* @public
*/
- function initUser( $user, $autocreate=false ) {
+ function initUser( &$user, $autocreate=false ) {
# Override this to do something.
}
@@ -242,5 +242,3 @@ class AuthPlugin {
return $username;
}
}
-
-
diff --git a/includes/AutoLoader.php b/includes/AutoLoader.php
index 2e2083b2..4f36784a 100644
--- a/includes/AutoLoader.php
+++ b/includes/AutoLoader.php
@@ -4,352 +4,265 @@
ini_set('unserialize_callback_func', '__autoload' );
-function __autoload($className) {
- global $wgAutoloadClasses;
-
+class AutoLoader {
# Locations of core classes
# Extension classes are specified with $wgAutoloadClasses
static $localClasses = array(
# Includes
'AjaxDispatcher' => 'includes/AjaxDispatcher.php',
- 'AjaxCachePolicy' => 'includes/AjaxFunctions.php',
'AjaxResponse' => 'includes/AjaxResponse.php',
'AlphabeticPager' => 'includes/Pager.php',
+ 'APCBagOStuff' => 'includes/BagOStuff.php',
+ 'ArrayDiffFormatter' => 'includes/DifferenceEngine.php',
'Article' => 'includes/Article.php',
+ 'AtomFeed' => 'includes/Feed.php',
'AuthPlugin' => 'includes/AuthPlugin.php',
'Autopromote' => 'includes/Autopromote.php',
'BagOStuff' => 'includes/BagOStuff.php',
- 'HashBagOStuff' => 'includes/BagOStuff.php',
- 'SqlBagOStuff' => 'includes/BagOStuff.php',
- 'MediaWikiBagOStuff' => 'includes/BagOStuff.php',
- 'TurckBagOStuff' => 'includes/BagOStuff.php',
- 'APCBagOStuff' => 'includes/BagOStuff.php',
- 'eAccelBagOStuff' => 'includes/BagOStuff.php',
- 'XCacheBagOStuff' => 'includes/BagOStuff.php',
- 'DBABagOStuff' => 'includes/BagOStuff.php',
'Block' => 'includes/Block.php',
- 'HTMLFileCache' => 'includes/HTMLFileCache.php',
- 'DependencyWrapper' => 'includes/CacheDependency.php',
- 'FileDependency' => 'includes/CacheDependency.php',
- 'TitleDependency' => 'includes/CacheDependency.php',
- 'TitleListDependency' => 'includes/CacheDependency.php',
+ 'CacheDependency' => 'includes/CacheDependency.php',
+ 'Category' => 'includes/Category.php',
+ 'Categoryfinder' => 'includes/Categoryfinder.php',
'CategoryPage' => 'includes/CategoryPage.php',
'CategoryViewer' => 'includes/CategoryPage.php',
- 'Categoryfinder' => 'includes/Categoryfinder.php',
- 'RCCacheEntry' => 'includes/ChangesList.php',
'ChangesList' => 'includes/ChangesList.php',
- 'OldChangesList' => 'includes/ChangesList.php',
- 'EnhancedChangesList' => 'includes/ChangesList.php',
- 'CoreParserFunctions' => 'includes/CoreParserFunctions.php',
- 'DBObject' => 'includes/Database.php',
- 'Database' => 'includes/Database.php',
- 'DatabaseMysql' => 'includes/Database.php',
- 'ResultWrapper' => 'includes/Database.php',
- 'DatabasePostgres' => 'includes/DatabasePostgres.php',
- 'DatabaseOracle' => 'includes/DatabaseOracle.php',
- 'DateFormatter' => 'includes/DateFormatter.php',
+ 'ChangesFeed' => 'includes/ChangesFeed.php',
+ 'ChannelFeed' => 'includes/Feed.php',
+ 'ConcatenatedGzipHistoryBlob' => 'includes/HistoryBlob.php',
+ 'ConstantDependency' => 'includes/CacheDependency.php',
+ 'DBABagOStuff' => 'includes/BagOStuff.php',
+ 'DependencyWrapper' => 'includes/CacheDependency.php',
+ '_DiffEngine' => 'includes/DifferenceEngine.php',
'DifferenceEngine' => 'includes/DifferenceEngine.php',
- '_DiffOp' => 'includes/DifferenceEngine.php',
- '_DiffOp_Copy' => 'includes/DifferenceEngine.php',
- '_DiffOp_Delete' => 'includes/DifferenceEngine.php',
+ 'DiffFormatter' => 'includes/DifferenceEngine.php',
+ 'Diff' => 'includes/DifferenceEngine.php',
'_DiffOp_Add' => 'includes/DifferenceEngine.php',
'_DiffOp_Change' => 'includes/DifferenceEngine.php',
- '_DiffEngine' => 'includes/DifferenceEngine.php',
- 'Diff' => 'includes/DifferenceEngine.php',
- 'MappedDiff' => 'includes/DifferenceEngine.php',
- 'DiffFormatter' => 'includes/DifferenceEngine.php',
- 'UnifiedDiffFormatter' => 'includes/DifferenceEngine.php',
- 'ArrayDiffFormatter' => 'includes/DifferenceEngine.php',
+ '_DiffOp_Copy' => 'includes/DifferenceEngine.php',
+ '_DiffOp_Delete' => 'includes/DifferenceEngine.php',
+ '_DiffOp' => 'includes/DifferenceEngine.php',
'DjVuImage' => 'includes/DjVuImage.php',
- '_HWLDF_WordAccumulator' => 'includes/DifferenceEngine.php',
- 'WordLevelDiff' => 'includes/DifferenceEngine.php',
- 'TableDiffFormatter' => 'includes/DifferenceEngine.php',
- 'EditPage' => 'includes/EditPage.php',
- 'MWException' => 'includes/Exception.php',
- 'Exif' => 'includes/Exif.php',
- 'FormatExif' => 'includes/Exif.php',
- 'WikiExporter' => 'includes/Export.php',
- 'XmlDumpWriter' => 'includes/Export.php',
- 'DumpOutput' => 'includes/Export.php',
- 'DumpFileOutput' => 'includes/Export.php',
- 'DumpPipeOutput' => 'includes/Export.php',
- 'DumpGZipOutput' => 'includes/Export.php',
- 'DumpBZip2Output' => 'includes/Export.php',
+ 'DoubleReplacer' => 'includes/StringUtils.php',
+ 'DoubleRedirectJob' => 'includes/DoubleRedirectJob.php',
'Dump7ZipOutput' => 'includes/Export.php',
+ 'DumpBZip2Output' => 'includes/Export.php',
+ 'DumpFileOutput' => 'includes/Export.php',
'DumpFilter' => 'includes/Export.php',
- 'DumpNotalkFilter' => 'includes/Export.php',
- 'DumpNamespaceFilter' => 'includes/Export.php',
+ 'DumpGZipOutput' => 'includes/Export.php',
'DumpLatestFilter' => 'includes/Export.php',
'DumpMultiWriter' => 'includes/Export.php',
+ 'DumpNamespaceFilter' => 'includes/Export.php',
+ 'DumpNotalkFilter' => 'includes/Export.php',
+ 'DumpOutput' => 'includes/Export.php',
+ 'DumpPipeOutput' => 'includes/Export.php',
+ 'eAccelBagOStuff' => 'includes/BagOStuff.php',
+ 'EditPage' => 'includes/EditPage.php',
+ 'EmaillingJob' => 'includes/EmaillingJob.php',
+ 'EmailNotification' => 'includes/UserMailer.php',
+ 'EnhancedChangesList' => 'includes/ChangesList.php',
+ 'EnotifNotifyJob' => 'includes/EnotifNotifyJob.php',
+ 'ErrorPageError' => 'includes/Exception.php',
+ 'Exif' => 'includes/Exif.php',
'ExternalEdit' => 'includes/ExternalEdit.php',
- 'ExternalStore' => 'includes/ExternalStore.php',
'ExternalStoreDB' => 'includes/ExternalStoreDB.php',
'ExternalStoreHttp' => 'includes/ExternalStoreHttp.php',
+ 'ExternalStore' => 'includes/ExternalStore.php',
+ 'FatalError' => 'includes/Exception.php',
'FakeTitle' => 'includes/FakeTitle.php',
+ 'FauxRequest' => 'includes/WebRequest.php',
'FeedItem' => 'includes/Feed.php',
- 'ChannelFeed' => 'includes/Feed.php',
- 'RSSFeed' => 'includes/Feed.php',
- 'AtomFeed' => 'includes/Feed.php',
+ 'FeedUtils' => 'includes/FeedUtils.php',
+ 'FileDeleteForm' => 'includes/FileDeleteForm.php',
+ 'FileDependency' => 'includes/CacheDependency.php',
+ 'FileRevertForm' => 'includes/FileRevertForm.php',
'FileStore' => 'includes/FileStore.php',
+ 'FormatExif' => 'includes/Exif.php',
+ 'FormOptions' => 'includes/FormOptions.php',
'FSException' => 'includes/FileStore.php',
'FSTransaction' => 'includes/FileStore.php',
+ 'GlobalDependency' => 'includes/CacheDependency.php',
+ 'HashBagOStuff' => 'includes/BagOStuff.php',
+ 'HashtableReplacer' => 'includes/StringUtils.php',
+ 'HistoryBlobCurStub' => 'includes/HistoryBlob.php',
'HistoryBlob' => 'includes/HistoryBlob.php',
- 'ConcatenatedGzipHistoryBlob' => 'includes/HistoryBlob.php',
'HistoryBlobStub' => 'includes/HistoryBlob.php',
- 'HistoryBlobCurStub' => 'includes/HistoryBlob.php',
'HTMLCacheUpdate' => 'includes/HTMLCacheUpdate.php',
+ 'HTMLCacheUpdateJob' => 'includes/HTMLCacheUpdate.php',
+ 'HTMLFileCache' => 'includes/HTMLFileCache.php',
'Http' => 'includes/HttpFunctions.php',
- 'IP' => 'includes/IP.php',
+ '_HWLDF_WordAccumulator' => 'includes/DifferenceEngine.php',
'ImageGallery' => 'includes/ImageGallery.php',
- 'ImagePage' => 'includes/ImagePage.php',
'ImageHistoryList' => 'includes/ImagePage.php',
- 'FileDeleteForm' => 'includes/FileDeleteForm.php',
- 'FileRevertForm' => 'includes/FileRevertForm.php',
+ 'ImagePage' => 'includes/ImagePage.php',
+ 'ImageQueryPage' => 'includes/ImageQueryPage.php',
+ 'IncludableSpecialPage' => 'includes/SpecialPage.php',
+ 'IndexPager' => 'includes/Pager.php',
+ 'IP' => 'includes/IP.php',
'Job' => 'includes/JobQueue.php',
- 'EmaillingJob' => 'includes/EmaillingJob.php',
- 'EnotifNotifyJob' => 'includes/EnotifNotifyJob.php',
- 'HTMLCacheUpdateJob' => 'includes/HTMLCacheUpdate.php',
- 'RefreshLinksJob' => 'includes/RefreshLinksJob.php',
- 'Licenses' => 'includes/Licenses.php',
'License' => 'includes/Licenses.php',
+ 'Licenses' => 'includes/Licenses.php',
'LinkBatch' => 'includes/LinkBatch.php',
'LinkCache' => 'includes/LinkCache.php',
- 'LinkFilter' => 'includes/LinkFilter.php',
'Linker' => 'includes/Linker.php',
+ 'LinkFilter' => 'includes/LinkFilter.php',
'LinksUpdate' => 'includes/LinksUpdate.php',
- 'LoadBalancer' => 'includes/LoadBalancer.php',
'LogPage' => 'includes/LogPage.php',
+ 'LogPager' => 'includes/LogEventsList.php',
+ 'LogEventsList' => 'includes/LogEventsList.php',
+ 'LogReader' => 'includes/LogEventsList.php',
+ 'LogViewer' => 'includes/LogEventsList.php',
'MacBinary' => 'includes/MacBinary.php',
- 'MagicWord' => 'includes/MagicWord.php',
'MagicWordArray' => 'includes/MagicWord.php',
+ 'MagicWord' => 'includes/MagicWord.php',
+ 'MailAddress' => 'includes/UserMailer.php',
+ 'MappedDiff' => 'includes/DifferenceEngine.php',
'MathRenderer' => 'includes/Math.php',
- 'MediaTransformOutput' => 'includes/MediaTransformOutput.php',
- 'ThumbnailImage' => 'includes/MediaTransformOutput.php',
'MediaTransformError' => 'includes/MediaTransformOutput.php',
- 'TransformParameterError' => 'includes/MediaTransformOutput.php',
+ 'MediaTransformOutput' => 'includes/MediaTransformOutput.php',
+ 'MediaWikiBagOStuff' => 'includes/BagOStuff.php',
+ 'MediaWiki_I18N' => 'includes/SkinTemplate.php',
+ 'MediaWiki' => 'includes/Wiki.php',
+ 'memcached' => 'includes/memcached-client.php',
'MessageCache' => 'includes/MessageCache.php',
'MimeMagic' => 'includes/MimeMagic.php',
- 'Namespace' => 'includes/Namespace.php',
- 'FakeMemCachedClient' => 'includes/ObjectCache.php',
+ 'MWException' => 'includes/Exception.php',
+ 'MWNamespace' => 'includes/Namespace.php',
+ 'MySQLSearchResultSet' => 'includes/SearchMySQL.php',
+ 'Namespace' => 'includes/NamespaceCompat.php', // Compat
+ 'OldChangesList' => 'includes/ChangesList.php',
+ 'OracleSearchResultSet' => 'includes/SearchOracle.php',
'OutputPage' => 'includes/OutputPage.php',
'PageHistory' => 'includes/PageHistory.php',
- 'IndexPager' => 'includes/Pager.php',
- 'ReverseChronologicalPager' => 'includes/Pager.php',
- 'TablePager' => 'includes/Pager.php',
- 'Parser' => 'includes/Parser.php',
- 'Parser_OldPP' => 'includes/Parser_OldPP.php',
- 'Parser_DiffTest' => 'includes/Parser_DiffTest.php',
- 'ParserCache' => 'includes/ParserCache.php',
- 'ParserOutput' => 'includes/ParserOutput.php',
- 'ParserOptions' => 'includes/ParserOptions.php',
+ 'PageHistoryPager' => 'includes/PageHistory.php',
+ 'PageQueryPage' => 'includes/PageQueryPage.php',
+ 'Pager' => 'includes/Pager.php',
+ 'PasswordError' => 'includes/User.php',
'PatrolLog' => 'includes/PatrolLog.php',
- 'Preprocessor' => 'includes/Preprocessor.php',
+ 'PostgresSearchResult' => 'includes/SearchPostgres.php',
+ 'PostgresSearchResultSet' => 'includes/SearchPostgres.php',
'PrefixSearch' => 'includes/PrefixSearch.php',
- 'PPFrame' => 'includes/Preprocessor.php',
- 'PPNode' => 'includes/Preprocessor.php',
- 'Preprocessor_DOM' => 'includes/Preprocessor_DOM.php',
- 'PPFrame_DOM' => 'includes/Preprocessor_DOM.php',
- 'PPTemplateFrame_DOM' => 'includes/Preprocessor_DOM.php',
- 'PPDStack' => 'includes/Preprocessor_DOM.php',
- 'PPDStackElement' => 'includes/Preprocessor_DOM.php',
- 'PPNode_DOM' => 'includes/Preprocessor_DOM.php',
- 'Preprocessor_Hash' => 'includes/Preprocessor_Hash.php',
+ 'Profiler' => 'includes/Profiler.php',
'ProfilerSimple' => 'includes/ProfilerSimple.php',
+ 'ProfilerSimpleText' => 'includes/ProfilerSimpleText.php',
'ProfilerSimpleUDP' => 'includes/ProfilerSimpleUDP.php',
- 'Profiler' => 'includes/Profiler.php',
- 'ProxyTools' => 'includes/ProxyTools.php',
'ProtectionForm' => 'includes/ProtectionForm.php',
'QueryPage' => 'includes/QueryPage.php',
- 'PageQueryPage' => 'includes/PageQueryPage.php',
- 'ImageQueryPage' => 'includes/ImageQueryPage.php',
+ 'QuickTemplate' => 'includes/SkinTemplate.php',
'RawPage' => 'includes/RawPage.php',
+ 'RCCacheEntry' => 'includes/ChangesList.php',
'RecentChange' => 'includes/RecentChange.php',
+ 'RefreshLinksJob' => 'includes/RefreshLinksJob.php',
+ 'RegexlikeReplacer' => 'includes/StringUtils.php',
+ 'ReplacementArray' => 'includes/StringUtils.php',
+ 'Replacer' => 'includes/StringUtils.php',
+ 'ReverseChronologicalPager' => 'includes/Pager.php',
'Revision' => 'includes/Revision.php',
+ 'RSSFeed' => 'includes/Feed.php',
'Sanitizer' => 'includes/Sanitizer.php',
- 'SearchEngine' => 'includes/SearchEngine.php',
- 'SearchResultSet' => 'includes/SearchEngine.php',
- 'SearchResult' => 'includes/SearchEngine.php',
'SearchEngineDummy' => 'includes/SearchEngine.php',
- 'SearchMySQL' => 'includes/SearchMySQL.php',
- 'MySQLSearchResultSet' => 'includes/SearchMySQL.php',
+ 'SearchEngine' => 'includes/SearchEngine.php',
+ 'SearchHighlighter' => 'includes/SearchEngine.php',
'SearchMySQL4' => 'includes/SearchMySQL4.php',
+ 'SearchMySQL' => 'includes/SearchMySQL.php',
+ 'SearchOracle' => 'includes/SearchOracle.php',
'SearchPostgres' => 'includes/SearchPostgres.php',
+ 'SearchResult' => 'includes/SearchEngine.php',
+ 'SearchResultSet' => 'includes/SearchEngine.php',
+ 'SearchResultTooMany' => 'includes/SearchEngine.php',
'SearchUpdate' => 'includes/SearchUpdate.php',
'SearchUpdateMyISAM' => 'includes/SearchUpdate.php',
- 'SearchOracle' => 'includes/SearchOracle.php',
'SiteConfiguration' => 'includes/SiteConfiguration.php',
'SiteStats' => 'includes/SiteStats.php',
'SiteStatsUpdate' => 'includes/SiteStats.php',
'Skin' => 'includes/Skin.php',
- 'MediaWiki_I18N' => 'includes/SkinTemplate.php',
'SkinTemplate' => 'includes/SkinTemplate.php',
- 'QuickTemplate' => 'includes/SkinTemplate.php',
- 'SpecialAllpages' => 'includes/SpecialAllpages.php',
- 'AncientPagesPage' => 'includes/SpecialAncientpages.php',
- 'IPBlockForm' => 'includes/SpecialBlockip.php',
- 'SpecialBookSources' => 'includes/SpecialBooksources.php',
- 'BrokenRedirectsPage' => 'includes/SpecialBrokenRedirects.php',
- 'EmailConfirmation' => 'includes/SpecialConfirmemail.php',
- 'ContributionsPage' => 'includes/SpecialContributions.php',
- 'DeadendPagesPage' => 'includes/SpecialDeadendpages.php',
- 'DisambiguationsPage' => 'includes/SpecialDisambiguations.php',
- 'DoubleRedirectsPage' => 'includes/SpecialDoubleRedirects.php',
- 'EmailUserForm' => 'includes/SpecialEmailuser.php',
- 'WikiRevision' => 'includes/SpecialImport.php',
- 'WikiImporter' => 'includes/SpecialImport.php',
- 'ImportStringSource' => 'includes/SpecialImport.php',
- 'ImportStreamSource' => 'includes/SpecialImport.php',
- 'IPUnblockForm' => 'includes/SpecialIpblocklist.php',
- 'ListredirectsPage' => 'includes/SpecialListredirects.php',
- 'DBLockForm' => 'includes/SpecialLockdb.php',
- 'LogReader' => 'includes/SpecialLog.php',
- 'LogViewer' => 'includes/SpecialLog.php',
- 'LonelyPagesPage' => 'includes/SpecialLonelypages.php',
- 'LongPagesPage' => 'includes/SpecialLongpages.php',
- 'MIMEsearchPage' => 'includes/SpecialMIMEsearch.php',
- 'MostcategoriesPage' => 'includes/SpecialMostcategories.php',
- 'MostimagesPage' => 'includes/SpecialMostimages.php',
- 'MostlinkedPage' => 'includes/SpecialMostlinked.php',
- 'MostlinkedCategoriesPage' => 'includes/SpecialMostlinkedcategories.php',
- 'SpecialMostlinkedtemplates' => 'includes/SpecialMostlinkedtemplates.php',
- 'MostrevisionsPage' => 'includes/SpecialMostrevisions.php',
- 'FewestrevisionsPage' => 'includes/SpecialFewestrevisions.php',
- 'MovePageForm' => 'includes/SpecialMovepage.php',
- 'NewbieContributionsPage' => 'includes/SpecialNewbieContributions.php',
- 'NewPagesPage' => 'includes/SpecialNewpages.php',
+ 'SpecialMycontributions' => 'includes/SpecialPage.php',
+ 'SpecialMypage' => 'includes/SpecialPage.php',
+ 'SpecialMytalk' => 'includes/SpecialPage.php',
'SpecialPage' => 'includes/SpecialPage.php',
- 'UnlistedSpecialPage' => 'includes/SpecialPage.php',
- 'IncludableSpecialPage' => 'includes/SpecialPage.php',
- 'PopularPagesPage' => 'includes/SpecialPopularpages.php',
- 'PreferencesForm' => 'includes/SpecialPreferences.php',
- 'SpecialPrefixindex' => 'includes/SpecialPrefixindex.php',
- 'RandomPage' => 'includes/SpecialRandompage.php',
- 'SpecialRandomredirect' => 'includes/SpecialRandomredirect.php',
- 'PasswordResetForm' => 'includes/SpecialResetpass.php',
- 'RevisionDeleteForm' => 'includes/SpecialRevisiondelete.php',
- 'RevisionDeleter' => 'includes/SpecialRevisiondelete.php',
- 'SpecialSearch' => 'includes/SpecialSearch.php',
- 'ShortPagesPage' => 'includes/SpecialShortpages.php',
- 'UncategorizedCategoriesPage' => 'includes/SpecialUncategorizedcategories.php',
- 'UncategorizedPagesPage' => 'includes/SpecialUncategorizedpages.php',
- 'UncategorizedTemplatesPage' => 'includes/SpecialUncategorizedtemplates.php',
- 'PageArchive' => 'includes/SpecialUndelete.php',
- 'UndeleteForm' => 'includes/SpecialUndelete.php',
- 'DBUnlockForm' => 'includes/SpecialUnlockdb.php',
- 'UnusedCategoriesPage' => 'includes/SpecialUnusedcategories.php',
- 'UnusedimagesPage' => 'includes/SpecialUnusedimages.php',
- 'UnusedtemplatesPage' => 'includes/SpecialUnusedtemplates.php',
- 'UnwatchedpagesPage' => 'includes/SpecialUnwatchedpages.php',
- 'UploadForm' => 'includes/SpecialUpload.php',
- 'UploadFormMogile' => 'includes/SpecialUploadMogile.php',
- 'LoginForm' => 'includes/SpecialUserlogin.php',
- 'UserrightsPage' => 'includes/SpecialUserrights.php',
- 'SpecialVersion' => 'includes/SpecialVersion.php',
- 'WantedCategoriesPage' => 'includes/SpecialWantedcategories.php',
- 'WantedPagesPage' => 'includes/SpecialWantedpages.php',
- 'WhatLinksHerePage' => 'includes/SpecialWhatlinkshere.php',
- 'WithoutInterwikiPage' => 'includes/SpecialWithoutinterwiki.php',
+ 'SpecialRedirectToSpecial' => 'includes/SpecialPage.php',
+ 'SqlBagOStuff' => 'includes/BagOStuff.php',
'SquidUpdate' => 'includes/SquidUpdate.php',
- 'ReplacementArray' => 'includes/StringUtils.php',
- 'Replacer' => 'includes/StringUtils.php',
- 'RegexlikeReplacer' => 'includes/StringUtils.php',
- 'DoubleReplacer' => 'includes/StringUtils.php',
- 'HashtableReplacer' => 'includes/StringUtils.php',
+ 'Status' => 'includes/Status.php',
'StringUtils' => 'includes/StringUtils.php',
+ 'TableDiffFormatter' => 'includes/DifferenceEngine.php',
+ 'TablePager' => 'includes/Pager.php',
+ 'ThumbnailImage' => 'includes/MediaTransformOutput.php',
+ 'TitleDependency' => 'includes/CacheDependency.php',
'Title' => 'includes/Title.php',
+ 'TitleListDependency' => 'includes/CacheDependency.php',
+ 'TransformParameterError' => 'includes/MediaTransformOutput.php',
+ 'TurckBagOStuff' => 'includes/BagOStuff.php',
+ 'UnifiedDiffFormatter' => 'includes/DifferenceEngine.php',
+ 'UnlistedSpecialPage' => 'includes/SpecialPage.php',
'User' => 'includes/User.php',
- 'UserRightsProxy' => 'includes/UserRightsProxy.php',
- 'MailAddress' => 'includes/UserMailer.php',
- 'EmailNotification' => 'includes/UserMailer.php',
+ 'UserArray' => 'includes/UserArray.php',
+ 'UserArrayFromResult' => 'includes/UserArray.php',
'UserMailer' => 'includes/UserMailer.php',
+ 'UserRightsProxy' => 'includes/UserRightsProxy.php',
'WatchedItem' => 'includes/WatchedItem.php',
+ 'WatchlistEditor' => 'includes/WatchlistEditor.php',
'WebRequest' => 'includes/WebRequest.php',
'WebResponse' => 'includes/WebResponse.php',
- 'FauxRequest' => 'includes/WebRequest.php',
- 'MediaWiki' => 'includes/Wiki.php',
'WikiError' => 'includes/WikiError.php',
'WikiErrorMsg' => 'includes/WikiError.php',
+ 'WikiExporter' => 'includes/Export.php',
'WikiXmlError' => 'includes/WikiError.php',
+ 'WordLevelDiff' => 'includes/DifferenceEngine.php',
+ 'XCacheBagOStuff' => 'includes/BagOStuff.php',
+ 'XmlDumpWriter' => 'includes/Export.php',
'Xml' => 'includes/Xml.php',
+ 'XmlSelect' => 'includes/Xml.php',
'XmlTypeCheck' => 'includes/XmlTypeCheck.php',
'ZhClient' => 'includes/ZhClient.php',
- 'memcached' => 'includes/memcached-client.php',
- 'EmaillingJob' => 'includes/JobQueue.php',
- 'WatchlistEditor' => 'includes/WatchlistEditor.php',
- # filerepo
- 'ArchivedFile' => 'includes/filerepo/ArchivedFile.php',
- 'File' => 'includes/filerepo/File.php',
- 'FileRepo' => 'includes/filerepo/FileRepo.php',
- 'FileRepoStatus' => 'includes/filerepo/FileRepoStatus.php',
- 'ForeignDBFile' => 'includes/filerepo/ForeignDBFile.php',
- 'ForeignDBRepo' => 'includes/filerepo/ForeignDBRepo.php',
- 'FSRepo' => 'includes/filerepo/FSRepo.php',
- 'Image' => 'includes/filerepo/LocalFile.php',
- 'LocalFile' => 'includes/filerepo/LocalFile.php',
- 'LocalFileDeleteBatch' => 'includes/filerepo/LocalFile.php',
- 'LocalFileRestoreBatch' => 'includes/filerepo/LocalFile.php',
- 'LocalRepo' => 'includes/filerepo/LocalRepo.php',
- 'OldLocalFile' => 'includes/filerepo/OldLocalFile.php',
- 'RepoGroup' => 'includes/filerepo/RepoGroup.php',
- 'UnregisteredLocalFile' => 'includes/filerepo/UnregisteredLocalFile.php',
-
- # Media
- 'BitmapHandler' => 'includes/media/Bitmap.php',
- 'BmpHandler' => 'includes/media/BMP.php',
- 'DjVuHandler' => 'includes/media/DjVu.php',
- 'MediaHandler' => 'includes/media/Generic.php',
- 'ImageHandler' => 'includes/media/Generic.php',
- 'SvgHandler' => 'includes/media/SVG.php',
-
- # Normal
- 'UtfNormal' => 'includes/normal/UtfNormal.php',
-
- # Templates
- 'UsercreateTemplate' => 'includes/templates/Userlogin.php',
- 'UserloginTemplate' => 'includes/templates/Userlogin.php',
-
- # Languages
- 'Language' => 'languages/Language.php',
-
- # API
+ # includes/api
'ApiBase' => 'includes/api/ApiBase.php',
+ 'ApiBlock' => 'includes/api/ApiBlock.php',
+ 'ApiDelete' => 'includes/api/ApiDelete.php',
+ 'ApiEditPage' => 'includes/api/ApiEditPage.php',
+ 'ApiEmailUser' => 'includes/api/ApiEmailUser.php',
'ApiExpandTemplates' => 'includes/api/ApiExpandTemplates.php',
- 'ApiFormatFeedWrapper' => 'includes/api/ApiFormatBase.php',
'ApiFeedWatchlist' => 'includes/api/ApiFeedWatchlist.php',
'ApiFormatBase' => 'includes/api/ApiFormatBase.php',
- 'Services_JSON' => 'includes/api/ApiFormatJson_json.php',
+ 'ApiFormatDbg' => 'includes/api/ApiFormatDbg.php',
+ 'ApiFormatFeedWrapper' => 'includes/api/ApiFormatBase.php',
'ApiFormatJson' => 'includes/api/ApiFormatJson.php',
'ApiFormatPhp' => 'includes/api/ApiFormatPhp.php',
+ 'ApiFormatTxt' => 'includes/api/ApiFormatTxt.php',
'ApiFormatWddx' => 'includes/api/ApiFormatWddx.php',
'ApiFormatXml' => 'includes/api/ApiFormatXml.php',
- 'ApiFormatTxt' => 'includes/api/ApiFormatTxt.php',
- 'ApiFormatDbg' => 'includes/api/ApiFormatDbg.php',
- 'Spyc' => 'includes/api/ApiFormatYaml_spyc.php',
'ApiFormatYaml' => 'includes/api/ApiFormatYaml.php',
'ApiHelp' => 'includes/api/ApiHelp.php',
'ApiLogin' => 'includes/api/ApiLogin.php',
'ApiLogout' => 'includes/api/ApiLogout.php',
'ApiMain' => 'includes/api/ApiMain.php',
+ 'ApiMove' => 'includes/api/ApiMove.php',
'ApiOpenSearch' => 'includes/api/ApiOpenSearch.php',
'ApiPageSet' => 'includes/api/ApiPageSet.php',
'ApiParamInfo' => 'includes/api/ApiParamInfo.php',
'ApiParse' => 'includes/api/ApiParse.php',
+ 'ApiProtect' => 'includes/api/ApiProtect.php',
'ApiQuery' => 'includes/api/ApiQuery.php',
- 'ApiQueryAllpages' => 'includes/api/ApiQueryAllpages.php',
- 'ApiQueryAllLinks' => 'includes/api/ApiQueryAllLinks.php',
'ApiQueryAllCategories' => 'includes/api/ApiQueryAllCategories.php',
+ 'ApiQueryAllimages' => 'includes/api/ApiQueryAllimages.php',
+ 'ApiQueryAllLinks' => 'includes/api/ApiQueryAllLinks.php',
'ApiQueryAllUsers' => 'includes/api/ApiQueryAllUsers.php',
- 'ApiQueryBase' => 'includes/api/ApiQueryBase.php',
- 'ApiQueryGeneratorBase' => 'includes/api/ApiQueryBase.php',
+ 'ApiQueryAllmessages' => 'includes/api/ApiQueryAllmessages.php',
+ 'ApiQueryAllpages' => 'includes/api/ApiQueryAllpages.php',
'ApiQueryBacklinks' => 'includes/api/ApiQueryBacklinks.php',
+ 'ApiQueryBase' => 'includes/api/ApiQueryBase.php',
+ 'ApiQueryBlocks' => 'includes/api/ApiQueryBlocks.php',
'ApiQueryCategories' => 'includes/api/ApiQueryCategories.php',
+ 'ApiQueryCategoryInfo' => 'includes/api/ApiQueryCategoryInfo.php',
'ApiQueryCategoryMembers' => 'includes/api/ApiQueryCategoryMembers.php',
'ApiQueryContributions' => 'includes/api/ApiQueryUserContributions.php',
- 'ApiQueryExternalLinks' => 'includes/api/ApiQueryExternalLinks.php',
+ 'ApiQueryDeletedrevs' => 'includes/api/ApiQueryDeletedrevs.php',
'ApiQueryExtLinksUsage' => 'includes/api/ApiQueryExtLinksUsage.php',
- 'ApiQueryImages' => 'includes/api/ApiQueryImages.php',
+ 'ApiQueryExternalLinks' => 'includes/api/ApiQueryExternalLinks.php',
+ 'ApiQueryGeneratorBase' => 'includes/api/ApiQueryBase.php',
'ApiQueryImageInfo' => 'includes/api/ApiQueryImageInfo.php',
+ 'ApiQueryImages' => 'includes/api/ApiQueryImages.php',
'ApiQueryInfo' => 'includes/api/ApiQueryInfo.php',
'ApiQueryLangLinks' => 'includes/api/ApiQueryLangLinks.php',
'ApiQueryLinks' => 'includes/api/ApiQueryLinks.php',
@@ -358,72 +271,264 @@ function __autoload($className) {
'ApiQueryRecentChanges'=> 'includes/api/ApiQueryRecentChanges.php',
'ApiQueryRevisions' => 'includes/api/ApiQueryRevisions.php',
'ApiQuerySearch' => 'includes/api/ApiQuerySearch.php',
- 'ApiQueryAllmessages' => 'includes/api/ApiQueryAllmessages.php',
'ApiQuerySiteinfo' => 'includes/api/ApiQuerySiteinfo.php',
- 'ApiQueryUsers' => 'includes/api/ApiQueryUsers.php',
'ApiQueryUserInfo' => 'includes/api/ApiQueryUserInfo.php',
+ 'ApiQueryUsers' => 'includes/api/ApiQueryUsers.php',
'ApiQueryWatchlist' => 'includes/api/ApiQueryWatchlist.php',
'ApiResult' => 'includes/api/ApiResult.php',
-
- # apiedit branch
- 'ApiBlock' => 'includes/api/ApiBlock.php',
- #'ApiChangeRights' => 'includes/api/ApiChangeRights.php',
- # Disabled for now
- 'ApiDelete' => 'includes/api/ApiDelete.php',
- 'ApiMove' => 'includes/api/ApiMove.php',
- 'ApiProtect' => 'includes/api/ApiProtect.php',
- 'ApiQueryBlocks' => 'includes/api/ApiQueryBlocks.php',
- 'ApiQueryDeletedrevs' => 'includes/api/ApiQueryDeletedrevs.php',
'ApiRollback' => 'includes/api/ApiRollback.php',
'ApiUnblock' => 'includes/api/ApiUnblock.php',
- 'ApiUndelete' => 'includes/api/ApiUndelete.php'
+ 'ApiUndelete' => 'includes/api/ApiUndelete.php',
+ 'Services_JSON' => 'includes/api/ApiFormatJson_json.php',
+ 'Services_JSON_Error' => 'includes/api/ApiFormatJson_json.php',
+ 'Spyc' => 'includes/api/ApiFormatYaml_spyc.php',
+ 'UsageException' => 'includes/api/ApiMain.php',
+ 'YAMLNode' => 'includes/api/ApiFormatYaml_spyc.php',
+
+ # includes/db
+ 'Blob' => 'includes/db/Database.php',
+ 'ChronologyProtector' => 'includes/db/LBFactory.php',
+ 'Database' => 'includes/db/Database.php',
+ 'DatabaseMssql' => 'includes/db/DatabaseMssql.php',
+ 'DatabaseMysql' => 'includes/db/Database.php',
+ 'DatabaseOracle' => 'includes/db/DatabaseOracle.php',
+ 'DatabasePostgres' => 'includes/db/DatabasePostgres.php',
+ 'DatabaseSqlite' => 'includes/db/DatabaseSqlite.php',
+ 'DBConnectionError' => 'includes/db/Database.php',
+ 'DBError' => 'includes/db/Database.php',
+ 'DBObject' => 'includes/db/Database.php',
+ 'DBQueryError' => 'includes/db/Database.php',
+ 'DBUnexpectedError' => 'includes/db/Database.php',
+ 'LBFactory' => 'includes/db/LBFactory.php',
+ 'LBFactory_Multi' => 'includes/db/LBFactory_Multi.php',
+ 'LBFactory_Simple' => 'includes/db/LBFactory.php',
+ 'LoadBalancer' => 'includes/db/LoadBalancer.php',
+ 'LoadMonitor' => 'includes/db/LoadMonitor.php',
+ 'LoadMonitor_MySQL' => 'includes/db/LoadMonitor.php',
+ 'MSSQLField' => 'includes/db/DatabaseMssql.php',
+ 'MySQLField' => 'includes/db/Database.php',
+ 'MySQLMasterPos' => 'includes/db/Database.php',
+ 'ORABlob' => 'includes/db/DatabaseOracle.php',
+ 'ORAResult' => 'includes/db/DatabaseOracle.php',
+ 'PostgresField' => 'includes/db/DatabasePostgres.php',
+ 'ResultWrapper' => 'includes/db/Database.php',
+ 'SQLiteField' => 'includes/db/DatabaseSqlite.php',
+
+ # includes/filerepo
+ 'ArchivedFile' => 'includes/filerepo/ArchivedFile.php',
+ 'File' => 'includes/filerepo/File.php',
+ 'FileRepo' => 'includes/filerepo/FileRepo.php',
+ 'FileRepoStatus' => 'includes/filerepo/FileRepoStatus.php',
+ 'ForeignAPIFile' => 'includes/filerepo/ForeignAPIFile.php',
+ 'ForeignAPIRepo' => 'includes/filerepo/ForeignAPIRepo.php',
+ 'ForeignDBFile' => 'includes/filerepo/ForeignDBFile.php',
+ 'ForeignDBRepo' => 'includes/filerepo/ForeignDBRepo.php',
+ 'ForeignDBViaLBRepo' => 'includes/filerepo/ForeignDBViaLBRepo.php',
+ 'FSRepo' => 'includes/filerepo/FSRepo.php',
+ 'Image' => 'includes/filerepo/Image.php',
+ 'LocalFile' => 'includes/filerepo/LocalFile.php',
+ 'LocalFileDeleteBatch' => 'includes/filerepo/LocalFile.php',
+ 'LocalFileMoveBatch' => 'includes/filerepo/LocalFile.php',
+ 'LocalFileRestoreBatch' => 'includes/filerepo/LocalFile.php',
+ 'LocalRepo' => 'includes/filerepo/LocalRepo.php',
+ 'OldLocalFile' => 'includes/filerepo/OldLocalFile.php',
+ 'RepoGroup' => 'includes/filerepo/RepoGroup.php',
+ 'UnregisteredLocalFile' => 'includes/filerepo/UnregisteredLocalFile.php',
+
+ # includes/media
+ 'BitmapHandler' => 'includes/media/Bitmap.php',
+ 'BmpHandler' => 'includes/media/BMP.php',
+ 'DjVuHandler' => 'includes/media/DjVu.php',
+ 'ImageHandler' => 'includes/media/Generic.php',
+ 'MediaHandler' => 'includes/media/Generic.php',
+ 'SvgHandler' => 'includes/media/SVG.php',
+
+ # includes/normal
+ 'UtfNormal' => 'includes/normal/UtfNormal.php',
+
+ # includes/parser
+ 'CoreParserFunctions' => 'includes/parser/CoreParserFunctions.php',
+ 'DateFormatter' => 'includes/parser/DateFormatter.php',
+ 'OnlyIncludeReplacer' => 'includes/parser/Parser.php',
+ 'PPDAccum_Hash' => 'includes/parser/Preprocessor_Hash.php',
+ 'PPDPart' => 'includes/parser/Preprocessor_DOM.php',
+ 'PPDPart_Hash' => 'includes/parser/Preprocessor_Hash.php',
+ 'PPDStack' => 'includes/parser/Preprocessor_DOM.php',
+ 'PPDStackElement' => 'includes/parser/Preprocessor_DOM.php',
+ 'PPDStackElement_Hash' => 'includes/parser/Preprocessor_Hash.php',
+ 'PPDStack_Hash' => 'includes/parser/Preprocessor_Hash.php',
+ 'PPFrame' => 'includes/parser/Preprocessor.php',
+ 'PPFrame_DOM' => 'includes/parser/Preprocessor_DOM.php',
+ 'PPFrame_Hash' => 'includes/parser/Preprocessor_Hash.php',
+ 'PPNode' => 'includes/parser/Preprocessor.php',
+ 'PPNode_DOM' => 'includes/parser/Preprocessor_DOM.php',
+ 'PPNode_Hash_Array' => 'includes/parser/Preprocessor_Hash.php',
+ 'PPNode_Hash_Attr' => 'includes/parser/Preprocessor_Hash.php',
+ 'PPNode_Hash_Text' => 'includes/parser/Preprocessor_Hash.php',
+ 'PPNode_Hash_Tree' => 'includes/parser/Preprocessor_Hash.php',
+ 'PPTemplateFrame_DOM' => 'includes/parser/Preprocessor_DOM.php',
+ 'PPTemplateFrame_Hash' => 'includes/parser/Preprocessor_Hash.php',
+ 'Parser' => 'includes/parser/Parser.php',
+ 'ParserCache' => 'includes/parser/ParserCache.php',
+ 'ParserOptions' => 'includes/parser/ParserOptions.php',
+ 'ParserOutput' => 'includes/parser/ParserOutput.php',
+ 'Parser_DiffTest' => 'includes/parser/Parser_DiffTest.php',
+ 'Parser_OldPP' => 'includes/parser/Parser_OldPP.php',
+ 'Preprocessor' => 'includes/parser/Preprocessor.php',
+ 'Preprocessor_DOM' => 'includes/parser/Preprocessor_DOM.php',
+ 'Preprocessor_Hash' => 'includes/parser/Preprocessor_Hash.php',
+ 'StripState' => 'includes/parser/Parser.php',
+
+ # includes/specials
+ 'AncientPagesPage' => 'includes/specials/SpecialAncientpages.php',
+ 'BrokenRedirectsPage' => 'includes/specials/SpecialBrokenRedirects.php',
+ 'ContribsPager' => 'includes/specials/SpecialContributions.php',
+ 'DBLockForm' => 'includes/specials/SpecialLockdb.php',
+ 'DBUnlockForm' => 'includes/specials/SpecialUnlockdb.php',
+ 'DeadendPagesPage' => 'includes/specials/SpecialDeadendpages.php',
+ 'DisambiguationsPage' => 'includes/specials/SpecialDisambiguations.php',
+ 'DoubleRedirectsPage' => 'includes/specials/SpecialDoubleRedirects.php',
+ 'EmailConfirmation' => 'includes/specials/SpecialConfirmemail.php',
+ 'EmailInvalidation' => 'includes/specials/SpecialConfirmemail.php',
+ 'EmailUserForm' => 'includes/specials/SpecialEmailuser.php',
+ 'FewestrevisionsPage' => 'includes/specials/SpecialFewestrevisions.php',
+ 'FileDuplicateSearchPage' => 'includes/specials/SpecialFileDuplicateSearch.php',
+ 'IPBlockForm' => 'includes/specials/SpecialBlockip.php',
+ 'IPBlocklistPager' => 'includes/specials/SpecialIpblocklist.php',
+ 'IPUnblockForm' => 'includes/specials/SpecialIpblocklist.php',
+ 'ImportReporter' => 'includes/specials/SpecialImport.php',
+ 'ImportStreamSource' => 'includes/specials/SpecialImport.php',
+ 'ImportStringSource' => 'includes/specials/SpecialImport.php',
+ 'ListredirectsPage' => 'includes/specials/SpecialListredirects.php',
+ 'LoginForm' => 'includes/specials/SpecialUserlogin.php',
+ 'LonelyPagesPage' => 'includes/specials/SpecialLonelypages.php',
+ 'LongPagesPage' => 'includes/specials/SpecialLongpages.php',
+ 'MIMEsearchPage' => 'includes/specials/SpecialMIMEsearch.php',
+ 'MostcategoriesPage' => 'includes/specials/SpecialMostcategories.php',
+ 'MostimagesPage' => 'includes/specials/SpecialMostimages.php',
+ 'MostlinkedCategoriesPage' => 'includes/specials/SpecialMostlinkedcategories.php',
+ 'MostlinkedPage' => 'includes/specials/SpecialMostlinked.php',
+ 'MostrevisionsPage' => 'includes/specials/SpecialMostrevisions.php',
+ 'MovePageForm' => 'includes/specials/SpecialMovepage.php',
+ 'SpecialNewpages' => 'includes/specials/SpecialNewpages.php',
+ 'NewPagesPager' => 'includes/specials/SpecialNewpages.php',
+ 'PageArchive' => 'includes/specials/SpecialUndelete.php',
+ 'PasswordResetForm' => 'includes/specials/SpecialResetpass.php',
+ 'PopularPagesPage' => 'includes/specials/SpecialPopularpages.php',
+ 'PreferencesForm' => 'includes/specials/SpecialPreferences.php',
+ 'RandomPage' => 'includes/specials/SpecialRandompage.php',
+ 'RevisionDeleteForm' => 'includes/specials/SpecialRevisiondelete.php',
+ 'RevisionDeleter' => 'includes/specials/SpecialRevisiondelete.php',
+ 'ShortPagesPage' => 'includes/specials/SpecialShortpages.php',
+ 'SpecialAllpages' => 'includes/specials/SpecialAllpages.php',
+ 'SpecialBookSources' => 'includes/specials/SpecialBooksources.php',
+ 'SpecialListGroupRights' => 'includes/specials/SpecialListgrouprights.php',
+ 'SpecialMostlinkedtemplates' => 'includes/specials/SpecialMostlinkedtemplates.php',
+ 'SpecialPrefixindex' => 'includes/specials/SpecialPrefixindex.php',
+ 'SpecialRandomredirect' => 'includes/specials/SpecialRandomredirect.php',
+ 'SpecialRecentchanges' => 'includes/specials/SpecialRecentchanges.php',
+ 'SpecialRecentchangeslinked' => 'includes/specials/SpecialRecentchangeslinked.php',
+ 'SpecialSearch' => 'includes/specials/SpecialSearch.php',
+ 'SpecialVersion' => 'includes/specials/SpecialVersion.php',
+ 'UncategorizedCategoriesPage' => 'includes/specials/SpecialUncategorizedcategories.php',
+ 'UncategorizedPagesPage' => 'includes/specials/SpecialUncategorizedpages.php',
+ 'UncategorizedTemplatesPage' => 'includes/specials/SpecialUncategorizedtemplates.php',
+ 'UndeleteForm' => 'includes/specials/SpecialUndelete.php',
+ 'UnusedCategoriesPage' => 'includes/specials/SpecialUnusedcategories.php',
+ 'UnusedimagesPage' => 'includes/specials/SpecialUnusedimages.php',
+ 'UnusedtemplatesPage' => 'includes/specials/SpecialUnusedtemplates.php',
+ 'UnwatchedpagesPage' => 'includes/specials/SpecialUnwatchedpages.php',
+ 'UploadForm' => 'includes/specials/SpecialUpload.php',
+ 'UploadFormMogile' => 'includes/specials/SpecialUploadMogile.php',
+ 'UserrightsPage' => 'includes/specials/SpecialUserrights.php',
+ 'UsersPager' => 'includes/specials/SpecialListusers.php',
+ 'WantedCategoriesPage' => 'includes/specials/SpecialWantedcategories.php',
+ 'WantedPagesPage' => 'includes/specials/SpecialWantedpages.php',
+ 'WhatLinksHerePage' => 'includes/specials/SpecialWhatlinkshere.php',
+ 'WikiImporter' => 'includes/specials/SpecialImport.php',
+ 'WikiRevision' => 'includes/specials/SpecialImport.php',
+ 'WithoutInterwikiPage' => 'includes/specials/SpecialWithoutinterwiki.php',
+
+ # includes/templates
+ 'UsercreateTemplate' => 'includes/templates/Userlogin.php',
+ 'UserloginTemplate' => 'includes/templates/Userlogin.php',
+
+ # languages
+ 'Language' => 'languages/Language.php',
+ 'FakeConverter' => 'languages/Language.php',
+
+ # maintenance/language
+ 'statsOutput' => 'maintenance/language/StatOutputs.php',
+ 'wikiStatsOutput' => 'maintenance/language/StatOutputs.php',
+ 'metawikiStatsOutput' => 'maintenance/language/StatOutputs.php',
+ 'textStatsOutput' => 'maintenance/language/StatOutputs.php',
+ 'csvStatsOutput' => 'maintenance/language/StatOutputs.php',
+
);
-
- wfProfileIn( __METHOD__ );
- if ( isset( $localClasses[$className] ) ) {
- $filename = $localClasses[$className];
- } elseif ( isset( $wgAutoloadClasses[$className] ) ) {
- $filename = $wgAutoloadClasses[$className];
- } else {
- # Try a different capitalisation
- # The case can sometimes be wrong when unserializing PHP 4 objects
- $filename = false;
- $lowerClass = strtolower( $className );
- foreach ( $localClasses as $class2 => $file2 ) {
- if ( strtolower( $class2 ) == $lowerClass ) {
- $filename = $file2;
+
+ /**
+ * autoload - take a class name and attempt to load it
+ *
+ * @param string $className Name of class we're looking for.
+ * @return bool Returning false is important on failure as
+ * it allows Zend to try and look in other registered autoloaders
+ * as well.
+ */
+ static function autoload( $className ) {
+ global $wgAutoloadClasses;
+
+ wfProfileIn( __METHOD__ );
+ if ( isset( self::$localClasses[$className] ) ) {
+ $filename = self::$localClasses[$className];
+ } elseif ( isset( $wgAutoloadClasses[$className] ) ) {
+ $filename = $wgAutoloadClasses[$className];
+ } else {
+ # Try a different capitalisation
+ # The case can sometimes be wrong when unserializing PHP 4 objects
+ $filename = false;
+ $lowerClass = strtolower( $className );
+ foreach ( self::$localClasses as $class2 => $file2 ) {
+ if ( strtolower( $class2 ) == $lowerClass ) {
+ $filename = $file2;
+ }
+ }
+ if ( !$filename ) {
+ # Give up
+ wfProfileOut( __METHOD__ );
+ return false;
}
}
- if ( !$filename ) {
- # Give up
- wfProfileOut( __METHOD__ );
- return;
+
+ # Make an absolute path, this improves performance by avoiding some stat calls
+ if ( substr( $filename, 0, 1 ) != '/' && substr( $filename, 1, 1 ) != ':' ) {
+ global $IP;
+ $filename = "$IP/$filename";
}
+ require( $filename );
+ wfProfileOut( __METHOD__ );
+ return true;
}
- # Make an absolute path, this improves performance by avoiding some stat calls
- if ( substr( $filename, 0, 1 ) != '/' && substr( $filename, 1, 1 ) != ':' ) {
- global $IP;
- $filename = "$IP/$filename";
+ static function loadAllExtensions() {
+ global $wgAutoloadClasses;
+
+ foreach( $wgAutoloadClasses as $class => $file ) {
+ if( !( class_exists( $class ) || interface_exists( $class ) ) ) {
+ require( $file );
+ }
+ }
}
- require( $filename );
- wfProfileOut( __METHOD__ );
}
function wfLoadAllExtensions() {
- global $wgAutoloadClasses;
+ AutoLoader::loadAllExtensions();
+}
- # It is crucial that SpecialPage.php is included before any special page
- # extensions are loaded. Otherwise the parent class will not be available
- # when APC loads the early-bound extension class. Normally this is
- # guaranteed by entering special pages via SpecialPage members such as
- # executePath(), but here we have to take a more explicit measure.
-
- require_once( dirname(__FILE__) . '/SpecialPage.php' );
-
- foreach( $wgAutoloadClasses as $class => $file ) {
- if( !( class_exists( $class ) || interface_exists( $class ) ) ) {
- require( $file );
- }
+if ( function_exists( 'spl_autoload_register' ) ) {
+ spl_autoload_register( array( 'AutoLoader', 'autoload' ) );
+} else {
+ function __autoload( $class ) {
+ AutoLoader::autoload( $class );
}
}
+
diff --git a/includes/Autopromote.php b/includes/Autopromote.php
index b5097423..68fe6636 100644
--- a/includes/Autopromote.php
+++ b/includes/Autopromote.php
@@ -8,7 +8,7 @@ class Autopromote {
/**
* Get the groups for the given user based on $wgAutopromote.
*
- * @param User $user The user to get the groups for
+ * @param $user The user to get the groups for
* @return array Array of groups to promote to.
*/
public static function getAutopromoteGroups( User $user ) {
@@ -18,6 +18,9 @@ class Autopromote {
if( self::recCheckCondition( $cond, $user ) )
$promote[] = $group;
}
+
+ wfRunHooks( 'GetAutoPromoteGroups', array($user, &$promote) );
+
return $promote;
}
@@ -33,12 +36,12 @@ class Autopromote {
* This function evaluates the former type recursively, and passes off to
* self::checkCondition for evaluation of the latter type.
*
- * @param mixed $cond A condition, possibly containing other conditions
- * @param User $user The user to check the conditions against
+ * @param $cond Mixed: a condition, possibly containing other conditions
+ * @param $user The user to check the conditions against
* @return bool Whether the condition is true
*/
private static function recCheckCondition( $cond, User $user ) {
- $validOps = array( '&', '|', '^' );
+ $validOps = array( '&', '|', '^', '!' );
if( is_array( $cond ) && count( $cond ) >= 2 && in_array( $cond[0], $validOps ) ) {
# Recursive condition
if( $cond[0] == '&' ) {
@@ -47,7 +50,7 @@ class Autopromote {
return false;
return true;
} elseif( $cond[0] == '|' ) {
- foreach( array_slice( $cond, 1 ) as $subcond )
+ foreach( array_slice( $cond, 1 ) as $subcond )
if( self::recCheckCondition( $subcond, $user ) )
return true;
return false;
@@ -60,6 +63,11 @@ class Autopromote {
$res = ($res xor self::recCheckCondition( $subcond, $user ));
}
return $res;
+ } elseif ( $cond[0] = '!' ) {
+ foreach( array_slice( $cond, 1 ) as $subcond )
+ if( self::recCheckCondition( $subcond, $user ) )
+ return false;
+ return true;
}
}
# If we got here, the array presumably does not contain other condi-
@@ -75,8 +83,8 @@ class Autopromote {
* APCOND_AGE. Other types will throw an exception if no extension evalu-
* ates them.
*
- * @param array $cond A condition, which must not contain other conditions
- * @param User $user The user to check the condition against
+ * @param $cond Array: A condition, which must not contain other conditions
+ * @param $user The user to check the condition against
* @return bool Whether the condition is true for the user
*/
private static function checkCondition( $cond, User $user ) {
@@ -87,7 +95,7 @@ class Autopromote {
if( User::isValidEmailAddr( $user->getEmail() ) ) {
global $wgEmailAuthentication;
if( $wgEmailAuthentication ) {
- return $user->getEmailAuthenticationTimestamp() ? true : false;
+ return (bool)$user->getEmailAuthenticationTimestamp();
} else {
return true;
}
diff --git a/includes/BagOStuff.php b/includes/BagOStuff.php
index 226abb35..b4fefc97 100644
--- a/includes/BagOStuff.php
+++ b/includes/BagOStuff.php
@@ -17,22 +17,25 @@
# 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
+
/**
+ * @defgroup Cache Cache
*
+ * @file
+ * @ingroup Cache
*/
/**
- * Simple generic object store
- *
* interface is intended to be more or less compatible with
* the PHP memcached client.
*
* backends for local hash array and SQL table included:
* <code>
* $bag = new HashBagOStuff();
- * $bag = new MysqlBagOStuff($tablename); # connect to db first
+ * $bag = new MediaWikiBagOStuff($tablename); # connect to db first
* </code>
*
+ * @ingroup Cache
*/
class BagOStuff {
var $debugmode;
@@ -167,14 +170,12 @@ class BagOStuff {
/**
* Functional versions!
- * @todo document
+ * This is a test of the interface, mainly. It stores things in an associative
+ * array, which is not going to persist between program runs.
+ *
+ * @ingroup Cache
*/
class HashBagOStuff extends BagOStuff {
- /*
- This is a test of the interface, mainly. It stores
- things in an associative array, which is not going to
- persist between program runs.
- */
var $bag;
function __construct() {
@@ -213,24 +214,20 @@ class HashBagOStuff extends BagOStuff {
}
}
-/*
-CREATE TABLE objectcache (
- keyname char(255) binary not null default '',
- value mediumblob,
- exptime datetime,
- unique key (keyname),
- key (exptime)
-);
-*/
-
/**
- * @todo document
- * @abstract
+ * Generic class to store objects in a database
+ *
+ * @ingroup Cache
*/
abstract class SqlBagOStuff extends BagOStuff {
var $table;
var $lastexpireall = 0;
+ /**
+ * Constructor
+ *
+ * @param $tablename String: name of the table to use
+ */
function __construct($tablename = 'objectcache') {
$this->table = $tablename;
}
@@ -247,8 +244,8 @@ abstract class SqlBagOStuff extends BagOStuff {
}
if($row=$this->_fetchobject($res)) {
$this->_debug("get: retrieved data; exp time is " . $row->exptime);
- if ( $row->exptime != $this->_maxdatetime() &&
- wfTimestamp( TS_UNIX, $row->exptime ) < time() )
+ if ( $row->exptime != $this->_maxdatetime() &&
+ wfTimestamp( TS_UNIX, $row->exptime ) < time() )
{
$this->_debug("get: key has expired, deleting");
$this->delete($key);
@@ -262,7 +259,7 @@ abstract class SqlBagOStuff extends BagOStuff {
}
function set($key,$value,$exptime=0) {
- if ( wfReadOnly() ) {
+ if ( $this->_readonly() ) {
return false;
}
$exptime = intval($exptime);
@@ -284,7 +281,7 @@ abstract class SqlBagOStuff extends BagOStuff {
}
function delete($key,$time=0) {
- if ( wfReadOnly() ) {
+ if ( $this->_readonly() ) {
return false;
}
$this->_query(
@@ -340,6 +337,8 @@ abstract class SqlBagOStuff extends BagOStuff {
abstract function _doinsert($table, $vals);
abstract function _doquery($sql);
+ abstract function _readonly();
+
function _freeresult($result) {
/* stub */
return false;
@@ -367,7 +366,7 @@ abstract class SqlBagOStuff extends BagOStuff {
function expireall() {
/* Remove any items that have expired */
- if ( wfReadOnly() ) {
+ if ( $this->_readonly() ) {
return false;
}
$now = $this->_fromunixtime( time() );
@@ -376,7 +375,7 @@ abstract class SqlBagOStuff extends BagOStuff {
function deleteall() {
/* Clear *all* items from cache table */
- if ( wfReadOnly() ) {
+ if ( $this->_readonly() ) {
return false;
}
$this->_query( "DELETE FROM $0" );
@@ -387,7 +386,7 @@ abstract class SqlBagOStuff extends BagOStuff {
* On typical message and page data, this can provide a 3X decrease
* in storage requirements.
*
- * @param mixed $data
+ * @param $data mixed
* @return string
*/
function _serialize( &$data ) {
@@ -401,7 +400,7 @@ abstract class SqlBagOStuff extends BagOStuff {
/**
* Unserialize and, if necessary, decompress an object.
- * @param string $serial
+ * @param $serial string
* @return mixed
*/
function _unserialize( $serial ) {
@@ -417,31 +416,33 @@ abstract class SqlBagOStuff extends BagOStuff {
}
/**
- * @todo document
+ * Stores objects in the main database of the wiki
+ *
+ * @ingroup Cache
*/
class MediaWikiBagOStuff extends SqlBagOStuff {
var $tableInitialised = false;
+ function _getDB(){
+ static $db;
+ if( !isset( $db ) )
+ $db = wfGetDB( DB_MASTER );
+ return $db;
+ }
function _doquery($sql) {
- $dbw = wfGetDB( DB_MASTER );
- return $dbw->query($sql, 'MediaWikiBagOStuff::_doquery');
+ return $this->_getDB()->query( $sql, __METHOD__ );
}
function _doinsert($t, $v) {
- $dbw = wfGetDB( DB_MASTER );
- return $dbw->insert($t, $v, 'MediaWikiBagOStuff::_doinsert',
- array( 'IGNORE' ) );
+ return $this->_getDB()->insert($t, $v, __METHOD__, array( 'IGNORE' ) );
}
function _fetchobject($result) {
- $dbw = wfGetDB( DB_MASTER );
- return $dbw->fetchObject($result);
+ return $this->_getDB()->fetchObject($result);
}
function _freeresult($result) {
- $dbw = wfGetDB( DB_MASTER );
- return $dbw->freeResult($result);
+ return $this->_getDB()->freeResult($result);
}
function _dberror($result) {
- $dbw = wfGetDB( DB_MASTER );
- return $dbw->lastError();
+ return $this->_getDB()->lastError();
}
function _maxdatetime() {
if ( time() > 0x7fffffff ) {
@@ -451,24 +452,23 @@ class MediaWikiBagOStuff extends SqlBagOStuff {
}
}
function _fromunixtime($ts) {
- $dbw = wfGetDB(DB_MASTER);
- return $dbw->timestamp($ts);
+ return $this->_getDB()->timestamp($ts);
+ }
+ function _readonly(){
+ return wfReadOnly();
}
function _strencode($s) {
- $dbw = wfGetDB( DB_MASTER );
- return $dbw->strencode($s);
+ return $this->_getDB()->strencode($s);
}
function _blobencode($s) {
- $dbw = wfGetDB( DB_MASTER );
- return $dbw->encodeBlob($s);
+ return $this->_getDB()->encodeBlob($s);
}
function _blobdecode($s) {
- $dbw = wfGetDB( DB_MASTER );
- return $dbw->decodeBlob($s);
+ return $this->_getDB()->decodeBlob($s);
}
function getTableName() {
if ( !$this->tableInitialised ) {
- $dbw = wfGetDB( DB_MASTER );
+ $dbw = $this->_getDB();
/* This is actually a hack, we should be able
to use Language classes here... or not */
if (!$dbw)
@@ -493,6 +493,7 @@ class MediaWikiBagOStuff extends SqlBagOStuff {
* that Turck's serializer is faster, so a possible future extension would be
* to use it for arrays but not for objects.
*
+ * @ingroup Cache
*/
class TurckBagOStuff extends BagOStuff {
function get($key) {
@@ -527,6 +528,7 @@ class TurckBagOStuff extends BagOStuff {
/**
* This is a wrapper for APC's shared memory functions
*
+ * @ingroup Cache
*/
class APCBagOStuff extends BagOStuff {
function get($key) {
@@ -536,12 +538,12 @@ class APCBagOStuff extends BagOStuff {
}
return $val;
}
-
+
function set($key, $value, $exptime=0) {
apc_store($key, serialize($value), $exptime);
return true;
}
-
+
function delete($key, $time=0) {
apc_delete($key);
return true;
@@ -555,6 +557,7 @@ class APCBagOStuff extends BagOStuff {
* This is basically identical to the Turck MMCache version,
* mostly because eAccelerator is based on Turck MMCache.
*
+ * @ingroup Cache
*/
class eAccelBagOStuff extends BagOStuff {
function get($key) {
@@ -589,13 +592,15 @@ class eAccelBagOStuff extends BagOStuff {
/**
* Wrapper for XCache object caching functions; identical interface
* to the APC wrapper
+ *
+ * @ingroup Cache
*/
class XCacheBagOStuff extends BagOStuff {
/**
* Get a value from the XCache object cache
*
- * @param string $key Cache key
+ * @param $key String: cache key
* @return mixed
*/
public function get( $key ) {
@@ -604,40 +609,41 @@ class XCacheBagOStuff extends BagOStuff {
$val = unserialize( $val );
return $val;
}
-
+
/**
* Store a value in the XCache object cache
*
- * @param string $key Cache key
- * @param mixed $value Object to store
- * @param int $expire Expiration time
+ * @param $key String: cache key
+ * @param $value Mixed: object to store
+ * @param $expire Int: expiration time
* @return bool
*/
public function set( $key, $value, $expire = 0 ) {
xcache_set( $key, serialize( $value ), $expire );
return true;
}
-
+
/**
* Remove a value from the XCache object cache
*
- * @param string $key Cache key
- * @param int $time Not used in this implementation
+ * @param $key String: cache key
+ * @param $time Int: not used in this implementation
* @return bool
*/
public function delete( $key, $time = 0 ) {
xcache_unset( $key );
return true;
}
-
+
}
/**
* @todo document
+ * @ingroup Cache
*/
class DBABagOStuff extends BagOStuff {
var $mHandler, $mFile, $mReader, $mWriter, $mDisabled;
-
+
function __construct( $handler = 'db3', $dir = false ) {
if ( $dir === false ) {
global $wgTmpDirectory;
@@ -645,6 +651,7 @@ class DBABagOStuff extends BagOStuff {
}
$this->mFile = "$dir/mw-cache-" . wfWikiID();
$this->mFile .= '.db';
+ wfDebug( __CLASS__.": using cache file {$this->mFile}\n" );
$this->mHandler = $handler;
}
@@ -664,7 +671,7 @@ class DBABagOStuff extends BagOStuff {
if ( !is_string( $blob ) ) {
return array( null, 0 );
} else {
- return array(
+ return array(
unserialize( substr( $blob, 11 ) ),
intval( substr( $blob, 0, 10 ) )
);
@@ -779,5 +786,3 @@ class DBABagOStuff extends BagOStuff {
return $result;
}
}
-
-
diff --git a/includes/Block.php b/includes/Block.php
index 3688d7cf..b208fa8a 100644
--- a/includes/Block.php
+++ b/includes/Block.php
@@ -1,5 +1,6 @@
<?php
/**
+ * @file
* Blocks and bans object
*/
@@ -15,16 +16,16 @@
class Block
{
/* public*/ var $mAddress, $mUser, $mBy, $mReason, $mTimestamp, $mAuto, $mId, $mExpiry,
- $mRangeStart, $mRangeEnd, $mAnonOnly, $mEnableAutoblock, $mHideName,
- $mBlockEmail;
- /* private */ var $mNetworkBits, $mIntegerAddr, $mForUpdate, $mFromMaster, $mByName;
-
+ $mRangeStart, $mRangeEnd, $mAnonOnly, $mEnableAutoblock, $mHideName,
+ $mBlockEmail, $mByName, $mAngryAutoblock;
+ /* private */ var $mNetworkBits, $mIntegerAddr, $mForUpdate, $mFromMaster;
+
const EB_KEEP_EXPIRED = 1;
const EB_FOR_UPDATE = 2;
const EB_RANGE_ONLY = 4;
function __construct( $address = '', $user = 0, $by = 0, $reason = '',
- $timestamp = '' , $auto = 0, $expiry = '', $anonOnly = 0, $createAccount = 0, $enableAutoblock = 0,
+ $timestamp = '' , $auto = 0, $expiry = '', $anonOnly = 0, $createAccount = 0, $enableAutoblock = 0,
$hideName = 0, $blockEmail = 0 )
{
$this->mId = 0;
@@ -45,6 +46,7 @@ class Block
$this->mForUpdate = false;
$this->mFromMaster = false;
$this->mByName = false;
+ $this->mAngryAutoblock = false;
$this->initialiseRange();
}
@@ -59,10 +61,10 @@ class Block
}
}
- static function newFromID( $id )
+ static function newFromID( $id )
{
$dbr = wfGetDB( DB_SLAVE );
- $res = $dbr->resultObject( $dbr->select( 'ipblocks', '*',
+ $res = $dbr->resultObject( $dbr->select( 'ipblocks', '*',
array( 'ipb_id' => $id ), __METHOD__ ) );
$block = new Block;
if ( $block->loadFromResult( $res ) ) {
@@ -75,8 +77,8 @@ class Block
function clear()
{
$this->mAddress = $this->mReason = $this->mTimestamp = '';
- $this->mId = $this->mAnonOnly = $this->mCreateAccount =
- $this->mEnableAutoblock = $this->mAuto = $this->mUser =
+ $this->mId = $this->mAnonOnly = $this->mCreateAccount =
+ $this->mEnableAutoblock = $this->mAuto = $this->mUser =
$this->mBy = $this->mHideName = $this->mBlockEmail = 0;
$this->mByName = false;
}
@@ -124,7 +126,7 @@ class Block
# Try user block
if ( $user ) {
- $res = $db->resultObject( $db->select( 'ipblocks', '*', array( 'ipb_user' => $user ),
+ $res = $db->resultObject( $db->select( 'ipblocks', '*', array( 'ipb_user' => $user ),
__METHOD__, $options ) );
if ( $this->loadFromResult( $res, $killExpired ) ) {
return true;
@@ -170,7 +172,7 @@ class Block
return true;
}
}
-
+
# Give up
$this->clear();
return false;
@@ -179,7 +181,7 @@ class Block
/**
* Fill in member variables from a result wrapper
*/
- function loadFromResult( ResultWrapper $res, $killExpired = true )
+ function loadFromResult( ResultWrapper $res, $killExpired = true )
{
$ret = false;
if ( 0 != $res->numRows() ) {
@@ -234,7 +236,7 @@ class Block
"ipb_range_start <= '$iaddr'",
"ipb_range_end >= '$iaddr'"
);
-
+
if ( $user ) {
$conds['ipb_anon_only'] = 0;
}
@@ -270,7 +272,7 @@ class Block
if ( isset( $row->user_name ) ) {
$this->mByName = $row->user_name;
} else {
- $this->mByName = false;
+ $this->mByName = $row->ipb_by_text;
}
$this->mRangeStart = $row->ipb_range_start;
$this->mRangeEnd = $row->ipb_range_end;
@@ -358,7 +360,7 @@ class Block
/**
* Insert a block into the block table.
- *@return Whether or not the insertion was successful.
+ * @return Whether or not the insertion was successful.
*/
function insert()
{
@@ -376,6 +378,15 @@ class Block
$this->mBlockEmail = 0; //Same goes for email...
}
+ if( !$this->mByName ) {
+ if( $this->mBy ) {
+ $this->mByName = User::whoIs( $this->mBy );
+ } else {
+ global $wgUser;
+ $this->mByName = $wgUser->getName();
+ }
+ }
+
# Don't collide with expired blocks
Block::purgeExpired();
@@ -386,6 +397,7 @@ class Block
'ipb_address' => $this->mAddress,
'ipb_user' => $this->mUser,
'ipb_by' => $this->mBy,
+ 'ipb_by_text' => $this->mByName,
'ipb_reason' => $this->mReason,
'ipb_timestamp' => $dbw->timestamp($this->mTimestamp),
'ipb_auto' => $this->mAuto,
@@ -400,7 +412,6 @@ class Block
), 'Block::insert', array( 'IGNORE' )
);
$affected = $dbw->affectedRows();
- $dbw->commit();
if ($affected)
$this->doRetroactiveAutoblock();
@@ -420,17 +431,30 @@ class Block
if ($this->mEnableAutoblock && $this->mUser) {
wfDebug("Doing retroactive autoblocks for " . $this->mAddress . "\n");
+
+ $options = array( 'ORDER BY' => 'rc_timestamp DESC' );
+ $conds = array( 'rc_user_text' => $this->mAddress );
+
+ if ($this->mAngryAutoblock) {
+ // Block any IP used in the last 7 days. Up to five IPs.
+ $conds[] = 'rc_timestamp < ' . $dbr->addQuotes( $dbr->timestamp( time() - (7*86400) ) );
+ $options['LIMIT'] = 5;
+ } else {
+ // Just the last IP used.
+ $options['LIMIT'] = 1;
+ }
- $row = $dbr->selectRow( 'recentchanges', array( 'rc_ip' ), array( 'rc_user_text' => $this->mAddress ),
- __METHOD__ , array( 'ORDER BY' => 'rc_timestamp DESC' ) );
+ $res = $dbr->select( 'recentchanges', array( 'rc_ip' ), $conds,
+ __METHOD__ , $options);
- if ( !$row || !$row->rc_ip ) {
+ if ( !$dbr->numRows( $res ) ) {
#No results, don't autoblock anything
wfDebug("No IP found to retroactively autoblock\n");
} else {
- #Limit is 1, so no loop needed.
- $retroblockip = $row->rc_ip;
- return $this->doAutoblock( $retroblockip, true );
+ while ( $row = $dbr->fetchObject( $res ) ) {
+ if ( $row->rc_ip )
+ $this->doAutoblock( $row->rc_ip );
+ }
}
}
}
@@ -476,6 +500,12 @@ class Block
wfDebug( " No match\n" );
}
}
+
+ ## Allow hooks to cancel the autoblock.
+ if (!wfRunHooks( 'AbortAutoblock', array( $autoblockip, &$this ) )) {
+ wfDebug( "Autoblock aborted by hook." );
+ return false;
+ }
# It's okay to autoblock. Go ahead and create/insert the block.
@@ -502,6 +532,7 @@ class Block
$ipblock->mAddress = $autoblockip;
$ipblock->mUser = 0;
$ipblock->mBy = $this->mBy;
+ $ipblock->mByName = $this->mByName;
$ipblock->mReason = wfMsgForContent( 'autoblocker', $this->mAddress, $this->mReason );
$ipblock->mTimestamp = wfTimestampNow();
$ipblock->mAuto = 1;
@@ -592,9 +623,6 @@ class Block
*/
function getByName()
{
- if ( $this->mByName === false ) {
- $this->mByName = User::whoIs( $this->mBy );
- }
return $this->mByName;
}
@@ -613,7 +641,7 @@ class Block
return $this->mAddress;
}
}
-
+
/**
* Encode expiry for DB
*/
@@ -625,7 +653,7 @@ class Block
}
}
- /**
+ /**
* Decode expiry which has come from the DB
*/
static function decodeExpiry( $expiry, $timestampType = TS_MW ) {
@@ -635,14 +663,14 @@ class Block
return wfTimestamp( $timestampType, $expiry );
}
}
-
+
static function getAutoblockExpiry( $timestamp )
{
global $wgAutoblockExpiry;
return wfTimestamp( TS_MW, wfTimestamp( TS_UNIX, $timestamp ) + $wgAutoblockExpiry );
}
-
- /**
+
+ /**
* Gets rid of uneeded numbers in quad-dotted/octet IP strings
* For example, 127.111.113.151/24 -> 127.111.113.0/24
*/
@@ -675,7 +703,7 @@ class Block
return $range;
}
- /**
+ /**
* Purge expired blocks from the ipblocks table
*/
static function purgeExpired() {
@@ -684,8 +712,8 @@ class Block
}
static function infinity() {
- # This is a special keyword for timestamps in PostgreSQL, and
- # works with CHAR(14) as well because "i" sorts after all numbers.
+ # This is a special keyword for timestamps in PostgreSQL, and
+ # works with CHAR(14) as well because "i" sorts after all numbers.
return 'infinity';
/*
@@ -697,6 +725,48 @@ class Block
return $infinity;
*/
}
+
+ /**
+ * Convert a DB-encoded expiry into a real string that humans can read.
+ */
+ static function formatExpiry( $encoded_expiry ) {
+
+ static $msg = null;
+
+ if( is_null( $msg ) ) {
+ $msg = array();
+ $keys = array( 'infiniteblock', 'expiringblock' );
+ foreach( $keys as $key ) {
+ $msg[$key] = wfMsgHtml( $key );
+ }
+ }
+
+ $expiry = Block::decodeExpiry( $encoded_expiry );
+ if ($expiry == 'infinity') {
+ $expirystr = $msg['infiniteblock'];
+ } else {
+ global $wgLang;
+ $expiretimestr = $wgLang->timeanddate( $expiry, true );
+ $expirystr = wfMsgReplaceArgs( $msg['expiringblock'], array($expiretimestr) );
+ }
+
+ return $expirystr;
+ }
+
+ /**
+ * Convert a typed-in expiry time into something we can put into the database.
+ */
+ static function parseExpiryInput( $expiry_input ) {
+ if ( $expiry_input == 'infinite' || $expiry_input == 'indefinite' ) {
+ $expiry = 'infinity';
+ } else {
+ $expiry = strtotime( $expiry_input );
+ if ($expiry < 0 || $expiry === false) {
+ return false;
+ }
+ }
+
+ return $expiry;
+ }
}
-
diff --git a/includes/CacheDependency.php b/includes/CacheDependency.php
index 1d48c383..b050c46d 100644
--- a/includes/CacheDependency.php
+++ b/includes/CacheDependency.php
@@ -1,10 +1,10 @@
<?php
/**
- * This class stores an arbitrary value along with its dependencies.
+ * This class stores an arbitrary value along with its dependencies.
* Users should typically only use DependencyWrapper::getFromCache(), rather
* than instantiating one of these objects directly.
- * @addtogroup Cache
+ * @ingroup Cache
*/
class DependencyWrapper {
var $value;
@@ -24,7 +24,7 @@ class DependencyWrapper {
$this->deps = $deps;
}
- /**
+ /**
* Returns true if any of the dependencies have expired
*/
function isExpired() {
@@ -62,24 +62,24 @@ class DependencyWrapper {
}
/**
- * Attempt to get a value from the cache. If the value is expired or missing,
+ * Attempt to get a value from the cache. If the value is expired or missing,
* it will be generated with the callback function (if present), and the newly
- * calculated value will be stored to the cache in a wrapper.
+ * calculated value will be stored to the cache in a wrapper.
*
* @param object $cache A cache object such as $wgMemc
* @param string $key The cache key
* @param integer $expiry The expiry timestamp or interval in seconds
* @param mixed $callback The callback for generating the value, or false
* @param array $callbackParams The function parameters for the callback
- * @param array $deps The dependencies to store on a cache miss. Note: these
+ * @param array $deps The dependencies to store on a cache miss. Note: these
* are not the dependencies used on a cache hit! Cache hits use the stored
* dependency array.
*
* @return mixed The value, or null if it was not present in the cache and no
* callback was defined.
*/
- static function getValueFromCache( $cache, $key, $expiry = 0, $callback = false,
- $callbackParams = array(), $deps = array() )
+ static function getValueFromCache( $cache, $key, $expiry = 0, $callback = false,
+ $callbackParams = array(), $deps = array() )
{
$obj = $cache->get( $key );
if ( is_object( $obj ) && $obj instanceof DependencyWrapper && !$obj->isExpired() ) {
@@ -97,7 +97,7 @@ class DependencyWrapper {
}
/**
- * @addtogroup Cache
+ * @ingroup Cache
*/
abstract class CacheDependency {
/**
@@ -112,7 +112,7 @@ abstract class CacheDependency {
}
/**
- * @addtogroup Cache
+ * @ingroup Cache
*/
class FileDependency extends CacheDependency {
var $filename, $timestamp;
@@ -122,11 +122,11 @@ class FileDependency extends CacheDependency {
*
* @param string $filename The name of the file, preferably fully qualified
* @param mixed $timestamp The unix last modified timestamp, or false if the
- * file does not exist. If omitted, the timestamp will be loaded from
+ * file does not exist. If omitted, the timestamp will be loaded from
* the file.
*
- * A dependency on a nonexistent file will be triggered when the file is
- * created. A dependency on an existing file will be triggered when the
+ * A dependency on a nonexistent file will be triggered when the file is
+ * created. A dependency on an existing file will be triggered when the
* file is changed.
*/
function __construct( $filename, $timestamp = null ) {
@@ -171,7 +171,7 @@ class FileDependency extends CacheDependency {
}
/**
- * @addtogroup Cache
+ * @ingroup Cache
*/
class TitleDependency extends CacheDependency {
var $titleObj;
@@ -191,7 +191,7 @@ class TitleDependency extends CacheDependency {
function loadDependencyValues() {
$this->touched = $this->getTitle()->getTouched();
}
-
+
/**
* Get rid of bulky Title object for sleep
*/
@@ -202,7 +202,7 @@ class TitleDependency extends CacheDependency {
function getTitle() {
if ( !isset( $this->titleObj ) ) {
$this->titleObj = Title::makeTitle( $this->ns, $this->dbk );
- }
+ }
return $this->titleObj;
}
@@ -230,12 +230,12 @@ class TitleDependency extends CacheDependency {
}
/**
- * @addtogroup Cache
+ * @ingroup Cache
*/
class TitleListDependency extends CacheDependency {
var $linkBatch;
var $timestamps;
-
+
/**
* Construct a dependency on a list of titles
*/
@@ -259,7 +259,7 @@ class TitleListDependency extends CacheDependency {
if ( count( $timestamps ) ) {
$dbr = wfGetDB( DB_SLAVE );
$where = $this->getLinkBatch()->constructSet( 'page', $dbr );
- $res = $dbr->select( 'page',
+ $res = $dbr->select( 'page',
array( 'page_namespace', 'page_title', 'page_touched' ),
$where, __METHOD__ );
while ( $row = $dbr->fetchObject( $res ) ) {
@@ -313,11 +313,11 @@ class TitleListDependency extends CacheDependency {
}
/**
- * @addtogroup Cache
+ * @ingroup Cache
*/
class GlobalDependency extends CacheDependency {
var $name, $value;
-
+
function __construct( $name ) {
$this->name = $name;
$this->value = $GLOBALS[$name];
@@ -329,7 +329,7 @@ class GlobalDependency extends CacheDependency {
}
/**
- * @addtogroup Cache
+ * @ingroup Cache
*/
class ConstantDependency extends CacheDependency {
var $name, $value;
@@ -343,5 +343,3 @@ class ConstantDependency extends CacheDependency {
return constant( $this->name ) != $this->value;
}
}
-
-
diff --git a/includes/Category.php b/includes/Category.php
new file mode 100644
index 00000000..acafc47a
--- /dev/null
+++ b/includes/Category.php
@@ -0,0 +1,261 @@
+<?php
+/**
+ * Category objects are immutable, strictly speaking. If you call methods that change the database, like to refresh link counts, the objects will be appropriately reinitialized. Member variables are lazy-initialized.
+ *
+ * TODO: Move some stuff from CategoryPage.php to here, and use that.
+ *
+ * @author Simetrical
+ */
+
+class Category {
+ /** Name of the category, normalized to DB-key form */
+ private $mName = null;
+ private $mID = null;
+ /** Category page title */
+ private $mTitle = null;
+ /** Counts of membership (cat_pages, cat_subcats, cat_files) */
+ private $mPages = null, $mSubcats = null, $mFiles = null;
+
+ private function __construct() {}
+
+ /**
+ * Set up all member variables using a database query.
+ * @return bool True on success, false on failure.
+ */
+ protected function initialize() {
+ if ( $this->mName === null && $this->mTitle )
+ $this->mName = $title->getDBKey();
+
+ if( $this->mName === null && $this->mID === null ) {
+ throw new MWException( __METHOD__.' has both names and IDs null' );
+ } elseif( $this->mID === null ) {
+ $where = array( 'cat_title' => $this->mName );
+ } elseif( $this->mName === null ) {
+ $where = array( 'cat_id' => $this->mID );
+ } else {
+ # Already initialized
+ return true;
+ }
+ $dbr = wfGetDB( DB_SLAVE );
+ $row = $dbr->selectRow(
+ 'category',
+ array( 'cat_id', 'cat_title', 'cat_pages', 'cat_subcats',
+ 'cat_files' ),
+ $where,
+ __METHOD__
+ );
+ if( !$row ) {
+ # Okay, there were no contents. Nothing to initialize.
+ if ( $this->mTitle ) {
+ # If there is a title object but no record in the category table, treat this as an empty category
+ $this->mID = false;
+ $this->mName = $this->mTitle->getDBKey();
+ $this->mPages = 0;
+ $this->mSubcats = 0;
+ $this->mFiles = 0;
+
+ return true;
+ } else {
+ return false; # Fail
+ }
+ }
+ $this->mID = $row->cat_id;
+ $this->mName = $row->cat_title;
+ $this->mPages = $row->cat_pages;
+ $this->mSubcats = $row->cat_subcats;
+ $this->mFiles = $row->cat_files;
+
+ # (bug 13683) If the count is negative, then 1) it's obviously wrong
+ # and should not be kept, and 2) we *probably* don't have to scan many
+ # rows to obtain the correct figure, so let's risk a one-time recount.
+ if( $this->mPages < 0 || $this->mSubcats < 0 ||
+ $this->mFiles < 0 ) {
+ $this->refreshCounts();
+ }
+
+ return true;
+ }
+
+ /**
+ * Factory function.
+ *
+ * @param array $name A category name (no "Category:" prefix). It need
+ * not be normalized, with spaces replaced by underscores.
+ * @return mixed Category, or false on a totally invalid name
+ */
+ public static function newFromName( $name ) {
+ $cat = new self();
+ $title = Title::makeTitleSafe( NS_CATEGORY, $name );
+ if( !is_object( $title ) ) {
+ return false;
+ }
+
+ $cat->mTitle = $title;
+ $cat->mName = $title->getDBKey();
+
+ return $cat;
+ }
+
+ /**
+ * Factory function.
+ *
+ * @param array $title Title for the category page
+ * @return mixed Category, or false on a totally invalid name
+ */
+ public static function newFromTitle( $title ) {
+ $cat = new self();
+
+ $cat->mTitle = $title;
+ $cat->mName = $title->getDBKey();
+
+ return $cat;
+ }
+
+ /**
+ * Factory function.
+ *
+ * @param array $id A category id
+ * @return Category
+ */
+ public static function newFromID( $id ) {
+ $cat = new self();
+ $cat->mID = intval( $id );
+ return $cat;
+ }
+
+ /**
+ * Factory function, for constructing a Category object from a result set
+ *
+ * @param $row result set row, must contain the cat_xxx fields. If the fields are null,
+ * the resulting Category object will represent an empty category if a title object
+ * was given. If the fields are null and no title was given, this method fails and returns false.
+ * @param $title optional title object for the category represented by the given row.
+ * May be provided if it is already known, to avoid having to re-create a title object later.
+ * @return Category
+ */
+ public static function newFromRow( $row, $title = null ) {
+ $cat = new self();
+ $cat->mTitle = $title;
+
+
+ # NOTE: the row often results from a LEFT JOIN on categorylinks. This may result in
+ # all the cat_xxx fields being null, if the category page exists, but nothing
+ # was ever added to the category. This case should be treated linke an empty
+ # category, if possible.
+
+ if ( $row->cat_title === null ) {
+ if ( $title === null ) {
+ # the name is probably somewhere in the row, for example as page_title,
+ # but we can't know that here...
+ return false;
+ } else {
+ $cat->mName = $title->getDBKey(); # if we have a title object, fetch the category name from there
+ }
+
+ $cat->mID = false;
+ $cat->mSubcats = 0;
+ $cat->mPages = 0;
+ $cat->mFiles = 0;
+ } else {
+ $cat->mName = $row->cat_title;
+ $cat->mID = $row->cat_id;
+ $cat->mSubcats = $row->cat_subcats;
+ $cat->mPages = $row->cat_pages;
+ $cat->mFiles = $row->cat_files;
+ }
+
+ return $cat;
+ }
+
+ /** @return mixed DB key name, or false on failure */
+ public function getName() { return $this->getX( 'mName' ); }
+ /** @return mixed Category ID, or false on failure */
+ public function getID() { return $this->getX( 'mID' ); }
+ /** @return mixed Total number of member pages, or false on failure */
+ public function getPageCount() { return $this->getX( 'mPages' ); }
+ /** @return mixed Number of subcategories, or false on failure */
+ public function getSubcatCount() { return $this->getX( 'mSubcats' ); }
+ /** @return mixed Number of member files, or false on failure */
+ public function getFileCount() { return $this->getX( 'mFiles' ); }
+
+ /**
+ * @return mixed The Title for this category, or false on failure.
+ */
+ public function getTitle() {
+ if( $this->mTitle ) return $this->mTitle;
+
+ if( !$this->initialize() ) {
+ return false;
+ }
+
+ $this->mTitle = Title::makeTitleSafe( NS_CATEGORY, $this->mName );
+ return $this->mTitle;
+ }
+
+ /** Generic accessor */
+ private function getX( $key ) {
+ if( !$this->initialize() ) {
+ return false;
+ }
+ return $this->{$key};
+ }
+
+ /**
+ * Refresh the counts for this category.
+ *
+ * @return bool True on success, false on failure
+ */
+ public function refreshCounts() {
+ if( wfReadOnly() ) {
+ return false;
+ }
+ $dbw = wfGetDB( DB_MASTER );
+ $dbw->begin();
+ # Note, we must use names for this, since categorylinks does.
+ if( $this->mName === null ) {
+ if( !$this->initialize() ) {
+ return false;
+ }
+ } else {
+ # Let's be sure that the row exists in the table. We don't need to
+ # do this if we got the row from the table in initialization!
+ $dbw->insert(
+ 'category',
+ array( 'cat_title' => $this->mName ),
+ __METHOD__,
+ 'IGNORE'
+ );
+ }
+
+ $cond1 = $dbw->conditional( 'page_namespace='.NS_CATEGORY, 1, 'NULL' );
+ $cond2 = $dbw->conditional( 'page_namespace='.NS_IMAGE, 1, 'NULL' );
+ $result = $dbw->selectRow(
+ array( 'categorylinks', 'page' ),
+ array( 'COUNT(*) AS pages',
+ "COUNT($cond1) AS subcats",
+ "COUNT($cond2) AS files"
+ ),
+ array( 'cl_to' => $this->mName, 'page_id = cl_from' ),
+ __METHOD__,
+ 'LOCK IN SHARE MODE'
+ );
+ $ret = $dbw->update(
+ 'category',
+ array(
+ 'cat_pages' => $result->pages,
+ 'cat_subcats' => $result->subcats,
+ 'cat_files' => $result->files
+ ),
+ array( 'cat_title' => $this->mName ),
+ __METHOD__
+ );
+ $dbw->commit();
+
+ # Now we should update our local counts.
+ $this->mPages = $result->pages;
+ $this->mSubcats = $result->subcats;
+ $this->mFiles = $result->files;
+
+ return $ret;
+ }
+}
diff --git a/includes/CategoryPage.php b/includes/CategoryPage.php
index 6fbcd3c1..92e4e279 100644
--- a/includes/CategoryPage.php
+++ b/includes/CategoryPage.php
@@ -66,10 +66,12 @@ class CategoryPage extends Article {
class CategoryViewer {
var $title, $limit, $from, $until,
- $articles, $articles_start_char,
+ $articles, $articles_start_char,
$children, $children_start_char,
$showGallery, $gallery,
$skin;
+ /** Category object for this page */
+ private $cat;
function __construct( $title, $from = '', $until = '' ) {
global $wgCategoryPagingLimit;
@@ -77,8 +79,9 @@ class CategoryViewer {
$this->from = $from;
$this->until = $until;
$this->limit = $wgCategoryPagingLimit;
+ $this->cat = Category::newFromName( $title->getDBKey() );
}
-
+
/**
* Format the category data list.
*
@@ -132,12 +135,21 @@ class CategoryViewer {
}
/**
- * Add a subcategory to the internal lists
+ * Add a subcategory to the internal lists, using a Category object
+ */
+ function addSubcategoryObject( $cat, $sortkey, $pageLength ) {
+ $title = $cat->getTitle();
+ $this->addSubcategory( $title, $sortkey, $pageLength );
+ }
+
+ /**
+ * Add a subcategory to the internal lists, using a title object
+ * @deprectated kept for compatibility, please use addSubcategoryObject instead
*/
function addSubcategory( $title, $sortkey, $pageLength ) {
global $wgContLang;
// Subcategory; strip the 'Category' namespace from the link text.
- $this->children[] = $this->getSkin()->makeKnownLinkObj(
+ $this->children[] = $this->getSkin()->makeKnownLinkObj(
$title, $wgContLang->convertHtml( $title->getText() ) );
$this->children_start_char[] = $this->getSubcategorySortChar( $title, $sortkey );
@@ -152,13 +164,13 @@ class CategoryViewer {
*/
function getSubcategorySortChar( $title, $sortkey ) {
global $wgContLang;
-
+
if( $title->getPrefixedText() == $sortkey ) {
$firstChar = $wgContLang->firstChar( $title->getDBkey() );
} else {
$firstChar = $wgContLang->firstChar( $sortkey );
}
-
+
return $wgContLang->convert( $firstChar );
}
@@ -167,11 +179,10 @@ class CategoryViewer {
*/
function addImage( Title $title, $sortkey, $pageLength, $isRedirect = false ) {
if ( $this->showGallery ) {
- $image = new Image( $title );
if( $this->flip ) {
- $this->gallery->insert( $image );
+ $this->gallery->insert( $title );
} else {
- $this->gallery->add( $image );
+ $this->gallery->add( $title );
}
} else {
$this->addPage( $title, $sortkey, $pageLength, $isRedirect );
@@ -211,17 +222,17 @@ class CategoryViewer {
$this->flip = false;
}
$res = $dbr->select(
- array( 'page', 'categorylinks' ),
- array( 'page_title', 'page_namespace', 'page_len', 'page_is_redirect', 'cl_sortkey' ),
+ array( 'page', 'categorylinks', 'category' ),
+ array( 'page_title', 'page_namespace', 'page_len', 'page_is_redirect', 'cl_sortkey',
+ 'cat_id', 'cat_title', 'cat_subcats', 'cat_pages', 'cat_files' ),
array( $pageCondition,
- 'cl_from = page_id',
- 'cl_to' => $this->title->getDBkey()),
- #'page_is_redirect' => 0),
- #+ $pageCondition,
+ 'cl_to' => $this->title->getDBkey() ),
__METHOD__,
array( 'ORDER BY' => $this->flip ? 'cl_sortkey DESC' : 'cl_sortkey',
- 'USE INDEX' => 'cl_sortkey',
- 'LIMIT' => $this->limit + 1 ) );
+ 'USE INDEX' => array( 'categorylinks' => 'cl_sortkey' ),
+ 'LIMIT' => $this->limit + 1 ),
+ array( 'categorylinks' => array( 'INNER JOIN', 'cl_from = page_id' ),
+ 'category' => array( 'LEFT JOIN', 'cat_title = page_title AND page_namespace = ' . NS_CATEGORY ) ) );
$count = 0;
$this->nextPage = null;
@@ -236,7 +247,8 @@ class CategoryViewer {
$title = Title::makeTitle( $x->page_namespace, $x->page_title );
if( $title->getNamespace() == NS_CATEGORY ) {
- $this->addSubcategory( $title, $x->cl_sortkey, $x->page_len );
+ $cat = Category::newFromRow( $x, $title );
+ $this->addSubcategoryObject( $cat, $x->cl_sortkey, $x->page_len );
} elseif( $this->showGallery && $title->getNamespace() == NS_IMAGE ) {
$this->addImage( $title, $x->cl_sortkey, $x->page_len, $x->page_is_redirect );
} else {
@@ -261,12 +273,14 @@ class CategoryViewer {
function getSubcategorySection() {
# Don't show subcategories section if there are none.
$r = '';
- $c = count( $this->children );
- if( $c > 0 ) {
+ $rescnt = count( $this->children );
+ $dbcnt = $this->cat->getSubcatCount();
+ $countmsg = $this->getCountMessage( $rescnt, $dbcnt, 'subcat' );
+ if( $rescnt > 0 ) {
# Showing subcategories
$r .= "<div id=\"mw-subcategories\">\n";
$r .= '<h2>' . wfMsg( 'subcategories' ) . "</h2>\n";
- $r .= wfMsgExt( 'subcategorycount', array( 'parse' ), $c );
+ $r .= $countmsg;
$r .= $this->formatList( $this->children, $this->children_start_char );
$r .= "\n</div>";
}
@@ -277,11 +291,20 @@ class CategoryViewer {
$ti = htmlspecialchars( $this->title->getText() );
# Don't show articles section if there are none.
$r = '';
- $c = count( $this->articles );
- if( $c > 0 ) {
+
+ # FIXME, here and in the other two sections: we don't need to bother
+ # with this rigamarole if the entire category contents fit on one page
+ # and have already been retrieved. We can just use $rescnt in that
+ # case and save a query and some logic.
+ $dbcnt = $this->cat->getPageCount() - $this->cat->getSubcatCount()
+ - $this->cat->getFileCount();
+ $rescnt = count( $this->articles );
+ $countmsg = $this->getCountMessage( $rescnt, $dbcnt, 'article' );
+
+ if( $rescnt > 0 ) {
$r = "<div id=\"mw-pages\">\n";
$r .= '<h2>' . wfMsg( 'category_header', $ti ) . "</h2>\n";
- $r .= wfMsgExt( 'categoryarticlecount', array( 'parse' ), $c );
+ $r .= $countmsg;
$r .= $this->formatList( $this->articles, $this->articles_start_char );
$r .= "\n</div>";
}
@@ -290,10 +313,13 @@ class CategoryViewer {
function getImageSection() {
if( $this->showGallery && ! $this->gallery->isEmpty() ) {
+ $dbcnt = $this->cat->getFileCount();
+ $rescnt = $this->gallery->count();
+ $countmsg = $this->getCountMessage( $rescnt, $dbcnt, 'file' );
+
return "<div id=\"mw-category-media\">\n" .
'<h2>' . wfMsg( 'category-media-header', htmlspecialchars($this->title->getText()) ) . "</h2>\n" .
- wfMsgExt( 'category-media-count', array( 'parse' ), $this->gallery->count() ) .
- $this->gallery->toHTML() . "\n</div>";
+ $countmsg . $this->gallery->toHTML() . "\n</div>";
} else {
return '';
}
@@ -440,7 +466,48 @@ class CategoryViewer {
return "($prevLink) ($nextLink)";
}
-}
-
-
+ /**
+ * What to do if the category table conflicts with the number of results
+ * returned? This function says what. It works the same whether the
+ * things being counted are articles, subcategories, or files.
+ *
+ * Note for grepping: uses the messages category-article-count,
+ * category-article-count-limited, category-subcat-count,
+ * category-subcat-count-limited, category-file-count,
+ * category-file-count-limited.
+ *
+ * @param int $rescnt The number of items returned by our database query.
+ * @param int $dbcnt The number of items according to the category table.
+ * @param string $type 'subcat', 'article', or 'file'
+ * @return string A message giving the number of items, to output to HTML.
+ */
+ private function getCountMessage( $rescnt, $dbcnt, $type ) {
+ global $wgLang;
+ # There are three cases:
+ # 1) The category table figure seems sane. It might be wrong, but
+ # we can't do anything about it if we don't recalculate it on ev-
+ # ery category view.
+ # 2) The category table figure isn't sane, like it's smaller than the
+ # number of actual results, *but* the number of results is less
+ # than $this->limit and there's no offset. In this case we still
+ # know the right figure.
+ # 3) We have no idea.
+ $totalrescnt = count( $this->articles ) + count( $this->children ) +
+ ($this->showGallery ? $this->gallery->count() : 0);
+ if($dbcnt == $rescnt || (($totalrescnt == $this->limit || $this->from
+ || $this->until) && $dbcnt > $rescnt)){
+ # Case 1: seems sane.
+ $totalcnt = $dbcnt;
+ } elseif($totalrescnt < $this->limit && !$this->from && !$this->until){
+ # Case 2: not sane, but salvageable.
+ $totalcnt = $rescnt;
+ } else {
+ # Case 3: hopeless. Don't give a total count at all.
+ return wfMsgExt("category-$type-count-limited", 'parse',
+ $wgLang->formatNum( $rescnt ) );
+ }
+ return wfMsgExt( "category-$type-count", 'parse', $wgLang->formatNum( $rescnt ),
+ $wgLang->formatNum( $totalcnt ) );