summaryrefslogtreecommitdiff
path: root/includes
diff options
context:
space:
mode:
Diffstat (limited to 'includes')
-rw-r--r--includes/Action.php64
-rw-r--r--includes/AjaxDispatcher.php56
-rw-r--r--includes/AjaxResponse.php109
-rw-r--r--includes/Article.php593
-rw-r--r--includes/AuthPlugin.php22
-rw-r--r--includes/AutoLoader.php223
-rw-r--r--includes/Autopromote.php25
-rw-r--r--includes/BacklinkCache.php62
-rw-r--r--includes/Block.php100
-rw-r--r--includes/CacheHelper.php392
-rw-r--r--includes/Category.php48
-rw-r--r--includes/CategoryPage.php21
-rw-r--r--includes/CategoryViewer.php52
-rw-r--r--includes/Categoryfinder.php21
-rw-r--r--includes/Cdb.php17
-rw-r--r--includes/Cdb_PHP.php17
-rw-r--r--includes/ChangeTags.php30
-rw-r--r--includes/ChangesFeed.php28
-rw-r--r--includes/ChangesList.php276
-rw-r--r--includes/Collation.php22
-rw-r--r--includes/ConfEditor.php32
-rw-r--r--includes/Cookie.php26
-rw-r--r--includes/CryptRand.php33
-rw-r--r--includes/DataUpdate.php124
-rw-r--r--includes/DefaultSettings.php1432
-rw-r--r--includes/DeferredUpdates.php36
-rw-r--r--includes/Defines.php27
-rw-r--r--includes/DeprecatedGlobal.php55
-rw-r--r--includes/EditPage.php690
-rw-r--r--includes/Exception.php229
-rw-r--r--includes/Export.php517
-rw-r--r--includes/ExternalEdit.php14
-rw-r--r--includes/ExternalStore.php25
-rw-r--r--includes/ExternalStoreDB.php23
-rw-r--r--includes/ExternalStoreHttp.php20
-rw-r--r--includes/ExternalUser.php4
-rw-r--r--includes/FakeTitle.php23
-rw-r--r--includes/Fallback.php4
-rw-r--r--includes/Feed.php34
-rw-r--r--includes/FeedUtils.php41
-rw-r--r--includes/FileDeleteForm.php108
-rw-r--r--includes/ForkController.php25
-rw-r--r--includes/FormOptions.php35
-rw-r--r--includes/GitInfo.php214
-rw-r--r--includes/GlobalFunctions.php746
-rw-r--r--includes/HTMLForm.php716
-rw-r--r--includes/HistoryBlob.php64
-rw-r--r--includes/Hooks.php2
-rw-r--r--includes/Html.php133
-rw-r--r--includes/HttpFunctions.old.php21
-rw-r--r--includes/HttpFunctions.php72
-rw-r--r--includes/IP.php48
-rw-r--r--includes/ImageFunctions.php87
-rw-r--r--includes/ImageGallery.php55
-rw-r--r--includes/ImagePage.php468
-rw-r--r--includes/ImageQueryPage.php21
-rw-r--r--includes/Import.php57
-rw-r--r--includes/Init.php21
-rw-r--r--includes/Licenses.php45
-rw-r--r--includes/LinkFilter.php23
-rw-r--r--includes/Linker.php415
-rw-r--r--includes/LinksUpdate.php153
-rw-r--r--includes/LocalisationCache.php192
-rw-r--r--includes/MWFunction.php4
-rw-r--r--includes/MagicWord.php48
-rw-r--r--includes/Message.php95
-rw-r--r--includes/MessageBlobStore.php7
-rw-r--r--includes/Metadata.php32
-rw-r--r--includes/MimeMagic.php22
-rw-r--r--includes/Namespace.php73
-rw-r--r--includes/OutputHandler.php25
-rw-r--r--includes/OutputPage.php403
-rw-r--r--includes/PHPVersionError.php25
-rw-r--r--includes/PageQueryPage.php29
-rw-r--r--includes/Pager.php264
-rw-r--r--includes/PathRouter.php62
-rw-r--r--includes/PoolCounter.php22
-rw-r--r--includes/Preferences.php102
-rw-r--r--includes/PrefixSearch.php24
-rw-r--r--includes/ProtectionForm.php85
-rw-r--r--includes/ProxyTools.php30
-rw-r--r--includes/QueryPage.php68
-rw-r--r--includes/RecentChange.php168
-rw-r--r--includes/Revision.php255
-rw-r--r--includes/RevisionList.php48
-rw-r--r--includes/Sanitizer.php111
-rw-r--r--includes/ScopedPHPTimeout.php84
-rw-r--r--includes/SeleniumWebSettings.php19
-rw-r--r--includes/Setup.php64
-rw-r--r--includes/SiteConfiguration.php149
-rw-r--r--includes/SiteStats.php226
-rw-r--r--includes/Skin.php233
-rw-r--r--includes/SkinLegacy.php186
-rw-r--r--includes/SkinTemplate.php332
-rw-r--r--includes/SpecialPage.php217
-rw-r--r--includes/SpecialPageFactory.php36
-rw-r--r--includes/SqlDataUpdate.php150
-rw-r--r--includes/SquidPurgeClient.php42
-rw-r--r--includes/Status.php76
-rw-r--r--includes/StreamFile.php51
-rw-r--r--includes/StringUtils.php94
-rw-r--r--includes/StubObject.php22
-rw-r--r--includes/Timestamp.php229
-rw-r--r--includes/Title.php306
-rw-r--r--includes/TitleArray.php19
-rw-r--r--includes/User.php326
-rw-r--r--includes/UserArray.php20
-rw-r--r--includes/UserMailer.php58
-rw-r--r--includes/UserRightsProxy.php21
-rw-r--r--includes/ViewCountUpdate.php9
-rw-r--r--includes/WatchedItem.php105
-rw-r--r--includes/WebRequest.php114
-rw-r--r--includes/WebStart.php2
-rw-r--r--includes/Wiki.php199
-rw-r--r--includes/WikiCategoryPage.php21
-rw-r--r--includes/WikiError.php12
-rw-r--r--includes/WikiFilePage.php29
-rw-r--r--includes/WikiMap.php40
-rw-r--r--includes/WikiPage.php629
-rw-r--r--includes/Xml.php87
-rw-r--r--includes/XmlTypeCheck.php20
-rw-r--r--includes/ZhClient.php20
-rw-r--r--includes/ZhConversion.php76
-rw-r--r--includes/ZipDirectoryReader.php46
-rw-r--r--includes/actions/CachedAction.php182
-rw-r--r--includes/actions/CreditsAction.php2
-rw-r--r--includes/actions/HistoryAction.php92
-rw-r--r--includes/actions/InfoAction.php629
-rw-r--r--includes/actions/PurgeAction.php6
-rw-r--r--includes/actions/RawAction.php26
-rw-r--r--includes/actions/RevertAction.php36
-rw-r--r--includes/actions/RevisiondeleteAction.php2
-rw-r--r--includes/actions/RollbackAction.php6
-rw-r--r--includes/actions/ViewAction.php3
-rw-r--r--includes/actions/WatchAction.php12
-rw-r--r--includes/api/ApiBase.php224
-rw-r--r--includes/api/ApiBlock.php61
-rw-r--r--includes/api/ApiComparePages.php51
-rw-r--r--includes/api/ApiDelete.php75
-rw-r--r--includes/api/ApiDisabled.php2
-rw-r--r--includes/api/ApiEditPage.php148
-rw-r--r--includes/api/ApiEmailUser.php24
-rw-r--r--includes/api/ApiExpandTemplates.php10
-rw-r--r--includes/api/ApiFeedContributions.php10
-rw-r--r--includes/api/ApiFeedWatchlist.php9
-rw-r--r--includes/api/ApiFileRevert.php38
-rw-r--r--includes/api/ApiFormatBase.php17
-rw-r--r--includes/api/ApiFormatDbg.php2
-rw-r--r--includes/api/ApiFormatJson.php2
-rw-r--r--includes/api/ApiFormatPhp.php2
-rw-r--r--includes/api/ApiFormatRaw.php2
-rw-r--r--includes/api/ApiFormatTxt.php2
-rw-r--r--includes/api/ApiFormatWddx.php2
-rw-r--r--includes/api/ApiFormatXml.php41
-rw-r--r--includes/api/ApiFormatYaml.php2
-rw-r--r--includes/api/ApiHelp.php2
-rw-r--r--includes/api/ApiImport.php42
-rw-r--r--includes/api/ApiLogin.php64
-rw-r--r--includes/api/ApiLogout.php6
-rw-r--r--includes/api/ApiMain.php161
-rw-r--r--includes/api/ApiMove.php51
-rw-r--r--includes/api/ApiOpenSearch.php4
-rw-r--r--includes/api/ApiOptions.php183
-rw-r--r--includes/api/ApiPageSet.php30
-rw-r--r--includes/api/ApiParamInfo.php58
-rw-r--r--includes/api/ApiParse.php115
-rw-r--r--includes/api/ApiPatrol.php15
-rw-r--r--includes/api/ApiProtect.php62
-rw-r--r--includes/api/ApiPurge.php38
-rw-r--r--includes/api/ApiQuery.php96
-rw-r--r--includes/api/ApiQueryAllCategories.php57
-rw-r--r--includes/api/ApiQueryAllImages.php409
-rw-r--r--includes/api/ApiQueryAllLinks.php68
-rw-r--r--includes/api/ApiQueryAllMessages.php (renamed from includes/api/ApiQueryAllmessages.php)25
-rw-r--r--includes/api/ApiQueryAllPages.php (renamed from includes/api/ApiQueryAllpages.php)45
-rw-r--r--includes/api/ApiQueryAllUsers.php103
-rw-r--r--includes/api/ApiQueryAllimages.php267
-rw-r--r--includes/api/ApiQueryBacklinks.php100
-rw-r--r--includes/api/ApiQueryBase.php13
-rw-r--r--includes/api/ApiQueryBlocks.php87
-rw-r--r--includes/api/ApiQueryCategories.php45
-rw-r--r--includes/api/ApiQueryCategoryInfo.php35
-rw-r--r--includes/api/ApiQueryCategoryMembers.php69
-rw-r--r--includes/api/ApiQueryDeletedrevs.php40
-rw-r--r--includes/api/ApiQueryDisabled.php2
-rw-r--r--includes/api/ApiQueryDuplicateFiles.php143
-rw-r--r--includes/api/ApiQueryExtLinksUsage.php17
-rw-r--r--includes/api/ApiQueryExternalLinks.php10
-rw-r--r--includes/api/ApiQueryFilearchive.php110
-rw-r--r--includes/api/ApiQueryIWBacklinks.php59
-rw-r--r--includes/api/ApiQueryIWLinks.php43
-rw-r--r--includes/api/ApiQueryImageInfo.php145
-rw-r--r--includes/api/ApiQueryImages.php38
-rw-r--r--includes/api/ApiQueryInfo.php259
-rw-r--r--includes/api/ApiQueryLangBacklinks.php59
-rw-r--r--includes/api/ApiQueryLangLinks.php38
-rw-r--r--includes/api/ApiQueryLinks.php43
-rw-r--r--includes/api/ApiQueryLogEvents.php66
-rw-r--r--includes/api/ApiQueryProtectedTitles.php38
-rw-r--r--includes/api/ApiQueryQueryPage.php37
-rw-r--r--includes/api/ApiQueryRandom.php10
-rw-r--r--includes/api/ApiQueryRecentChanges.php147
-rw-r--r--includes/api/ApiQueryRevisions.php98
-rw-r--r--includes/api/ApiQuerySearch.php59
-rw-r--r--includes/api/ApiQuerySiteinfo.php66
-rw-r--r--includes/api/ApiQueryStashImageInfo.php6
-rw-r--r--includes/api/ApiQueryTags.php21
-rw-r--r--includes/api/ApiQueryUserContributions.php100
-rw-r--r--includes/api/ApiQueryUserInfo.php74
-rw-r--r--includes/api/ApiQueryUsers.php96
-rw-r--r--includes/api/ApiQueryWatchlist.php85
-rw-r--r--includes/api/ApiQueryWatchlistRaw.php50
-rw-r--r--includes/api/ApiResult.php4
-rw-r--r--includes/api/ApiRollback.php26
-rw-r--r--includes/api/ApiSetNotificationTimestamp.php285
-rw-r--r--includes/api/ApiTokens.php158
-rw-r--r--includes/api/ApiUnblock.php48
-rw-r--r--includes/api/ApiUndelete.php22
-rw-r--r--includes/api/ApiUpload.php130
-rw-r--r--includes/api/ApiUserrights.php8
-rw-r--r--includes/api/ApiWatch.php18
-rw-r--r--includes/cache/CacheDependency.php23
-rw-r--r--includes/cache/FileCacheBase.php35
-rw-r--r--includes/cache/GenderCache.php93
-rw-r--r--includes/cache/HTMLCacheUpdate.php21
-rw-r--r--includes/cache/HTMLFileCache.php33
-rw-r--r--includes/cache/LinkBatch.php28
-rw-r--r--includes/cache/LinkCache.php22
-rw-r--r--includes/cache/MemcachedSessions.php98
-rw-r--r--includes/cache/MessageCache.php40
-rw-r--r--includes/cache/ObjectFileCache.php24
-rw-r--r--includes/cache/ProcessCacheLRU.php120
-rw-r--r--includes/cache/ResourceFileCache.php24
-rw-r--r--includes/cache/SquidUpdate.php64
-rw-r--r--includes/cache/UserCache.php134
-rw-r--r--includes/dao/IDBAccessObject.php55
-rw-r--r--includes/db/CloneDatabase.php1
-rw-r--r--includes/db/Database.php701
-rw-r--r--includes/db/DatabaseError.php27
-rw-r--r--includes/db/DatabaseIbm_db2.php165
-rw-r--r--includes/db/DatabaseMssql.php53
-rw-r--r--includes/db/DatabaseMysql.php159
-rw-r--r--includes/db/DatabaseOracle.php48
-rw-r--r--includes/db/DatabasePostgres.php622
-rw-r--r--includes/db/DatabaseSqlite.php80
-rw-r--r--includes/db/DatabaseUtility.php28
-rw-r--r--includes/db/IORMRow.php275
-rw-r--r--includes/db/IORMTable.php448
-rw-r--r--includes/db/LBFactory.php29
-rw-r--r--includes/db/LBFactory_Multi.php17
-rw-r--r--includes/db/LBFactory_Single.php21
-rw-r--r--includes/db/LoadBalancer.php25
-rw-r--r--includes/db/LoadMonitor.php17
-rw-r--r--includes/db/ORMIterator.php31
-rw-r--r--includes/db/ORMResult.php123
-rw-r--r--includes/db/ORMRow.php663
-rw-r--r--includes/db/ORMTable.php675
-rw-r--r--includes/debug/Debug.php371
-rw-r--r--includes/diff/DairikiDiff.php20
-rw-r--r--includes/diff/DifferenceEngine.php88
-rw-r--r--includes/filebackend/FSFile.php (renamed from includes/filerepo/backend/FSFile.php)29
-rw-r--r--includes/filebackend/FSFileBackend.php986
-rw-r--r--includes/filebackend/FileBackend.php1173
-rw-r--r--includes/filebackend/FileBackendGroup.php (renamed from includes/filerepo/backend/FileBackendGroup.php)37
-rw-r--r--includes/filebackend/FileBackendMultiWrite.php689
-rw-r--r--includes/filebackend/FileBackendStore.php1766
-rw-r--r--includes/filebackend/FileOp.php (renamed from includes/filerepo/backend/FileOp.php)523
-rw-r--r--includes/filebackend/FileOpBatch.php240
-rw-r--r--includes/filebackend/SwiftFileBackend.php1544
-rw-r--r--includes/filebackend/TempFSFile.php (renamed from includes/filerepo/backend/TempFSFile.php)41
-rw-r--r--includes/filebackend/filejournal/DBFileJournal.php152
-rw-r--r--includes/filebackend/filejournal/FileJournal.php196
-rw-r--r--includes/filebackend/lockmanager/DBLockManager.php374
-rw-r--r--includes/filebackend/lockmanager/FSLockManager.php (renamed from includes/filerepo/backend/lockmanager/FSLockManager.php)89
-rw-r--r--includes/filebackend/lockmanager/LSLockManager.php218
-rw-r--r--includes/filebackend/lockmanager/LockManager.php425
-rw-r--r--includes/filebackend/lockmanager/LockManagerGroup.php (renamed from includes/filerepo/backend/lockmanager/LockManagerGroup.php)62
-rw-r--r--includes/filebackend/lockmanager/MemcLockManager.php319
-rw-r--r--includes/filerepo/FSRepo.php20
-rw-r--r--includes/filerepo/FileRepo.php659
-rw-r--r--includes/filerepo/FileRepoStatus.php17
-rw-r--r--includes/filerepo/ForeignAPIRepo.php138
-rw-r--r--includes/filerepo/ForeignDBRepo.php40
-rw-r--r--includes/filerepo/ForeignDBViaLBRepo.php37
-rw-r--r--includes/filerepo/LocalRepo.php66
-rw-r--r--includes/filerepo/NullRepo.php54
-rw-r--r--includes/filerepo/RepoGroup.php120
-rw-r--r--includes/filerepo/backend/FSFileBackend.php600
-rw-r--r--includes/filerepo/backend/FileBackend.php1739
-rw-r--r--includes/filerepo/backend/FileBackendMultiWrite.php420
-rw-r--r--includes/filerepo/backend/SwiftFileBackend.php877
-rw-r--r--includes/filerepo/backend/lockmanager/DBLockManager.php469
-rw-r--r--includes/filerepo/backend/lockmanager/LSLockManager.php295
-rw-r--r--includes/filerepo/backend/lockmanager/LockManager.php182
-rw-r--r--includes/filerepo/file/ArchivedFile.php21
-rw-r--r--includes/filerepo/file/File.php219
-rw-r--r--includes/filerepo/file/ForeignAPIFile.php90
-rw-r--r--includes/filerepo/file/ForeignDBFile.php46
-rw-r--r--includes/filerepo/file/LocalFile.php491
-rw-r--r--includes/filerepo/file/OldLocalFile.php103
-rw-r--r--includes/filerepo/file/UnregisteredLocalFile.php57
-rw-r--r--includes/installer/CliInstaller.php21
-rw-r--r--includes/installer/DatabaseInstaller.php38
-rw-r--r--includes/installer/DatabaseUpdater.php127
-rw-r--r--includes/installer/Ibm_db2Installer.php17
-rw-r--r--includes/installer/Ibm_db2Updater.php25
-rw-r--r--includes/installer/InstallDocFormatter.php20
-rw-r--r--includes/installer/Installer.i18n.php7
-rw-r--r--includes/installer/Installer.php98
-rw-r--r--includes/installer/LocalSettingsGenerator.php34
-rw-r--r--includes/installer/MysqlInstaller.php33
-rw-r--r--includes/installer/MysqlUpdater.php115
-rw-r--r--includes/installer/OracleInstaller.php20
-rw-r--r--includes/installer/OracleUpdater.php59
-rw-r--r--includes/installer/PostgresInstaller.php57
-rw-r--r--includes/installer/PostgresUpdater.php248
-rw-r--r--includes/installer/SqliteInstaller.php17
-rw-r--r--includes/installer/SqliteUpdater.php33
-rw-r--r--includes/installer/WebInstaller.php57
-rw-r--r--includes/installer/WebInstallerOutput.php26
-rw-r--r--includes/installer/WebInstallerPage.php101
-rw-r--r--includes/interwiki/Interwiki.php41
-rw-r--r--includes/job/DoubleRedirectJob.php30
-rw-r--r--includes/job/EmaillingJob.php15
-rw-r--r--includes/job/EnotifNotifyJob.php15
-rw-r--r--includes/job/Job.php (renamed from includes/job/JobQueue.php)92
-rw-r--r--includes/job/RefreshLinksJob.php162
-rw-r--r--includes/job/UploadFromUrlJob.php33
-rw-r--r--includes/json/FormatJson.php32
-rw-r--r--includes/json/Services_JSON.php1
-rw-r--r--includes/libs/CSSJanus.php16
-rw-r--r--includes/libs/CSSMin.php26
-rw-r--r--includes/libs/GenericArrayObject.php244
-rw-r--r--includes/libs/HttpStatus.php21
-rw-r--r--includes/libs/IEContentAnalyzer.php6
-rw-r--r--includes/libs/IEUrlExtension.php26
-rw-r--r--includes/libs/JavaScriptMinifier.php10
-rw-r--r--includes/libs/jsminplus.php2
-rw-r--r--includes/logging/LogEntry.php43
-rw-r--r--includes/logging/LogEventsList.php347
-rw-r--r--includes/logging/LogFormatter.php393
-rw-r--r--includes/logging/LogPage.php72
-rw-r--r--includes/logging/LogPager.php2
-rw-r--r--includes/logging/PatrolLog.php53
-rw-r--r--includes/media/BMP.php17
-rw-r--r--includes/media/Bitmap.php64
-rw-r--r--includes/media/BitmapMetadataHandler.php41
-rw-r--r--includes/media/Bitmap_ClientOnly.php20
-rw-r--r--includes/media/DjVu.php50
-rw-r--r--includes/media/DjVuImage.php4
-rw-r--r--includes/media/Exif.php9
-rw-r--r--includes/media/ExifBitmap.php20
-rw-r--r--includes/media/FormatMetadata.php125
-rw-r--r--includes/media/GIF.php30
-rw-r--r--includes/media/GIFMetadataExtractor.php17
-rw-r--r--includes/media/IPTC.php31
-rw-r--r--includes/media/ImageHandler.php249
-rw-r--r--includes/media/Jpeg.php17
-rw-r--r--includes/media/JpegMetadataExtractor.php44
-rw-r--r--includes/media/MediaHandler.php (renamed from includes/media/Generic.php)287
-rw-r--r--includes/media/MediaTransformOutput.php99
-rw-r--r--includes/media/PNG.php29
-rw-r--r--includes/media/PNGMetadataExtractor.php16
-rw-r--r--includes/media/SVG.php79
-rw-r--r--includes/media/SVGMetadataExtractor.php33
-rw-r--r--includes/media/Tiff.php15
-rw-r--r--includes/media/XCF.php17
-rw-r--r--includes/media/XMP.php62
-rw-r--r--includes/media/XMPInfo.php22
-rw-r--r--includes/media/XMPValidate.php22
-rw-r--r--includes/mobile/DeviceDetection.php459
-rw-r--r--includes/normal/RandomTest.php4
-rw-r--r--includes/normal/UtfNormal.php3
-rw-r--r--includes/normal/UtfNormalDefines.php15
-rw-r--r--includes/normal/UtfNormalTest.php1
-rw-r--r--includes/normal/UtfNormalTest2.php18
-rw-r--r--includes/objectcache/APCBagOStuff.php60
-rw-r--r--includes/objectcache/BagOStuff.php119
-rw-r--r--includes/objectcache/DBABagOStuff.php127
-rw-r--r--includes/objectcache/EhcacheBagOStuff.php82
-rw-r--r--includes/objectcache/EmptyBagOStuff.php37
-rw-r--r--includes/objectcache/HashBagOStuff.php44
-rw-r--r--includes/objectcache/MemcachedBagOStuff.php180
-rw-r--r--includes/objectcache/MemcachedClient.php281
-rw-r--r--includes/objectcache/MemcachedPeclBagOStuff.php237
-rw-r--r--includes/objectcache/MemcachedPhpBagOStuff.php139
-rw-r--r--includes/objectcache/MultiWriteBagOStuff.php86
-rw-r--r--includes/objectcache/ObjectCache.php48
-rw-r--r--includes/objectcache/ObjectCacheSessionHandler.php145
-rw-r--r--includes/objectcache/RedisBagOStuff.php413
-rw-r--r--includes/objectcache/SqlBagOStuff.php314
-rw-r--r--includes/objectcache/WinCacheBagOStuff.php24
-rw-r--r--includes/objectcache/XCacheBagOStuff.php44
-rw-r--r--includes/parser/CacheTime.php132
-rw-r--r--includes/parser/CoreLinkFunctions.php16
-rw-r--r--includes/parser/CoreParserFunctions.php169
-rw-r--r--includes/parser/CoreTagHooks.php16
-rw-r--r--includes/parser/DateFormatter.php91
-rw-r--r--includes/parser/LinkHolderArray.php32
-rw-r--r--includes/parser/Parser.php373
-rw-r--r--includes/parser/ParserCache.php33
-rw-r--r--includes/parser/ParserOptions.php55
-rw-r--r--includes/parser/ParserOutput.php175
-rw-r--r--includes/parser/Parser_DiffTest.php16
-rw-r--r--includes/parser/Parser_LinkHooks.php20
-rw-r--r--includes/parser/Preprocessor.php28
-rw-r--r--includes/parser/Preprocessor_DOM.php80
-rw-r--r--includes/parser/Preprocessor_Hash.php78
-rw-r--r--includes/parser/Preprocessor_HipHop.hphp106
-rw-r--r--includes/parser/StripState.php55
-rw-r--r--includes/parser/Tidy.php22
-rw-r--r--includes/profiler/Profiler.php131
-rw-r--r--includes/profiler/ProfilerSimple.php78
-rw-r--r--includes/profiler/ProfilerSimpleText.php17
-rw-r--r--includes/profiler/ProfilerSimpleTrace.php36
-rw-r--r--includes/profiler/ProfilerSimpleUDP.php21
-rw-r--r--includes/profiler/ProfilerStub.php27
-rw-r--r--includes/resourceloader/ResourceLoader.php166
-rw-r--r--includes/resourceloader/ResourceLoaderContext.php13
-rw-r--r--includes/resourceloader/ResourceLoaderFileModule.php15
-rw-r--r--includes/resourceloader/ResourceLoaderFilePageModule.php21
-rw-r--r--includes/resourceloader/ResourceLoaderLanguageDataModule.php122
-rw-r--r--includes/resourceloader/ResourceLoaderModule.php21
-rw-r--r--includes/resourceloader/ResourceLoaderNoscriptModule.php2
-rw-r--r--includes/resourceloader/ResourceLoaderSiteModule.php2
-rw-r--r--includes/resourceloader/ResourceLoaderStartUpModule.php54
-rw-r--r--includes/resourceloader/ResourceLoaderUserCSSPrefsModule.php14
-rw-r--r--includes/resourceloader/ResourceLoaderUserGroupsModule.php39
-rw-r--r--includes/resourceloader/ResourceLoaderUserModule.php57
-rw-r--r--includes/resourceloader/ResourceLoaderUserOptionsModule.php11
-rw-r--r--includes/resourceloader/ResourceLoaderUserTokensModule.php9
-rw-r--r--includes/resourceloader/ResourceLoaderWikiModule.php19
-rw-r--r--includes/revisiondelete/RevisionDelete.php152
-rw-r--r--includes/revisiondelete/RevisionDeleteAbstracts.php38
-rw-r--r--includes/revisiondelete/RevisionDeleteUser.php22
-rw-r--r--includes/revisiondelete/RevisionDeleter.php84
-rw-r--r--includes/search/SearchEngine.php47
-rw-r--r--includes/search/SearchIBM_DB2.php5
-rw-r--r--includes/search/SearchMssql.php7
-rw-r--r--includes/search/SearchMySQL.php5
-rw-r--r--includes/search/SearchOracle.php4
-rw-r--r--includes/search/SearchPostgres.php1
-rw-r--r--includes/search/SearchSqlite.php1
-rw-r--r--includes/search/SearchUpdate.php15
-rw-r--r--includes/specials/SpecialActiveusers.php54
-rw-r--r--includes/specials/SpecialAllmessages.php22
-rw-r--r--includes/specials/SpecialAllpages.php75
-rw-r--r--includes/specials/SpecialAncientpages.php6
-rw-r--r--includes/specials/SpecialBlock.php196
-rw-r--r--includes/specials/SpecialBlockList.php2
-rw-r--r--includes/specials/SpecialBooksources.php13
-rw-r--r--includes/specials/SpecialBrokenRedirects.php8
-rw-r--r--includes/specials/SpecialCachedPage.php198
-rw-r--r--includes/specials/SpecialCategories.php9
-rw-r--r--includes/specials/SpecialChangeEmail.php84
-rw-r--r--includes/specials/SpecialChangePassword.php31
-rw-r--r--includes/specials/SpecialConfirmemail.php4
-rw-r--r--includes/specials/SpecialContributions.php413
-rw-r--r--includes/specials/SpecialDeadendpages.php10
-rw-r--r--includes/specials/SpecialDeletedContributions.php55
-rw-r--r--includes/specials/SpecialDisambiguations.php75
-rw-r--r--includes/specials/SpecialDoubleRedirects.php16
-rw-r--r--includes/specials/SpecialEditWatchlist.php84
-rw-r--r--includes/specials/SpecialEmailuser.php74
-rw-r--r--includes/specials/SpecialExport.php49
-rw-r--r--includes/specials/SpecialFewestrevisions.php16
-rw-r--r--includes/specials/SpecialFileDuplicateSearch.php30
-rw-r--r--includes/specials/SpecialFilepath.php6
-rw-r--r--includes/specials/SpecialImport.php97
-rw-r--r--includes/specials/SpecialJavaScriptTest.php61
-rw-r--r--includes/specials/SpecialLinkSearch.php29
-rw-r--r--includes/specials/SpecialListfiles.php60
-rw-r--r--includes/specials/SpecialListgrouprights.php44
-rw-r--r--includes/specials/SpecialListredirects.php8
-rw-r--r--includes/specials/SpecialListusers.php126
-rw-r--r--includes/specials/SpecialLockdb.php10
-rw-r--r--includes/specials/SpecialLog.php35
-rw-r--r--includes/specials/SpecialLonelypages.php8
-rw-r--r--includes/specials/SpecialMIMEsearch.php31
-rw-r--r--includes/specials/SpecialMergeHistory.php66
-rw-r--r--includes/specials/SpecialMostcategories.php40
-rw-r--r--includes/specials/SpecialMostimages.php6
-rw-r--r--includes/specials/SpecialMostinterwikis.php112
-rw-r--r--includes/specials/SpecialMostlinked.php17
-rw-r--r--includes/specials/SpecialMostlinkedcategories.php22
-rw-r--r--includes/specials/SpecialMostlinkedtemplates.php24
-rw-r--r--includes/specials/SpecialMovepage.php77
-rw-r--r--includes/specials/SpecialNewimages.php34
-rw-r--r--includes/specials/SpecialNewpages.php66
-rw-r--r--includes/specials/SpecialPasswordReset.php17
-rw-r--r--includes/specials/SpecialPopularpages.php14
-rw-r--r--includes/specials/SpecialPreferences.php7
-rw-r--r--includes/specials/SpecialPrefixindex.php78
-rw-r--r--includes/specials/SpecialProtectedpages.php89
-rw-r--r--includes/specials/SpecialProtectedtitles.php55
-rw-r--r--includes/specials/SpecialRandompage.php2
-rw-r--r--includes/specials/SpecialRecentchanges.php119
-rw-r--r--includes/specials/SpecialRecentchangeslinked.php23
-rw-r--r--includes/specials/SpecialRevisiondelete.php105
-rw-r--r--includes/specials/SpecialSearch.php159
-rw-r--r--includes/specials/SpecialShortpages.php55
-rw-r--r--includes/specials/SpecialStatistics.php46
-rw-r--r--includes/specials/SpecialTags.php27
-rw-r--r--includes/specials/SpecialUnblock.php15
-rw-r--r--includes/specials/SpecialUncategorizedimages.php6
-rw-r--r--includes/specials/SpecialUncategorizedpages.php6
-rw-r--r--includes/specials/SpecialUndelete.php111
-rw-r--r--includes/specials/SpecialUnusedcategories.php7
-rw-r--r--includes/specials/SpecialUnusedimages.php8
-rw-r--r--includes/specials/SpecialUnusedtemplates.php16
-rw-r--r--includes/specials/SpecialUnwatchedpages.php20
-rw-r--r--includes/specials/SpecialUpload.php141
-rw-r--r--includes/specials/SpecialUploadStash.php44
-rw-r--r--includes/specials/SpecialUserlogin.php158
-rw-r--r--includes/specials/SpecialUserlogout.php2
-rw-r--r--includes/specials/SpecialUserrights.php38
-rw-r--r--includes/specials/SpecialVersion.php256
-rw-r--r--includes/specials/SpecialWantedcategories.php6
-rw-r--r--includes/specials/SpecialWantedfiles.php9
-rw-r--r--includes/specials/SpecialWantedpages.php8
-rw-r--r--includes/specials/SpecialWantedtemplates.php8
-rw-r--r--includes/specials/SpecialWatchlist.php81
-rw-r--r--includes/specials/SpecialWhatlinkshere.php44
-rw-r--r--includes/specials/SpecialWithoutinterwiki.php18
-rw-r--r--includes/templates/NoLocalSettings.php17
-rw-r--r--includes/templates/Usercreate.php22
-rw-r--r--includes/templates/Userlogin.php38
-rw-r--r--includes/tidy.conf1
-rw-r--r--includes/upload/UploadBase.php148
-rw-r--r--includes/upload/UploadFromChunks.php122
-rw-r--r--includes/upload/UploadFromFile.php33
-rw-r--r--includes/upload/UploadFromStash.php28
-rw-r--r--includes/upload/UploadFromUrl.php86
-rw-r--r--includes/upload/UploadStash.php48
-rw-r--r--includes/zhtable/Makefile.py14
-rw-r--r--includes/zhtable/simp2trad.manual1
-rw-r--r--includes/zhtable/toCN.manual1
-rw-r--r--includes/zhtable/toHK.manual58
-rw-r--r--includes/zhtable/toTW.manual1
-rw-r--r--includes/zhtable/trad2simp.manual1
-rw-r--r--includes/zhtable/tradphrases.manual3
541 files changed, 41910 insertions, 16311 deletions
diff --git a/includes/Action.php b/includes/Action.php
index 37c48488..51922251 100644
--- a/includes/Action.php
+++ b/includes/Action.php
@@ -1,15 +1,6 @@
<?php
/**
- * @defgroup Actions Action done on pages
- */
-
-/**
- * Actions are things which can be done to pages (edit, delete, rollback, etc). They
- * are distinct from Special Pages because an action must apply to exactly one page.
- *
- * To add an action in an extension, create a subclass of Action, and add the key to
- * $wgActions. There is also the deprecated UnknownAction hook
- *
+ * Base classes for actions done on pages.
*
* 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
@@ -27,23 +18,39 @@
*
* @file
*/
+
+/**
+ * @defgroup Actions Action done on pages
+ */
+
+/**
+ * Actions are things which can be done to pages (edit, delete, rollback, etc). They
+ * are distinct from Special Pages because an action must apply to exactly one page.
+ *
+ * To add an action in an extension, create a subclass of Action, and add the key to
+ * $wgActions. There is also the deprecated UnknownAction hook
+ *
+ * Actions generally fall into two groups: the show-a-form-then-do-something-with-the-input
+ * format (protect, delete, move, etc), and the just-do-something format (watch, rollback,
+ * patrol, etc). The FormAction and FormlessAction classes respresent these two groups.
+ */
abstract class Action {
/**
* Page on which we're performing the action
- * @var Page
+ * @var Page $page
*/
protected $page;
/**
* IContextSource if specified; otherwise we'll use the Context from the Page
- * @var IContextSource
+ * @var IContextSource $context
*/
protected $context;
/**
* The fields used to create the HTMLForm
- * @var Array
+ * @var Array $fields
*/
protected $fields;
@@ -78,7 +85,7 @@ abstract class Action {
* @param $action String
* @param $page Page
* @param $context IContextSource
- * @return Action|false|null false if the action is disabled, null
+ * @return Action|bool|null false if the action is disabled, null
* if it is not recognised
*/
public final static function factory( $action, Page $page, IContextSource $context = null ) {
@@ -128,7 +135,7 @@ abstract class Action {
if ( !$context->canUseWikiPage() ) {
return 'view';
}
-
+
$action = Action::factory( $actionName, $context->getWikiPage() );
if ( $action instanceof Action ) {
return $action->getName();
@@ -266,6 +273,7 @@ abstract class Action {
*
* @param $user User: the user to check, or null to use the context user
* @throws ErrorPageError
+ * @return bool True on success
*/
protected function checkCanExecute( User $user ) {
$right = $this->getRestriction();
@@ -277,7 +285,7 @@ abstract class Action {
}
if ( $this->requiresUnblock() && $user->isBlocked() ) {
- $block = $user->mBlock;
+ $block = $user->getBlock();
throw new UserBlockedError( $block );
}
@@ -287,6 +295,7 @@ abstract class Action {
if ( $this->requiresWrite() && wfReadOnly() ) {
throw new ReadOnlyError();
}
+ return true;
}
/**
@@ -332,7 +341,7 @@ abstract class Action {
* @return String
*/
protected function getDescription() {
- return wfMsgHtml( strtolower( $this->getName() ) );
+ return $this->msg( strtolower( $this->getName() ) )->escaped();
}
/**
@@ -350,6 +359,9 @@ abstract class Action {
public abstract function execute();
}
+/**
+ * An action which shows a form and does something based on the input from the form
+ */
abstract class FormAction extends Action {
/**
@@ -385,7 +397,7 @@ abstract class FormAction extends Action {
// Give hooks a chance to alter the form, adding extra fields or text etc
wfRunHooks( 'ActionModifyFormFields', array( $this->getName(), &$this->fields, $this->page ) );
- $form = new HTMLForm( $this->fields, $this->getContext() );
+ $form = new HTMLForm( $this->fields, $this->getContext(), $this->getName() );
$form->setSubmitCallback( array( $this, 'onSubmit' ) );
// Retain query parameters (uselang etc)
@@ -444,8 +456,8 @@ abstract class FormAction extends Action {
/**
* @see Action::execute()
* @throws ErrorPageError
- * @param array|null $data
- * @param bool $captureErrors
+ * @param $data array|null
+ * @param $captureErrors bool
* @return bool
*/
public function execute( array $data = null, $captureErrors = true ) {
@@ -486,9 +498,7 @@ abstract class FormAction extends Action {
}
/**
- * Actions generally fall into two groups: the show-a-form-then-do-something-with-the-input
- * format (protect, delete, move, etc), and the just-do-something format (watch, rollback,
- * patrol, etc).
+ * An action which just does something, without showing a form first.
*/
abstract class FormlessAction extends Action {
@@ -501,15 +511,23 @@ abstract class FormlessAction extends Action {
/**
* We don't want an HTMLForm
+ * @return bool
*/
protected function getFormFields() {
return false;
}
+ /**
+ * @param $data Array
+ * @return bool
+ */
public function onSubmit( $data ) {
return false;
}
+ /**
+ * @return bool
+ */
public function onSuccess() {
return false;
}
diff --git a/includes/AjaxDispatcher.php b/includes/AjaxDispatcher.php
index 5bc9f067..b00cf309 100644
--- a/includes/AjaxDispatcher.php
+++ b/includes/AjaxDispatcher.php
@@ -1,10 +1,28 @@
<?php
/**
- * @defgroup Ajax Ajax
+ * Handle ajax requests and send them to the proper handler.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * http://www.gnu.org/copyleft/gpl.html
*
* @file
* @ingroup Ajax
- * Handle ajax requests and send them to the proper handler.
+ */
+
+/**
+ * @defgroup Ajax Ajax
*/
/**
@@ -12,16 +30,26 @@
* @ingroup Ajax
*/
class AjaxDispatcher {
- /** The way the request was made, either a 'get' or a 'post' */
+ /**
+ * The way the request was made, either a 'get' or a 'post'
+ * @var string $mode
+ */
private $mode;
- /** Name of the requested handler */
+ /**
+ * Name of the requested handler
+ * @var string $func_name
+ */
private $func_name;
- /** Arguments passed */
+ /** Arguments passed
+ * @var array $args
+ */
private $args;
- /** Load up our object with user supplied data */
+ /**
+ * Load up our object with user supplied data
+ */
function __construct() {
wfProfileIn( __METHOD__ );
@@ -62,13 +90,14 @@ class AjaxDispatcher {
wfProfileOut( __METHOD__ );
}
- /** Pass the request to our internal function.
+ /**
+ * Pass the request to our internal function.
* BEWARE! Data are passed as they have been supplied by the user,
* they should be carefully handled in the function processing the
* request.
*/
function performAction() {
- global $wgAjaxExportList, $wgOut, $wgUser;
+ global $wgAjaxExportList, $wgUser;
if ( empty( $this->mode ) ) {
return;
@@ -84,7 +113,7 @@ class AjaxDispatcher {
'Bad Request',
"unknown function " . (string) $this->func_name
);
- } elseif ( !in_array( 'read', User::getGroupPermissions( array( '*' ) ), true )
+ } elseif ( !in_array( 'read', User::getGroupPermissions( array( '*' ) ), true )
&& !$wgUser->isAllowed( 'read' ) )
{
wfHttpError(
@@ -94,14 +123,8 @@ class AjaxDispatcher {
} else {
wfDebug( __METHOD__ . ' dispatching ' . $this->func_name . "\n" );
- if ( strpos( $this->func_name, '::' ) !== false ) {
- $func = explode( '::', $this->func_name, 2 );
- } else {
- $func = $this->func_name;
- }
-
try {
- $result = call_user_func_array( $func, $this->args );
+ $result = call_user_func_array( $this->func_name, $this->args );
if ( $result === false || $result === null ) {
wfDebug( __METHOD__ . ' ERROR while dispatching '
@@ -134,7 +157,6 @@ class AjaxDispatcher {
}
}
- $wgOut = null;
wfProfileOut( __METHOD__ );
}
}
diff --git a/includes/AjaxResponse.php b/includes/AjaxResponse.php
index e60ca23c..6bf94ccb 100644
--- a/includes/AjaxResponse.php
+++ b/includes/AjaxResponse.php
@@ -1,6 +1,21 @@
<?php
/**
- * Response handler for Ajax requests
+ * Response handler for Ajax requests.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * http://www.gnu.org/copyleft/gpl.html
*
* @file
* @ingroup Ajax
@@ -13,27 +28,52 @@
* @ingroup Ajax
*/
class AjaxResponse {
- /** Number of seconds to get the response cached by a proxy */
+
+ /**
+ * Number of seconds to get the response cached by a proxy
+ * @var int $mCacheDuration
+ */
private $mCacheDuration;
- /** HTTP header Content-Type */
+ /**
+ * HTTP header Content-Type
+ * @var string $mContentType
+ */
private $mContentType;
- /** Disables output. Can be set by calling $AjaxResponse->disable() */
+ /**
+ * Disables output. Can be set by calling $AjaxResponse->disable()
+ * @var bool $mDisabled
+ */
private $mDisabled;
- /** Date for the HTTP header Last-modified */
+ /**
+ * Date for the HTTP header Last-modified
+ * @var string|false $mLastModified
+ */
private $mLastModified;
- /** HTTP response code */
+ /**
+ * HTTP response code
+ * @var string $mResponseCode
+ */
private $mResponseCode;
- /** HTTP Vary header */
+ /**
+ * HTTP Vary header
+ * @var string $mVary
+ */
private $mVary;
- /** Content of our HTTP response */
+ /**
+ * Content of our HTTP response
+ * @var string $mText
+ */
private $mText;
+ /**
+ * @param $text string|null
+ */
function __construct( $text = null ) {
$this->mCacheDuration = null;
$this->mVary = null;
@@ -49,41 +89,67 @@ class AjaxResponse {
}
}
+ /**
+ * Set the number of seconds to get the response cached by a proxy
+ * @param $duration int
+ */
function setCacheDuration( $duration ) {
$this->mCacheDuration = $duration;
}
+ /**
+ * Set the HTTP Vary header
+ * @param $vary string
+ */
function setVary( $vary ) {
$this->mVary = $vary;
}
+ /**
+ * Set the HTTP response code
+ * @param $code string
+ */
function setResponseCode( $code ) {
$this->mResponseCode = $code;
}
+ /**
+ * Set the HTTP header Content-Type
+ * @param $type string
+ */
function setContentType( $type ) {
$this->mContentType = $type;
}
+ /**
+ * Disable output.
+ */
function disable() {
$this->mDisabled = true;
}
- /** Add content to the response */
+ /**
+ * Add content to the response
+ * @param $text string
+ */
function addText( $text ) {
if ( ! $this->mDisabled && $text ) {
$this->mText .= $text;
}
}
- /** Output text */
+ /**
+ * Output text
+ */
function printText() {
if ( ! $this->mDisabled ) {
print $this->mText;
}
}
- /** Construct the header and output it */
+ /**
+ * Construct the header and output it
+ */
function sendHeaders() {
global $wgUseSquid, $wgUseESI;
@@ -139,8 +205,10 @@ class AjaxResponse {
/**
* checkLastModified tells the client to use the client-cached response if
* possible. If sucessful, the AjaxResponse is disabled so that
- * any future call to AjaxResponse::printText() have no effect. The method
- * returns true iff the response code was set to 304 Not Modified.
+ * any future call to AjaxResponse::printText() have no effect.
+ *
+ * @param $timestamp string
+ * @return bool Returns true if the response code was set to 304 Not Modified.
*/
function checkLastModified ( $timestamp ) {
global $wgCachePages, $wgCacheEpoch, $wgUser;
@@ -148,21 +216,21 @@ class AjaxResponse {
if ( !$timestamp || $timestamp == '19700101000000' ) {
wfDebug( "$fname: CACHE DISABLED, NO TIMESTAMP\n" );
- return;
+ return false;
}
if ( !$wgCachePages ) {
wfDebug( "$fname: CACHE DISABLED\n", false );
- return;
+ return false;
}
if ( $wgUser->getOption( 'nocache' ) ) {
wfDebug( "$fname: USER DISABLED CACHE\n", false );
- return;
+ return false;
}
$timestamp = wfTimestamp( TS_MW, $timestamp );
- $lastmod = wfTimestamp( TS_RFC2822, max( $timestamp, $wgUser->mTouched, $wgCacheEpoch ) );
+ $lastmod = wfTimestamp( TS_RFC2822, max( $timestamp, $wgUser->getTouched(), $wgCacheEpoch ) );
if ( !empty( $_SERVER['HTTP_IF_MODIFIED_SINCE'] ) ) {
# IE sends sizes after the date like this:
@@ -191,11 +259,12 @@ class AjaxResponse {
wfDebug( "$fname: client did not send If-Modified-Since header\n", false );
$this->mLastModified = $lastmod;
}
+ return false;
}
/**
- * @param $mckey
- * @param $touched
+ * @param $mckey string
+ * @param $touched int
* @return bool
*/
function loadFromMemcached( $mckey, $touched ) {
@@ -222,7 +291,7 @@ class AjaxResponse {
}
/**
- * @param $mckey
+ * @param $mckey string
* @param $expiry int
* @return bool
*/
diff --git a/includes/Article.php b/includes/Article.php
index b07f309c..9ab4b6ba 100644
--- a/includes/Article.php
+++ b/includes/Article.php
@@ -1,6 +1,22 @@
<?php
/**
- * File for articles
+ * User interface for page actions.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
* @file
*/
@@ -9,7 +25,7 @@
*
* This maintains WikiPage functions for backwards compatibility.
*
- * @TODO: move and rewrite code to an Action class
+ * @todo move and rewrite code to an Action class
*
* See design.txt for an overview.
* Note: edit user interface and cache support functions have been
@@ -23,42 +39,69 @@ class Article extends Page {
*/
/**
- * @var IContextSource
+ * The context this Article is executed in
+ * @var IContextSource $mContext
*/
protected $mContext;
/**
- * @var WikiPage
+ * The WikiPage object of this instance
+ * @var WikiPage $mPage
*/
protected $mPage;
/**
- * @var ParserOptions: ParserOptions object for $wgUser articles
+ * ParserOptions object for $wgUser articles
+ * @var ParserOptions $mParserOptions
*/
public $mParserOptions;
+ /**
+ * Content of the revision we are working on
+ * @var string $mContent
+ */
var $mContent; // !<
+
+ /**
+ * Is the content ($mContent) already loaded?
+ * @var bool $mContentLoaded
+ */
var $mContentLoaded = false; // !<
+
+ /**
+ * The oldid of the article that is to be shown, 0 for the
+ * current revision
+ * @var int|null $mOldId
+ */
var $mOldId; // !<
/**
- * @var Title
+ * Title from which we were redirected here
+ * @var Title $mRedirectedFrom
*/
var $mRedirectedFrom = null;
/**
- * @var mixed: boolean false or URL string
+ * URL to redirect to or false if none
+ * @var string|false $mRedirectUrl
*/
var $mRedirectUrl = false; // !<
+
+ /**
+ * Revision ID of revision we are working on
+ * @var int $mRevIdFetched
+ */
var $mRevIdFetched = 0; // !<
/**
- * @var Revision
+ * Revision we are working on
+ * @var Revision $mRevision
*/
var $mRevision = null;
/**
- * @var ParserOutput
+ * ParserOutput object
+ * @var ParserOutput $mParserOutput
*/
var $mParserOutput;
@@ -188,11 +231,9 @@ class Article extends Page {
* This function has side effects! Do not use this function if you
* only want the real revision text if any.
*
- * @return Return the text of this revision
+ * @return string Return the text of this revision
*/
public function getContent() {
- global $wgUser;
-
wfProfileIn( __METHOD__ );
if ( $this->mPage->getID() === 0 ) {
@@ -204,7 +245,8 @@ class Article extends Page {
$text = '';
}
} else {
- $text = wfMsgExt( $wgUser->isLoggedIn() ? 'noarticletext' : 'noarticletextanon', 'parsemag' );
+ $message = $this->getContext()->getUser()->isLoggedIn() ? 'noarticletext' : 'noarticletextanon';
+ $text = wfMessage( $message )->text();
}
wfProfileOut( __METHOD__ );
@@ -235,11 +277,10 @@ class Article extends Page {
* @return int The old id for the request
*/
public function getOldIDFromRequest() {
- global $wgRequest;
-
$this->mRedirectUrl = false;
- $oldid = $wgRequest->getIntOrNull( 'oldid' );
+ $request = $this->getContext()->getRequest();
+ $oldid = $request->getIntOrNull( 'oldid' );
if ( $oldid === null ) {
return 0;
@@ -248,17 +289,21 @@ class Article extends Page {
if ( $oldid !== 0 ) {
# Load the given revision and check whether the page is another one.
# In that case, update this instance to reflect the change.
- $this->mRevision = Revision::newFromId( $oldid );
- if ( $this->mRevision !== null ) {
- // Revision title doesn't match the page title given?
- if ( $this->mPage->getID() != $this->mRevision->getPage() ) {
- $function = array( get_class( $this->mPage ), 'newFromID' );
- $this->mPage = call_user_func( $function, $this->mRevision->getPage() );
+ if ( $oldid === $this->mPage->getLatest() ) {
+ $this->mRevision = $this->mPage->getRevision();
+ } else {
+ $this->mRevision = Revision::newFromId( $oldid );
+ if ( $this->mRevision !== null ) {
+ // Revision title doesn't match the page title given?
+ if ( $this->mPage->getID() != $this->mRevision->getPage() ) {
+ $function = array( get_class( $this->mPage ), 'newFromID' );
+ $this->mPage = call_user_func( $function, $this->mRevision->getPage() );
+ }
}
}
}
- if ( $wgRequest->getVal( 'direction' ) == 'next' ) {
+ if ( $request->getVal( 'direction' ) == 'next' ) {
$nextid = $this->getTitle()->getNextRevisionID( $oldid );
if ( $nextid ) {
$oldid = $nextid;
@@ -266,7 +311,7 @@ class Article extends Page {
} else {
$this->mRedirectUrl = $this->getTitle()->getFullURL( 'redirect=no' );
}
- } elseif ( $wgRequest->getVal( 'direction' ) == 'prev' ) {
+ } elseif ( $request->getVal( 'direction' ) == 'prev' ) {
$previd = $this->getTitle()->getPreviousRevisionID( $oldid );
if ( $previd ) {
$oldid = $previd;
@@ -306,9 +351,7 @@ class Article extends Page {
# Pre-fill content with error message so that if something
# fails we'll have something telling us what we intended.
- $t = $this->getTitle()->getPrefixedText();
- $d = $oldid ? wfMsgExt( 'missingarticle-rev', array( 'escape' ), $oldid ) : '';
- $this->mContent = wfMsgNoTrans( 'missing-article', $t, $d ) ;
+ $this->mContent = wfMessage( 'missing-revision', $oldid )->plain();
if ( $oldid ) {
# $this->mRevision might already be fetched by getOldIDFromRequest()
@@ -400,8 +443,7 @@ class Article extends Page {
* page of the given title.
*/
public function view() {
- global $wgUser, $wgOut, $wgRequest, $wgParser;
- global $wgUseFileCache, $wgUseETag, $wgDebugToolbar;
+ global $wgParser, $wgUseFileCache, $wgUseETag, $wgDebugToolbar;
wfProfileIn( __METHOD__ );
@@ -411,17 +453,19 @@ class Article extends Page {
# the first call of this method even if $oldid is used way below.
$oldid = $this->getOldID();
+ $user = $this->getContext()->getUser();
# Another whitelist check in case getOldID() is altering the title
- $permErrors = $this->getTitle()->getUserPermissionsErrors( 'read', $wgUser );
+ $permErrors = $this->getTitle()->getUserPermissionsErrors( 'read', $user );
if ( count( $permErrors ) ) {
wfDebug( __METHOD__ . ": denied on secondary read check\n" );
wfProfileOut( __METHOD__ );
throw new PermissionsError( 'read', $permErrors );
}
+ $outputPage = $this->getContext()->getOutput();
# getOldID() may as well want us to redirect somewhere else
if ( $this->mRedirectUrl ) {
- $wgOut->redirect( $this->mRedirectUrl );
+ $outputPage->redirect( $this->mRedirectUrl );
wfDebug( __METHOD__ . ": redirecting due to oldid\n" );
wfProfileOut( __METHOD__ );
@@ -429,7 +473,7 @@ class Article extends Page {
}
# If we got diff in the query, we want to see a diff page instead of the article.
- if ( $wgRequest->getCheck( 'diff' ) ) {
+ if ( $this->getContext()->getRequest()->getCheck( 'diff' ) ) {
wfDebug( __METHOD__ . ": showing diff page\n" );
$this->showDiffPage();
wfProfileOut( __METHOD__ );
@@ -438,31 +482,31 @@ class Article extends Page {
}
# Set page title (may be overridden by DISPLAYTITLE)
- $wgOut->setPageTitle( $this->getTitle()->getPrefixedText() );
+ $outputPage->setPageTitle( $this->getTitle()->getPrefixedText() );
- $wgOut->setArticleFlag( true );
+ $outputPage->setArticleFlag( true );
# Allow frames by default
- $wgOut->allowClickjacking();
+ $outputPage->allowClickjacking();
$parserCache = ParserCache::singleton();
$parserOptions = $this->getParserOptions();
# Render printable version, use printable version cache
- if ( $wgOut->isPrintable() ) {
+ if ( $outputPage->isPrintable() ) {
$parserOptions->setIsPrintable( true );
$parserOptions->setEditSection( false );
- } elseif ( !$this->isCurrent() || !$this->getTitle()->quickUserCan( 'edit' ) ) {
+ } elseif ( !$this->isCurrent() || !$this->getTitle()->quickUserCan( 'edit', $user ) ) {
$parserOptions->setEditSection( false );
}
# Try client and file cache
if ( !$wgDebugToolbar && $oldid === 0 && $this->mPage->checkTouched() ) {
if ( $wgUseETag ) {
- $wgOut->setETag( $parserCache->getETag( $this, $parserOptions ) );
+ $outputPage->setETag( $parserCache->getETag( $this, $parserOptions ) );
}
# Is it client cached?
- if ( $wgOut->checkLastModified( $this->mPage->getTouched() ) ) {
+ if ( $outputPage->checkLastModified( $this->mPage->getTouched() ) ) {
wfDebug( __METHOD__ . ": done 304\n" );
wfProfileOut( __METHOD__ );
@@ -471,8 +515,8 @@ class Article extends Page {
} elseif ( $wgUseFileCache && $this->tryFileCache() ) {
wfDebug( __METHOD__ . ": done file cache\n" );
# tell wgOut that output is taken care of
- $wgOut->disable();
- $this->mPage->doViewUpdates( $wgUser );
+ $outputPage->disable();
+ $this->mPage->doViewUpdates( $user );
wfProfileOut( __METHOD__ );
return;
@@ -482,7 +526,7 @@ class Article extends Page {
# Should the parser cache be used?
$useParserCache = $this->mPage->isParserCacheUsed( $parserOptions, $oldid );
wfDebug( 'Article::view using parser cache: ' . ( $useParserCache ? 'yes' : 'no' ) . "\n" );
- if ( $wgUser->getStubThreshold() ) {
+ if ( $user->getStubThreshold() ) {
wfIncrStats( 'pcache_miss_stub' );
}
@@ -520,14 +564,14 @@ class Article extends Page {
} else {
wfDebug( __METHOD__ . ": showing parser cache contents\n" );
}
- $wgOut->addParserOutput( $this->mParserOutput );
+ $outputPage->addParserOutput( $this->mParserOutput );
# Ensure that UI elements requiring revision ID have
# the correct version information.
- $wgOut->setRevisionId( $this->mPage->getLatest() );
+ $outputPage->setRevisionId( $this->mPage->getLatest() );
# Preload timestamp to avoid a DB hit
$cachedTimestamp = $this->mParserOutput->getTimestamp();
if ( $cachedTimestamp !== null ) {
- $wgOut->setRevisionTimestamp( $cachedTimestamp );
+ $outputPage->setRevisionTimestamp( $cachedTimestamp );
$this->mPage->setTimestamp( $cachedTimestamp );
}
$outputDone = true;
@@ -551,16 +595,16 @@ class Article extends Page {
# Ensure that UI elements requiring revision ID have
# the correct version information.
- $wgOut->setRevisionId( $this->getRevIdFetched() );
+ $outputPage->setRevisionId( $this->getRevIdFetched() );
# Preload timestamp to avoid a DB hit
- $wgOut->setRevisionTimestamp( $this->getTimestamp() );
+ $outputPage->setRevisionTimestamp( $this->getTimestamp() );
# Pages containing custom CSS or JavaScript get special treatment
if ( $this->getTitle()->isCssOrJsPage() || $this->getTitle()->isCssJsSubpage() ) {
wfDebug( __METHOD__ . ": showing CSS/JS source\n" );
$this->showCssOrJsPage();
$outputDone = true;
- } elseif( !wfRunHooks( 'ArticleViewCustom', array( $this->mContent, $this->getTitle(), $wgOut ) ) ) {
+ } elseif( !wfRunHooks( 'ArticleViewCustom', array( $this->mContent, $this->getTitle(), $outputPage ) ) ) {
# Allow extensions do their own custom view for certain pages
$outputDone = true;
} else {
@@ -569,10 +613,10 @@ class Article extends Page {
if ( $rt ) {
wfDebug( __METHOD__ . ": showing redirect=no page\n" );
# Viewing a redirect page (e.g. with parameter redirect=no)
- $wgOut->addHTML( $this->viewRedirect( $rt ) );
+ $outputPage->addHTML( $this->viewRedirect( $rt ) );
# Parse just to get categories, displaytitle, etc.
$this->mParserOutput = $wgParser->parse( $text, $this->getTitle(), $parserOptions );
- $wgOut->addParserOutputNoText( $this->mParserOutput );
+ $outputPage->addParserOutputNoText( $this->mParserOutput );
$outputDone = true;
}
}
@@ -587,12 +631,12 @@ class Article extends Page {
if ( !$poolArticleView->execute() ) {
$error = $poolArticleView->getError();
if ( $error ) {
- $wgOut->clearHTML(); // for release() errors
- $wgOut->enableClientCache( false );
- $wgOut->setRobotPolicy( 'noindex,nofollow' );
+ $outputPage->clearHTML(); // for release() errors
+ $outputPage->enableClientCache( false );
+ $outputPage->setRobotPolicy( 'noindex,nofollow' );
$errortext = $error->getWikiText( false, 'view-pool-error' );
- $wgOut->addWikiText( '<div class="errorbox">' . $errortext . '</div>' );
+ $outputPage->addWikiText( '<div class="errorbox">' . $errortext . '</div>' );
}
# Connection or timeout error
wfProfileOut( __METHOD__ );
@@ -600,12 +644,12 @@ class Article extends Page {
}
$this->mParserOutput = $poolArticleView->getParserOutput();
- $wgOut->addParserOutput( $this->mParserOutput );
+ $outputPage->addParserOutput( $this->mParserOutput );
# Don't cache a dirty ParserOutput object
if ( $poolArticleView->getIsDirty() ) {
- $wgOut->setSquidMaxage( 0 );
- $wgOut->addHTML( "<!-- parser cache is expired, sending anyway due to pool overload-->\n" );
+ $outputPage->setSquidMaxage( 0 );
+ $outputPage->addHTML( "<!-- parser cache is expired, sending anyway due to pool overload-->\n" );
}
$outputDone = true;
@@ -634,17 +678,17 @@ class Article extends Page {
if ( $this->getTitle()->isMainPage() ) {
$msg = wfMessage( 'pagetitle-view-mainpage' )->inContentLanguage();
if ( !$msg->isDisabled() ) {
- $wgOut->setHTMLTitle( $msg->title( $this->getTitle() )->text() );
+ $outputPage->setHTMLTitle( $msg->title( $this->getTitle() )->text() );
}
}
# Check for any __NOINDEX__ tags on the page using $pOutput
$policy = $this->getRobotPolicy( 'view', $pOutput );
- $wgOut->setIndexPolicy( $policy['index'] );
- $wgOut->setFollowPolicy( $policy['follow'] );
+ $outputPage->setIndexPolicy( $policy['index'] );
+ $outputPage->setFollowPolicy( $policy['follow'] );
$this->showViewFooter();
- $this->mPage->doViewUpdates( $wgUser );
+ $this->mPage->doViewUpdates( $user );
wfProfileOut( __METHOD__ );
}
@@ -654,11 +698,10 @@ class Article extends Page {
* @param $pOutput ParserOutput
*/
public function adjustDisplayTitle( ParserOutput $pOutput ) {
- global $wgOut;
# Adjust the title if it was set by displaytitle, -{T|}- or language conversion
$titleText = $pOutput->getTitleText();
if ( strval( $titleText ) !== '' ) {
- $wgOut->setPageTitle( $titleText );
+ $this->getContext()->getOutput()->setPageTitle( $titleText );
}
}
@@ -667,13 +710,13 @@ class Article extends Page {
* Article::view() only, other callers should use the DifferenceEngine class.
*/
public function showDiffPage() {
- global $wgRequest, $wgUser;
-
- $diff = $wgRequest->getVal( 'diff' );
- $rcid = $wgRequest->getVal( 'rcid' );
- $diffOnly = $wgRequest->getBool( 'diffonly', $wgUser->getOption( 'diffonly' ) );
- $purge = $wgRequest->getVal( 'action' ) == 'purge';
- $unhide = $wgRequest->getInt( 'unhide' ) == 1;
+ $request = $this->getContext()->getRequest();
+ $user = $this->getContext()->getUser();
+ $diff = $request->getVal( 'diff' );
+ $rcid = $request->getVal( 'rcid' );
+ $diffOnly = $request->getBool( 'diffonly', $user->getOption( 'diffonly' ) );
+ $purge = $request->getVal( 'action' ) == 'purge';
+ $unhide = $request->getInt( 'unhide' ) == 1;
$oldid = $this->getOldID();
$de = new DifferenceEngine( $this->getContext(), $oldid, $diff, $rcid, $purge, $unhide );
@@ -683,7 +726,7 @@ class Article extends Page {
if ( $diff == 0 || $diff == $this->mPage->getLatest() ) {
# Run view updates for current revision only
- $this->mPage->doViewUpdates( $wgUser );
+ $this->mPage->doViewUpdates( $user );
}
}
@@ -695,22 +738,21 @@ class Article extends Page {
* page views.
*/
protected function showCssOrJsPage() {
- global $wgOut;
-
$dir = $this->getContext()->getLanguage()->getDir();
$lang = $this->getContext()->getLanguage()->getCode();
- $wgOut->wrapWikiMsg( "<div id='mw-clearyourcache' lang='$lang' dir='$dir' class='mw-content-$dir'>\n$1\n</div>",
+ $outputPage = $this->getContext()->getOutput();
+ $outputPage->wrapWikiMsg( "<div id='mw-clearyourcache' lang='$lang' dir='$dir' class='mw-content-$dir'>\n$1\n</div>",
'clearyourcache' );
// Give hooks a chance to customise the output
- if ( wfRunHooks( 'ShowRawCssJs', array( $this->mContent, $this->getTitle(), $wgOut ) ) ) {
+ if ( wfRunHooks( 'ShowRawCssJs', array( $this->mContent, $this->getTitle(), $outputPage ) ) ) {
// Wrap the whole lot in a <pre> and don't parse
$m = array();
preg_match( '!\.(css|js)$!u', $this->getTitle()->getText(), $m );
- $wgOut->addHTML( "<pre class=\"mw-code mw-{$m[1]}\" dir=\"ltr\">\n" );
- $wgOut->addHTML( htmlspecialchars( $this->mContent ) );
- $wgOut->addHTML( "\n</pre>\n" );
+ $outputPage->addHTML( "<pre class=\"mw-code mw-{$m[1]}\" dir=\"ltr\">\n" );
+ $outputPage->addHTML( htmlspecialchars( $this->mContent ) );
+ $outputPage->addHTML( "\n</pre>\n" );
}
}
@@ -722,8 +764,7 @@ class Article extends Page {
* TODO: actions other than 'view'
*/
public function getRobotPolicy( $action, $pOutput ) {
- global $wgOut, $wgArticleRobotPolicies, $wgNamespaceRobotPolicies;
- global $wgDefaultRobotPolicy, $wgRequest;
+ global $wgArticleRobotPolicies, $wgNamespaceRobotPolicies, $wgDefaultRobotPolicy;
$ns = $this->getTitle()->getNamespace();
@@ -745,13 +786,13 @@ class Article extends Page {
'index' => 'noindex',
'follow' => 'nofollow'
);
- } elseif ( $wgOut->isPrintable() ) {
+ } elseif ( $this->getContext()->getOutput()->isPrintable() ) {
# Discourage indexing of printable versions, but encourage following
return array(
'index' => 'noindex',
'follow' => 'follow'
);
- } elseif ( $wgRequest->getInt( 'curid' ) ) {
+ } elseif ( $this->getContext()->getRequest()->getInt( 'curid' ) ) {
# For ?curid=x urls, disallow indexing
return array(
'index' => 'noindex',
@@ -794,7 +835,7 @@ class Article extends Page {
* merging of several policies using array_merge().
* @param $policy Mixed, returns empty array on null/false/'', transparent
* to already-converted arrays, converts String.
- * @return Array: 'index' => <indexpolicy>, 'follow' => <followpolicy>
+ * @return Array: 'index' => \<indexpolicy\>, 'follow' => \<followpolicy\>
*/
public static function formatRobotPolicy( $policy ) {
if ( is_array( $policy ) ) {
@@ -820,15 +861,16 @@ class Article extends Page {
/**
* If this request is a redirect view, send "redirected from" subtitle to
- * $wgOut. Returns true if the header was needed, false if this is not a
- * redirect view. Handles both local and remote redirects.
+ * the output. Returns true if the header was needed, false if this is not
+ * a redirect view. Handles both local and remote redirects.
*
* @return boolean
*/
public function showRedirectedFromHeader() {
- global $wgOut, $wgRequest, $wgRedirectSources;
+ global $wgRedirectSources;
+ $outputPage = $this->getContext()->getOutput();
- $rdfrom = $wgRequest->getVal( 'rdfrom' );
+ $rdfrom = $this->getContext()->getRequest()->getVal( 'rdfrom' );
if ( isset( $this->mRedirectedFrom ) ) {
// This is an internally redirected page view.
@@ -841,21 +883,21 @@ class Article extends Page {
array( 'redirect' => 'no' )
);
- $wgOut->addSubtitle( wfMessage( 'redirectedfrom' )->rawParams( $redir ) );
+ $outputPage->addSubtitle( wfMessage( 'redirectedfrom' )->rawParams( $redir ) );
// Set the fragment if one was specified in the redirect
if ( strval( $this->getTitle()->getFragment() ) != '' ) {
$fragment = Xml::escapeJsString( $this->getTitle()->getFragmentForURL() );
- $wgOut->addInlineScript( "redirectToFragment(\"$fragment\");" );
+ $outputPage->addInlineScript( "redirectToFragment(\"$fragment\");" );
}
// Add a <link rel="canonical"> tag
- $wgOut->addLink( array( 'rel' => 'canonical',
+ $outputPage->addLink( array( 'rel' => 'canonical',
'href' => $this->getTitle()->getLocalURL() )
);
- // Tell $wgOut the user arrived at this article through a redirect
- $wgOut->setRedirectedFrom( $this->mRedirectedFrom );
+ // Tell the output object that the user arrived at this article through a redirect
+ $outputPage->setRedirectedFrom( $this->mRedirectedFrom );
return true;
}
@@ -864,7 +906,7 @@ class Article extends Page {
// If it was reported from a trusted site, supply a backlink.
if ( $wgRedirectSources && preg_match( $wgRedirectSources, $rdfrom ) ) {
$redir = Linker::makeExternalLink( $rdfrom, $rdfrom );
- $wgOut->addSubtitle( wfMessage( 'redirectedfrom' )->rawParams( $redir ) );
+ $outputPage->addSubtitle( wfMessage( 'redirectedfrom' )->rawParams( $redir ) );
return true;
}
@@ -878,11 +920,9 @@ class Article extends Page {
* [[MediaWiki:Talkpagetext]]. For Article::view().
*/
public function showNamespaceHeader() {
- global $wgOut;
-
if ( $this->getTitle()->isTalkPage() ) {
if ( !wfMessage( 'talkpageheader' )->isDisabled() ) {
- $wgOut->wrapWikiMsg( "<div class=\"mw-talkpageheader\">\n$1\n</div>", array( 'talkpageheader' ) );
+ $this->getContext()->getOutput()->wrapWikiMsg( "<div class=\"mw-talkpageheader\">\n$1\n</div>", array( 'talkpageheader' ) );
}
}
}
@@ -891,11 +931,9 @@ class Article extends Page {
* Show the footer section of an ordinary page view
*/
public function showViewFooter() {
- global $wgOut;
-
# check if we're displaying a [[User talk:x.x.x.x]] anonymous talk page
if ( $this->getTitle()->getNamespace() == NS_USER_TALK && IP::isValid( $this->getTitle()->getText() ) ) {
- $wgOut->addWikiMsg( 'anontalkpagetext' );
+ $this->getContext()->getOutput()->addWikiMsg( 'anontalkpagetext' );
}
# If we have been passed an &rcid= parameter, we want to give the user a
@@ -912,33 +950,32 @@ class Article extends Page {
* desired, does nothing.
*/
public function showPatrolFooter() {
- global $wgOut, $wgRequest, $wgUser;
-
- $rcid = $wgRequest->getVal( 'rcid' );
+ $request = $this->getContext()->getRequest();
+ $outputPage = $this->getContext()->getOutput();
+ $user = $this->getContext()->getUser();
+ $rcid = $request->getVal( 'rcid' );
- if ( !$rcid || !$this->getTitle()->quickUserCan( 'patrol' ) ) {
+ if ( !$rcid || !$this->getTitle()->quickUserCan( 'patrol', $user ) ) {
return;
}
- $token = $wgUser->getEditToken( $rcid );
- $wgOut->preventClickjacking();
+ $token = $user->getEditToken( $rcid );
+ $outputPage->preventClickjacking();
- $wgOut->addHTML(
+ $link = Linker::linkKnown(
+ $this->getTitle(),
+ wfMessage( 'markaspatrolledtext' )->escaped(),
+ array(),
+ array(
+ 'action' => 'markpatrolled',
+ 'rcid' => $rcid,
+ 'token' => $token,
+ )
+ );
+
+ $outputPage->addHTML(
"<div class='patrollink'>" .
- wfMsgHtml(
- 'markaspatrolledlink',
- Linker::link(
- $this->getTitle(),
- wfMsgHtml( 'markaspatrolledtext' ),
- array(),
- array(
- 'action' => 'markpatrolled',
- 'rcid' => $rcid,
- 'token' => $token,
- ),
- array( 'known', 'noclasses' )
- )
- ) .
+ wfMessage( 'markaspatrolledlink' )->rawParams( $link )->escaped() .
'</div>'
);
}
@@ -948,7 +985,8 @@ class Article extends Page {
* namespace, show the default message text. To be called from Article::view().
*/
public function showMissingArticle() {
- global $wgOut, $wgRequest, $wgUser, $wgSend404Code;
+ global $wgSend404Code;
+ $outputPage = $this->getContext()->getOutput();
# Show info in user (talk) namespace. Does the user exist? Is he blocked?
if ( $this->getTitle()->getNamespace() == NS_USER || $this->getTitle()->getNamespace() == NS_USER_TALK ) {
@@ -958,13 +996,13 @@ class Article extends Page {
$ip = User::isIP( $rootPart );
if ( !($user && $user->isLoggedIn()) && !$ip ) { # User does not exist
- $wgOut->wrapWikiMsg( "<div class=\"mw-userpage-userdoesnotexist error\">\n\$1\n</div>",
+ $outputPage->wrapWikiMsg( "<div class=\"mw-userpage-userdoesnotexist error\">\n\$1\n</div>",
array( 'userpage-userdoesnotexist-view', wfEscapeWikiText( $rootPart ) ) );
} elseif ( $user->isBlocked() ) { # Show log extract if the user is currently blocked
LogEventsList::showLogExtract(
- $wgOut,
+ $outputPage,
'block',
- $user->getUserPage()->getPrefixedText(),
+ $user->getUserPage(),
'',
array(
'lim' => 1,
@@ -981,7 +1019,7 @@ class Article extends Page {
wfRunHooks( 'ShowMissingArticle', array( $this ) );
# Show delete and move logs
- LogEventsList::showLogExtract( $wgOut, array( 'delete', 'move' ), $this->getTitle()->getPrefixedText(), '',
+ LogEventsList::showLogExtract( $outputPage, array( 'delete', 'move' ), $this->getTitle(), '',
array( 'lim' => 10,
'conds' => array( "log_action != 'revision'" ),
'showIfEmpty' => false,
@@ -991,7 +1029,7 @@ class Article extends Page {
if ( !$this->mPage->hasViewableContent() && $wgSend404Code ) {
// If there's no backing content, send a 404 Not Found
// for better machine handling of broken links.
- $wgRequest->response()->header( "HTTP/1.1 404 Not Found" );
+ $this->getContext()->getRequest()->response()->header( "HTTP/1.1 404 Not Found" );
}
$hookResult = wfRunHooks( 'BeforeDisplayNoArticleText', array( $this ) );
@@ -1003,56 +1041,50 @@ class Article extends Page {
# Show error message
$oldid = $this->getOldID();
if ( $oldid ) {
- $text = wfMsgNoTrans( 'missing-article',
- $this->getTitle()->getPrefixedText(),
- wfMsgNoTrans( 'missingarticle-rev', $oldid ) );
+ $text = wfMessage( 'missing-revision', $oldid )->plain();
} elseif ( $this->getTitle()->getNamespace() === NS_MEDIAWIKI ) {
// Use the default message text
$text = $this->getTitle()->getDefaultMessageText();
+ } elseif ( $this->getTitle()->quickUserCan( 'create', $this->getContext()->getUser() )
+ && $this->getTitle()->quickUserCan( 'edit', $this->getContext()->getUser() )
+ ) {
+ $text = wfMessage( 'noarticletext' )->plain();
} else {
- $createErrors = $this->getTitle()->getUserPermissionsErrors( 'create', $wgUser );
- $editErrors = $this->getTitle()->getUserPermissionsErrors( 'edit', $wgUser );
- $errors = array_merge( $createErrors, $editErrors );
-
- if ( !count( $errors ) ) {
- $text = wfMsgNoTrans( 'noarticletext' );
- } else {
- $text = wfMsgNoTrans( 'noarticletext-nopermission' );
- }
+ $text = wfMessage( 'noarticletext-nopermission' )->plain();
}
$text = "<div class='noarticletext'>\n$text\n</div>";
- $wgOut->addWikiText( $text );
+ $outputPage->addWikiText( $text );
}
/**
* If the revision requested for view is deleted, check permissions.
- * Send either an error message or a warning header to $wgOut.
+ * Send either an error message or a warning header to the output.
*
* @return boolean true if the view is allowed, false if not.
*/
public function showDeletedRevisionHeader() {
- global $wgOut, $wgRequest;
-
if ( !$this->mRevision->isDeleted( Revision::DELETED_TEXT ) ) {
// Not deleted
return true;
}
+ $outputPage = $this->getContext()->getOutput();
+ $user = $this->getContext()->getUser();
// If the user is not allowed to see it...
- if ( !$this->mRevision->userCan( Revision::DELETED_TEXT ) ) {
- $wgOut->wrapWikiMsg( "<div class='mw-warning plainlinks'>\n$1\n</div>\n",
+ if ( !$this->mRevision->userCan( Revision::DELETED_TEXT, $user ) ) {
+ $outputPage->wrapWikiMsg( "<div class='mw-warning plainlinks'>\n$1\n</div>\n",
'rev-deleted-text-permission' );
return false;
// If the user needs to confirm that they want to see it...
- } elseif ( $wgRequest->getInt( 'unhide' ) != 1 ) {
+ } elseif ( $this->getContext()->getRequest()->getInt( 'unhide' ) != 1 ) {
# Give explanation and add a link to view the revision...
$oldid = intval( $this->getOldID() );
$link = $this->getTitle()->getFullUrl( "oldid={$oldid}&unhide=1" );
$msg = $this->mRevision->isDeleted( Revision::DELETED_RESTRICTED ) ?
'rev-suppressed-text-unhide' : 'rev-deleted-text-unhide';
- $wgOut->wrapWikiMsg( "<div class='mw-warning plainlinks'>\n$1\n</div>\n",
+ $outputPage->wrapWikiMsg( "<div class='mw-warning plainlinks'>\n$1\n</div>\n",
array( $msg, $link ) );
return false;
@@ -1060,7 +1092,7 @@ class Article extends Page {
} else {
$msg = $this->mRevision->isDeleted( Revision::DELETED_RESTRICTED ) ?
'rev-suppressed-text-view' : 'rev-deleted-text-view';
- $wgOut->wrapWikiMsg( "<div class='mw-warning plainlinks'>\n$1\n</div>\n", $msg );
+ $outputPage->wrapWikiMsg( "<div class='mw-warning plainlinks'>\n$1\n</div>\n", $msg );
return true;
}
@@ -1072,30 +1104,36 @@ class Article extends Page {
* Revision as of \<date\>; view current revision
* \<- Previous version | Next Version -\>
*
- * @param $oldid String: revision ID of this article revision
+ * @param $oldid int: revision ID of this article revision
*/
public function setOldSubtitle( $oldid = 0 ) {
- global $wgLang, $wgOut, $wgUser, $wgRequest;
-
if ( !wfRunHooks( 'DisplayOldSubtitle', array( &$this, &$oldid ) ) ) {
return;
}
- $unhide = $wgRequest->getInt( 'unhide' ) == 1;
+ $unhide = $this->getContext()->getRequest()->getInt( 'unhide' ) == 1;
# Cascade unhide param in links for easy deletion browsing
$extraParams = array();
- if ( $wgRequest->getVal( 'unhide' ) ) {
+ if ( $unhide ) {
$extraParams['unhide'] = 1;
}
- $revision = Revision::newFromId( $oldid );
+ if ( $this->mRevision && $this->mRevision->getId() === $oldid ) {
+ $revision = $this->mRevision;
+ } else {
+ $revision = Revision::newFromId( $oldid );
+ }
+
$timestamp = $revision->getTimestamp();
$current = ( $oldid == $this->mPage->getLatest() );
- $td = $wgLang->timeanddate( $timestamp, true );
- $tddate = $wgLang->date( $timestamp, true );
- $tdtime = $wgLang->time( $timestamp, true );
+ $language = $this->getContext()->getLanguage();
+ $user = $this->getContext()->getUser();
+
+ $td = $language->userTimeAndDate( $timestamp, $user );
+ $tddate = $language->userDate( $timestamp, $user );
+ $tdtime = $language->userTime( $timestamp, $user );
# Show user links if allowed to see them. If hidden, then show them only if requested...
$userlinks = Linker::revUserTools( $revision, !$unhide );
@@ -1104,89 +1142,85 @@ class Article extends Page {
? 'revision-info-current'
: 'revision-info';
- $wgOut->addSubtitle( "<div id=\"mw-{$infomsg}\">" . wfMessage( $infomsg,
+ $outputPage = $this->getContext()->getOutput();
+ $outputPage->addSubtitle( "<div id=\"mw-{$infomsg}\">" . wfMessage( $infomsg,
$td )->rawParams( $userlinks )->params( $revision->getID(), $tddate,
$tdtime, $revision->getUser() )->parse() . "</div>" );
$lnk = $current
- ? wfMsgHtml( 'currentrevisionlink' )
- : Linker::link(
+ ? wfMessage( 'currentrevisionlink' )->escaped()
+ : Linker::linkKnown(
$this->getTitle(),
- wfMsgHtml( 'currentrevisionlink' ),
+ wfMessage( 'currentrevisionlink' )->escaped(),
array(),
- $extraParams,
- array( 'known', 'noclasses' )
+ $extraParams
);
$curdiff = $current
- ? wfMsgHtml( 'diff' )
- : Linker::link(
+ ? wfMessage( 'diff' )->escaped()
+ : Linker::linkKnown(
$this->getTitle(),
- wfMsgHtml( 'diff' ),
+ wfMessage( 'diff' )->escaped(),
array(),
array(
'diff' => 'cur',
'oldid' => $oldid
- ) + $extraParams,
- array( 'known', 'noclasses' )
+ ) + $extraParams
);
$prev = $this->getTitle()->getPreviousRevisionID( $oldid ) ;
$prevlink = $prev
- ? Linker::link(
+ ? Linker::linkKnown(
$this->getTitle(),
- wfMsgHtml( 'previousrevision' ),
+ wfMessage( 'previousrevision' )->escaped(),
array(),
array(
'direction' => 'prev',
'oldid' => $oldid
- ) + $extraParams,
- array( 'known', 'noclasses' )
+ ) + $extraParams
)
- : wfMsgHtml( 'previousrevision' );
+ : wfMessage( 'previousrevision' )->escaped();
$prevdiff = $prev
- ? Linker::link(
+ ? Linker::linkKnown(
$this->getTitle(),
- wfMsgHtml( 'diff' ),
+ wfMessage( 'diff' )->escaped(),
array(),
array(
'diff' => 'prev',
'oldid' => $oldid
- ) + $extraParams,
- array( 'known', 'noclasses' )
+ ) + $extraParams
)
- : wfMsgHtml( 'diff' );
+ : wfMessage( 'diff' )->escaped();
$nextlink = $current
- ? wfMsgHtml( 'nextrevision' )
- : Linker::link(
+ ? wfMessage( 'nextrevision' )->escaped()
+ : Linker::linkKnown(
$this->getTitle(),
- wfMsgHtml( 'nextrevision' ),
+ wfMessage( 'nextrevision' )->escaped(),
array(),
array(
'direction' => 'next',
'oldid' => $oldid
- ) + $extraParams,
- array( 'known', 'noclasses' )
+ ) + $extraParams
);
$nextdiff = $current
- ? wfMsgHtml( 'diff' )
- : Linker::link(
+ ? wfMessage( 'diff' )->escaped()
+ : Linker::linkKnown(
$this->getTitle(),
- wfMsgHtml( 'diff' ),
+ wfMessage( 'diff' )->escaped(),
array(),
array(
'diff' => 'next',
'oldid' => $oldid
- ) + $extraParams,
- array( 'known', 'noclasses' )
+ ) + $extraParams
);
- $cdel = Linker::getRevDeleteLink( $wgUser, $revision, $this->getTitle() );
+ $cdel = Linker::getRevDeleteLink( $user, $revision, $this->getTitle() );
if ( $cdel !== '' ) {
$cdel .= ' ';
}
- $wgOut->addSubtitle( "<div id=\"mw-revision-nav\">" . $cdel .
- wfMsgExt( 'revision-nav', array( 'escapenoentities', 'parsemag', 'replaceafter' ),
- $prevdiff, $prevlink, $lnk, $curdiff, $nextlink, $nextdiff ) . "</div>" );
+ $outputPage->addSubtitle( "<div id=\"mw-revision-nav\">" . $cdel .
+ wfMessage( 'revision-nav' )->rawParams(
+ $prevdiff, $prevlink, $lnk, $curdiff, $nextlink, $nextdiff
+ )->escaped() . "</div>" );
}
/**
@@ -1198,7 +1232,7 @@ class Article extends Page {
* @return string containing HMTL with redirect link
*/
public function viewRedirect( $target, $appendSubtitle = true, $forceKnown = false ) {
- global $wgOut, $wgStylePath;
+ global $wgStylePath;
if ( !is_array( $target ) ) {
$target = array( $target );
@@ -1208,7 +1242,8 @@ class Article extends Page {
$imageDir = $lang->getDir();
if ( $appendSubtitle ) {
- $wgOut->appendSubtitle( wfMsgHtml( 'redirectpagesub' ) );
+ $out = $this->getContext()->getOutput();
+ $out->addSubtitle( wfMessage( 'redirectpagesub' )->escaped() );
}
// the loop prepends the arrow image before the link, so the first case needs to be outside
@@ -1246,9 +1281,7 @@ class Article extends Page {
* Handle action=render
*/
public function render() {
- global $wgOut;
-
- $wgOut->setArticleBodyOnly( true );
+ $this->getContext()->getOutput()->setArticleBodyOnly( true );
$this->view();
}
@@ -1271,8 +1304,6 @@ class Article extends Page {
* UI entry point for page deletion
*/
public function delete() {
- global $wgOut, $wgRequest, $wgLang;
-
# This code desperately needs to be totally rewritten
$title = $this->getTitle();
@@ -1290,48 +1321,54 @@ class Article extends Page {
}
# Better double-check that it hasn't been deleted yet!
- $dbw = wfGetDB( DB_MASTER );
- $conds = $title->pageCond();
- $latest = $dbw->selectField( 'page', 'page_latest', $conds, __METHOD__ );
- if ( $latest === false ) {
- $wgOut->setPageTitle( wfMessage( 'cannotdelete-title', $title->getPrefixedText() ) );
- $wgOut->wrapWikiMsg( "<div class=\"error mw-error-cannotdelete\">\n$1\n</div>",
+ $this->mPage->loadPageData( 'fromdbmaster' );
+ if ( !$this->mPage->exists() ) {
+ $deleteLogPage = new LogPage( 'delete' );
+ $outputPage = $this->getContext()->getOutput();
+ $outputPage->setPageTitle( wfMessage( 'cannotdelete-title', $title->getPrefixedText() ) );
+ $outputPage->wrapWikiMsg( "<div class=\"error mw-error-cannotdelete\">\n$1\n</div>",
array( 'cannotdelete', wfEscapeWikiText( $title->getPrefixedText() ) )
);
- $wgOut->addHTML( Xml::element( 'h2', null, LogPage::logName( 'delete' ) ) );
+ $outputPage->addHTML(
+ Xml::element( 'h2', null, $deleteLogPage->getName()->text() )
+ );
LogEventsList::showLogExtract(
- $wgOut,
+ $outputPage,
'delete',
- $title->getPrefixedText()
+ $title
);
return;
}
- $deleteReasonList = $wgRequest->getText( 'wpDeleteReasonList', 'other' );
- $deleteReason = $wgRequest->getText( 'wpReason' );
+ $request = $this->getContext()->getRequest();
+ $deleteReasonList = $request->getText( 'wpDeleteReasonList', 'other' );
+ $deleteReason = $request->getText( 'wpReason' );
if ( $deleteReasonList == 'other' ) {
$reason = $deleteReason;
} elseif ( $deleteReason != '' ) {
// Entry from drop down menu + additional comment
- $reason = $deleteReasonList . wfMsgForContent( 'colon-separator' ) . $deleteReason;
+ $colonseparator = wfMessage( 'colon-separator' )->inContentLanguage()->text();
+ $reason = $deleteReasonList . $colonseparator . $deleteReason;
} else {
$reason = $deleteReasonList;
}
- if ( $wgRequest->wasPosted() && $user->matchEditToken( $wgRequest->getVal( 'wpEditToken' ),
+ if ( $request->wasPosted() && $user->matchEditToken( $request->getVal( 'wpEditToken' ),
array( 'delete', $this->getTitle()->getPrefixedText() ) ) )
{
# Flag to hide all contents of the archived revisions
- $suppress = $wgRequest->getVal( 'wpSuppress' ) && $user->isAllowed( 'suppressrevision' );
+ $suppress = $request->getVal( 'wpSuppress' ) && $user->isAllowed( 'suppressrevision' );
$this->doDelete( $reason, $suppress );
- if ( $wgRequest->getCheck( 'wpWatch' ) && $user->isLoggedIn() ) {
- $this->doWatch();
- } elseif ( $title->userIsWatching() ) {
- $this->doUnwatch();
+ if ( $user->isLoggedIn() && $request->getCheck( 'wpWatch' ) != $user->isWatched( $title ) ) {
+ if ( $request->getCheck( 'wpWatch' ) ) {
+ WatchAction::doWatch( $title, $user );
+ } else {
+ WatchAction::doUnwatch( $title, $user );
+ }
}
return;
@@ -1347,10 +1384,10 @@ class Article extends Page {
if ( $hasHistory ) {
$revisions = $this->mTitle->estimateRevisionCount();
// @todo FIXME: i18n issue/patchwork message
- $wgOut->addHTML( '<strong class="mw-delete-warning-revisions">' .
- wfMsgExt( 'historywarning', array( 'parseinline' ), $wgLang->formatNum( $revisions ) ) .
- wfMsgHtml( 'word-separator' ) . Linker::link( $title,
- wfMsgHtml( 'history' ),
+ $this->getContext()->getOutput()->addHTML( '<strong class="mw-delete-warning-revisions">' .
+ wfMessage( 'historywarning' )->numParams( $revisions )->parse() .
+ wfMessage( 'word-separator' )->plain() . Linker::linkKnown( $title,
+ wfMessage( 'history' )->escaped(),
array( 'rel' => 'archives' ),
array( 'action' => 'history' ) ) .
'</strong>'
@@ -1358,12 +1395,12 @@ class Article extends Page {
if ( $this->mTitle->isBigDeletion() ) {
global $wgDeleteRevisionsLimit;
- $wgOut->wrapWikiMsg( "<div class='error'>\n$1\n</div>\n",
- array( 'delete-warning-toobig', $wgLang->formatNum( $wgDeleteRevisionsLimit ) ) );
+ $this->getContext()->getOutput()->wrapWikiMsg( "<div class='error'>\n$1\n</div>\n",
+ array( 'delete-warning-toobig', $this->getContext()->getLanguage()->formatNum( $wgDeleteRevisionsLimit ) ) );
}
}
- return $this->confirmDelete( $reason );
+ $this->confirmDelete( $reason );
}
/**
@@ -1372,16 +1409,15 @@ class Article extends Page {
* @param $reason String: prefilled reason
*/
public function confirmDelete( $reason ) {
- global $wgOut;
-
wfDebug( "Article::confirmDelete\n" );
- $wgOut->setPageTitle( wfMessage( 'delete-confirm', $this->getTitle()->getPrefixedText() ) );
- $wgOut->addBacklinkSubtitle( $this->getTitle() );
- $wgOut->setRobotPolicy( 'noindex,nofollow' );
- $wgOut->addWikiMsg( 'confirmdeletetext' );
+ $outputPage = $this->getContext()->getOutput();
+ $outputPage->setPageTitle( wfMessage( 'delete-confirm', $this->getTitle()->getPrefixedText() ) );
+ $outputPage->addBacklinkSubtitle( $this->getTitle() );
+ $outputPage->setRobotPolicy( 'noindex,nofollow' );
+ $outputPage->addWikiMsg( 'confirmdeletetext' );
- wfRunHooks( 'ArticleConfirmDelete', array( $this, $wgOut, &$reason ) );
+ wfRunHooks( 'ArticleConfirmDelete', array( $this, $outputPage, &$reason ) );
$user = $this->getContext()->getUser();
@@ -1389,33 +1425,33 @@ class Article extends Page {
$suppress = "<tr id=\"wpDeleteSuppressRow\">
<td></td>
<td class='mw-input'><strong>" .
- Xml::checkLabel( wfMsg( 'revdelete-suppress' ),
+ Xml::checkLabel( wfMessage( 'revdelete-suppress' )->text(),
'wpSuppress', 'wpSuppress', false, array( 'tabindex' => '4' ) ) .
"</strong></td>
</tr>";
} else {
$suppress = '';
}
- $checkWatch = $user->getBoolOption( 'watchdeletion' ) || $this->getTitle()->userIsWatching();
+ $checkWatch = $user->getBoolOption( 'watchdeletion' ) || $user->isWatched( $this->getTitle() );
$form = Xml::openElement( 'form', array( 'method' => 'post',
'action' => $this->getTitle()->getLocalURL( 'action=delete' ), 'id' => 'deleteconfirm' ) ) .
Xml::openElement( 'fieldset', array( 'id' => 'mw-delete-table' ) ) .
- Xml::tags( 'legend', null, wfMsgExt( 'delete-legend', array( 'parsemag', 'escapenoentities' ) ) ) .
+ Xml::tags( 'legend', null, wfMessage( 'delete-legend' )->escaped() ) .
Xml::openElement( 'table', array( 'id' => 'mw-deleteconfirm-table' ) ) .
"<tr id=\"wpDeleteReasonListRow\">
<td class='mw-label'>" .
- Xml::label( wfMsg( 'deletecomment' ), 'wpDeleteReasonList' ) .
+ Xml::label( wfMessage( 'deletecomment' )->text(), 'wpDeleteReasonList' ) .
"</td>
<td class='mw-input'>" .
Xml::listDropDown( 'wpDeleteReasonList',
- wfMsgForContent( 'deletereason-dropdown' ),
- wfMsgForContent( 'deletereasonotherlist' ), '', 'wpReasonDropDown', 1 ) .
+ wfMessage( 'deletereason-dropdown' )->inContentLanguage()->text(),
+ wfMessage( 'deletereasonotherlist' )->inContentLanguage()->text(), '', 'wpReasonDropDown', 1 ) .
"</td>
</tr>
<tr id=\"wpDeleteReasonRow\">
<td class='mw-label'>" .
- Xml::label( wfMsg( 'deleteotherreason' ), 'wpReason' ) .
+ Xml::label( wfMessage( 'deleteotherreason' )->text(), 'wpReason' ) .
"</td>
<td class='mw-input'>" .
Html::input( 'wpReason', $reason, 'text', array(
@@ -1434,7 +1470,7 @@ class Article extends Page {
<tr>
<td></td>
<td class='mw-input'>" .
- Xml::checkLabel( wfMsg( 'watchthis' ),
+ Xml::checkLabel( wfMessage( 'watchthis' )->text(),
'wpWatch', 'wpWatch', $checkWatch, array( 'tabindex' => '3' ) ) .
"</td>
</tr>";
@@ -1445,7 +1481,7 @@ class Article extends Page {
<tr>
<td></td>
<td class='mw-submit'>" .
- Xml::submitButton( wfMsg( 'deletepage' ),
+ Xml::submitButton( wfMessage( 'deletepage' )->text(),
array( 'name' => 'wpConfirmB', 'id' => 'wpConfirmB', 'tabindex' => '5' ) ) .
"</td>
</tr>" .
@@ -1458,17 +1494,19 @@ class Article extends Page {
$title = Title::makeTitle( NS_MEDIAWIKI, 'Deletereason-dropdown' );
$link = Linker::link(
$title,
- wfMsgHtml( 'delete-edit-reasonlist' ),
+ wfMessage( 'delete-edit-reasonlist' )->escaped(),
array(),
array( 'action' => 'edit' )
);
$form .= '<p class="mw-delete-editreasons">' . $link . '</p>';
}
- $wgOut->addHTML( $form );
- $wgOut->addHTML( Xml::element( 'h2', null, LogPage::logName( 'delete' ) ) );
- LogEventsList::showLogExtract( $wgOut, 'delete',
- $this->getTitle()->getPrefixedText()
+ $outputPage->addHTML( $form );
+
+ $deleteLogPage = new LogPage( 'delete' );
+ $outputPage->addHTML( Xml::element( 'h2', null, $deleteLogPage->getName()->text() ) );
+ LogEventsList::showLogExtract( $outputPage, 'delete',
+ $this->getTitle()
);
}
@@ -1478,34 +1516,35 @@ class Article extends Page {
* @param $suppress bool
*/
public function doDelete( $reason, $suppress = false ) {
- global $wgOut;
-
$error = '';
- if ( $this->mPage->doDeleteArticle( $reason, $suppress, 0, true, $error ) ) {
+ $outputPage = $this->getContext()->getOutput();
+ $status = $this->mPage->doDeleteArticleReal( $reason, $suppress, 0, true, $error );
+ if ( $status->isGood() ) {
$deleted = $this->getTitle()->getPrefixedText();
- $wgOut->setPageTitle( wfMessage( 'actioncomplete' ) );
- $wgOut->setRobotPolicy( 'noindex,nofollow' );
+ $outputPage->setPageTitle( wfMessage( 'actioncomplete' ) );
+ $outputPage->setRobotPolicy( 'noindex,nofollow' );
- $loglink = '[[Special:Log/delete|' . wfMsgNoTrans( 'deletionlog' ) . ']]';
+ $loglink = '[[Special:Log/delete|' . wfMessage( 'deletionlog' )->text() . ']]';
- $wgOut->addWikiMsg( 'deletedtext', wfEscapeWikiText( $deleted ), $loglink );
- $wgOut->returnToMain( false );
+ $outputPage->addWikiMsg( 'deletedtext', wfEscapeWikiText( $deleted ), $loglink );
+ $outputPage->returnToMain( false );
} else {
- $wgOut->setPageTitle( wfMessage( 'cannotdelete-title', $this->getTitle()->getPrefixedText() ) );
+ $outputPage->setPageTitle( wfMessage( 'cannotdelete-title', $this->getTitle()->getPrefixedText() ) );
if ( $error == '' ) {
- $wgOut->wrapWikiMsg( "<div class=\"error mw-error-cannotdelete\">\n$1\n</div>",
- array( 'cannotdelete', wfEscapeWikiText( $this->getTitle()->getPrefixedText() ) )
+ $outputPage->addWikiText(
+ "<div class=\"error mw-error-cannotdelete\">\n" . $status->getWikiText() . "\n</div>"
);
- $wgOut->addHTML( Xml::element( 'h2', null, LogPage::logName( 'delete' ) ) );
+ $deleteLogPage = new LogPage( 'delete' );
+ $outputPage->addHTML( Xml::element( 'h2', null, $deleteLogPage->getName()->text() ) );
LogEventsList::showLogExtract(
- $wgOut,
+ $outputPage,
'delete',
- $this->getTitle()->getPrefixedText()
+ $this->getTitle()
);
} else {
- $wgOut->addHTML( $error );
+ $outputPage->addHTML( $error );
}
}
}
@@ -1578,22 +1617,22 @@ class Article extends Page {
* @return ParserOutput or false if the given revsion ID is not found
*/
public function getParserOutput( $oldid = null, User $user = null ) {
- global $wgUser;
-
- $user = is_null( $user ) ? $wgUser : $user;
- $parserOptions = $this->mPage->makeParserOptions( $user );
+ if ( $user === null ) {
+ $parserOptions = $this->getParserOptions();
+ } else {
+ $parserOptions = $this->mPage->makeParserOptions( $user );
+ }
return $this->mPage->getParserOutput( $parserOptions, $oldid );
}
/**
* Get parser options suitable for rendering the primary article wikitext
- * @return ParserOptions|false
+ * @return ParserOptions
*/
public function getParserOptions() {
- global $wgUser;
if ( !$this->mParserOptions ) {
- $this->mParserOptions = $this->mPage->makeParserOptions( $wgUser );
+ $this->mParserOptions = $this->mPage->makeParserOptions( $this->getContext() );
}
// Clone to allow modifications of the return value without affecting cache
return clone $this->mParserOptions;
@@ -1645,6 +1684,7 @@ class Article extends Page {
/**
* Handle action=purge
* @deprecated since 1.19
+ * @return Action|bool|null false if the action is disabled, null if it is not recognised
*/
public function purge() {
return Action::factory( 'purge', $this )->show();
@@ -1679,7 +1719,7 @@ class Article extends Page {
}
/**
- * Add this page to $wgUser's watchlist
+ * Add this page to the current user's watchlist
*
* This is safe to be called multiple times
*
@@ -1687,9 +1727,8 @@ class Article extends Page {
* @deprecated since 1.18
*/
public function doWatch() {
- global $wgUser;
wfDeprecated( __METHOD__, '1.18' );
- return WatchAction::doWatch( $this->getTitle(), $wgUser );
+ return WatchAction::doWatch( $this->getTitle(), $this->getContext()->getUser() );
}
/**
@@ -1708,24 +1747,21 @@ class Article extends Page {
* @deprecated since 1.18
*/
public function doUnwatch() {
- global $wgUser;
wfDeprecated( __METHOD__, '1.18' );
- return WatchAction::doUnwatch( $this->getTitle(), $wgUser );
+ return WatchAction::doUnwatch( $this->getTitle(), $this->getContext()->getUser() );
}
/**
* Output a redirect back to the article.
* This is typically used after an edit.
*
- * @deprecated in 1.18; call $wgOut->redirect() directly
+ * @deprecated in 1.18; call OutputPage::redirect() directly
* @param $noRedir Boolean: add redirect=no
* @param $sectionAnchor String: section to redirect to, including "#"
* @param $extraQuery String: extra query params
*/
public function doRedirect( $noRedir = false, $sectionAnchor = '', $extraQuery = '' ) {
wfDeprecated( __METHOD__, '1.18' );
- global $wgOut;
-
if ( $noRedir ) {
$query = 'redirect=no';
if ( $extraQuery )
@@ -1734,7 +1770,7 @@ class Article extends Page {
$query = $extraQuery;
}
- $wgOut->redirect( $this->getTitle()->getFullURL( $query ) . $sectionAnchor );
+ $this->getContext()->getOutput()->redirect( $this->getTitle()->getFullURL( $query ) . $sectionAnchor );
}
/**
@@ -1776,6 +1812,7 @@ class Article extends Page {
*
* @param $fname String Name of called method
* @param $args Array Arguments to the method
+ * @return mixed
*/
public function __call( $fname, $args ) {
if ( is_callable( array( $this->mPage, $fname ) ) ) {
@@ -1832,8 +1869,7 @@ class Article extends Page {
* @return array
*/
public function doRollback( $fromP, $summary, $token, $bot, &$resultDetails, User $user = null ) {
- global $wgUser;
- $user = is_null( $user ) ? $wgUser : $user;
+ $user = is_null( $user ) ? $this->getContext()->getUser() : $user;
return $this->mPage->doRollback( $fromP, $summary, $token, $bot, $resultDetails, $user );
}
@@ -1846,8 +1882,7 @@ class Article extends Page {
* @return array
*/
public function commitRollback( $fromP, $summary, $bot, &$resultDetails, User $guser = null ) {
- global $wgUser;
- $guser = is_null( $guser ) ? $wgUser : $guser;
+ $guser = is_null( $guser ) ? $this->getContext()->getUser() : $guser;
return $this->mPage->commitRollback( $fromP, $summary, $bot, $resultDetails, $guser );
}
diff --git a/includes/AuthPlugin.php b/includes/AuthPlugin.php
index e8bab859..2e42439c 100644
--- a/includes/AuthPlugin.php
+++ b/includes/AuthPlugin.php
@@ -34,6 +34,12 @@
* someone logs in who can be authenticated externally.
*/
class AuthPlugin {
+
+ /**
+ * @var string
+ */
+ protected $domain;
+
/**
* Check whether there exists a user account with the given name.
* The name will be normalized to MediaWiki's requirements, so
@@ -84,6 +90,19 @@ class AuthPlugin {
}
/**
+ * Get the user's domain
+ *
+ * @return string
+ */
+ public function getDomain() {
+ if ( isset( $this->domain ) ) {
+ return $this->domain;
+ } else {
+ return 'invaliddomain';
+ }
+ }
+
+ /**
* Check to see if the specific domain is a valid domain.
*
* @param $domain String: authentication domain.
@@ -103,6 +122,7 @@ class AuthPlugin {
* forget the & on your function declaration.
*
* @param $user User object
+ * @return bool
*/
public function updateUser( &$user ) {
# Override this and do something
@@ -256,6 +276,8 @@ class AuthPlugin {
/**
* If you want to munge the case of an account name before the final
* check, now is your chance.
+ * @param $username string
+ * @return string
*/
public function getCanonicalName( $username ) {
return $username;
diff --git a/includes/AutoLoader.php b/includes/AutoLoader.php
index 93fac45f..d3a2c548 100644
--- a/includes/AutoLoader.php
+++ b/includes/AutoLoader.php
@@ -2,6 +2,21 @@
/**
* This defines autoloading handler for whole MediaWiki framework
*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
* @file
*/
@@ -27,6 +42,7 @@ $wgAutoloadLocalClasses = array(
'BadTitleError' => 'includes/Exception.php',
'BaseTemplate' => 'includes/SkinTemplate.php',
'Block' => 'includes/Block.php',
+ 'CacheHelper' => 'includes/CacheHelper.php',
'Category' => 'includes/Category.php',
'Categoryfinder' => 'includes/Categoryfinder.php',
'CategoryPage' => 'includes/CategoryPage.php',
@@ -53,9 +69,11 @@ $wgAutoloadLocalClasses = array(
'CurlHttpRequest' => 'includes/HttpFunctions.php',
'DeferrableUpdate' => 'includes/DeferredUpdates.php',
'DeferredUpdates' => 'includes/DeferredUpdates.php',
+ 'DeprecatedGlobal' => 'includes/DeprecatedGlobal.php',
'DerivativeRequest' => 'includes/WebRequest.php',
+ 'DeviceDetection' => 'includes/mobile/DeviceDetection.php',
+ 'DeviceProperties' => 'includes/mobile/DeviceDetection.php',
'DiffHistoryBlob' => 'includes/HistoryBlob.php',
-
'DoubleReplacer' => 'includes/StringUtils.php',
'DummyLinker' => 'includes/Linker.php',
'Dump7ZipOutput' => 'includes/Export.php',
@@ -92,6 +110,7 @@ $wgAutoloadLocalClasses = array(
'FormAction' => 'includes/Action.php',
'FormOptions' => 'includes/FormOptions.php',
'FormSpecialPage' => 'includes/SpecialPage.php',
+ 'GitInfo' => 'includes/GitInfo.php',
'HashtableReplacer' => 'includes/StringUtils.php',
'HistoryBlob' => 'includes/HistoryBlob.php',
'HistoryBlobCurStub' => 'includes/HistoryBlob.php',
@@ -117,7 +136,10 @@ $wgAutoloadLocalClasses = array(
'Http' => 'includes/HttpFunctions.php',
'HttpError' => 'includes/Exception.php',
'HttpRequest' => 'includes/HttpFunctions.old.php',
+ 'ICacheHelper' => 'includes/CacheHelper.php',
'IcuCollation' => 'includes/Collation.php',
+ 'IDeviceProperties' => 'includes/mobile/DeviceDetection.php',
+ 'IDeviceDetector' => 'includes/mobile/DeviceDetection.php',
'IdentityCollation' => 'includes/Collation.php',
'ImageGallery' => 'includes/ImageGallery.php',
'ImageHistoryList' => 'includes/ImagePage.php',
@@ -140,6 +162,7 @@ $wgAutoloadLocalClasses = array(
'Linker' => 'includes/Linker.php',
'LinkFilter' => 'includes/LinkFilter.php',
'LinksUpdate' => 'includes/LinksUpdate.php',
+ 'LinksDeletionUpdate' => 'includes/LinksUpdate.php',
'LocalisationCache' => 'includes/LocalisationCache.php',
'LocalisationCache_BulkLoad' => 'includes/LocalisationCache.php',
'MagicWord' => 'includes/MagicWord.php',
@@ -153,6 +176,7 @@ $wgAutoloadLocalClasses = array(
'MWException' => 'includes/Exception.php',
'MWExceptionHandler' => 'includes/Exception.php',
'MWFunction' => 'includes/MWFunction.php',
+ 'MWHookException' => 'includes/Hooks.php',
'MWHttpRequest' => 'includes/HttpFunctions.php',
'MWInit' => 'includes/Init.php',
'MWNamespace' => 'includes/Namespace.php',
@@ -185,12 +209,16 @@ $wgAutoloadLocalClasses = array(
'ReplacementArray' => 'includes/StringUtils.php',
'Replacer' => 'includes/StringUtils.php',
'ReverseChronologicalPager' => 'includes/Pager.php',
+ 'RevisionItem' => 'includes/RevisionList.php',
'RevisionItemBase' => 'includes/RevisionList.php',
'RevisionListBase' => 'includes/RevisionList.php',
'Revision' => 'includes/Revision.php',
'RevisionList' => 'includes/RevisionList.php',
'RSSFeed' => 'includes/Feed.php',
'Sanitizer' => 'includes/Sanitizer.php',
+ 'DataUpdate' => 'includes/DataUpdate.php',
+ 'SqlDataUpdate' => 'includes/SqlDataUpdate.php',
+ 'ScopedPHPTimeout' => 'includes/ScopedPHPTimeout.php',
'SiteConfiguration' => 'includes/SiteConfiguration.php',
'SiteStats' => 'includes/SiteStats.php',
'SiteStatsInit' => 'includes/SiteStats.php',
@@ -217,16 +245,20 @@ $wgAutoloadLocalClasses = array(
'StubObject' => 'includes/StubObject.php',
'StubUserLang' => 'includes/StubObject.php',
'TablePager' => 'includes/Pager.php',
+ 'MWTimestamp' => 'includes/Timestamp.php',
'Title' => 'includes/Title.php',
'TitleArray' => 'includes/TitleArray.php',
'TitleArrayFromResult' => 'includes/TitleArray.php',
'ThrottledError' => 'includes/Exception.php',
'UnlistedSpecialPage' => 'includes/SpecialPage.php',
+ 'UploadSourceAdapter' => 'includes/Import.php',
'UppercaseCollation' => 'includes/Collation.php',
'User' => 'includes/User.php',
'UserArray' => 'includes/UserArray.php',
'UserArrayFromResult' => 'includes/UserArray.php',
'UserBlockedError' => 'includes/Exception.php',
+ 'UserNotLoggedIn' => 'includes/Exception.php',
+ 'UserCache' => 'includes/cache/UserCache.php',
'UserMailer' => 'includes/UserMailer.php',
'UserRightsProxy' => 'includes/UserRightsProxy.php',
'ViewCountUpdate' => 'includes/ViewCountUpdate.php',
@@ -249,12 +281,15 @@ $wgAutoloadLocalClasses = array(
'Xml' => 'includes/Xml.php',
'XmlDumpWriter' => 'includes/Export.php',
'XmlJsCode' => 'includes/Xml.php',
+ 'XMLReader2' => 'includes/Import.php',
'XmlSelect' => 'includes/Xml.php',
'XmlTypeCheck' => 'includes/XmlTypeCheck.php',
'ZhClient' => 'includes/ZhClient.php',
'ZipDirectoryReader' => 'includes/ZipDirectoryReader.php',
+ 'ZipDirectoryReaderError' => 'includes/ZipDirectoryReader.php',
# includes/actions
+ 'CachedAction' => 'includes/actions/CachedAction.php',
'CreditsAction' => 'includes/actions/CreditsAction.php',
'DeleteAction' => 'includes/actions/DeleteAction.php',
'EditAction' => 'includes/actions/EditAction.php',
@@ -310,6 +345,7 @@ $wgAutoloadLocalClasses = array(
'ApiMain' => 'includes/api/ApiMain.php',
'ApiMove' => 'includes/api/ApiMove.php',
'ApiOpenSearch' => 'includes/api/ApiOpenSearch.php',
+ 'ApiOptions' => 'includes/api/ApiOptions.php',
'ApiPageSet' => 'includes/api/ApiPageSet.php',
'ApiParamInfo' => 'includes/api/ApiParamInfo.php',
'ApiParse' => 'includes/api/ApiParse.php',
@@ -318,10 +354,10 @@ $wgAutoloadLocalClasses = array(
'ApiPurge' => 'includes/api/ApiPurge.php',
'ApiQuery' => 'includes/api/ApiQuery.php',
'ApiQueryAllCategories' => 'includes/api/ApiQueryAllCategories.php',
- 'ApiQueryAllimages' => 'includes/api/ApiQueryAllimages.php',
+ 'ApiQueryAllImages' => 'includes/api/ApiQueryAllImages.php',
'ApiQueryAllLinks' => 'includes/api/ApiQueryAllLinks.php',
- 'ApiQueryAllmessages' => 'includes/api/ApiQueryAllmessages.php',
- 'ApiQueryAllpages' => 'includes/api/ApiQueryAllpages.php',
+ 'ApiQueryAllMessages' => 'includes/api/ApiQueryAllMessages.php',
+ 'ApiQueryAllPages' => 'includes/api/ApiQueryAllPages.php',
'ApiQueryAllUsers' => 'includes/api/ApiQueryAllUsers.php',
'ApiQueryBacklinks' => 'includes/api/ApiQueryBacklinks.php',
'ApiQueryBase' => 'includes/api/ApiQueryBase.php',
@@ -363,11 +399,14 @@ $wgAutoloadLocalClasses = array(
'ApiResult' => 'includes/api/ApiResult.php',
'ApiRollback' => 'includes/api/ApiRollback.php',
'ApiRsd' => 'includes/api/ApiRsd.php',
+ 'ApiSetNotificationTimestamp' => 'includes/api/ApiSetNotificationTimestamp.php',
+ 'ApiTokens' => 'includes/api/ApiTokens.php',
'ApiUnblock' => 'includes/api/ApiUnblock.php',
'ApiUndelete' => 'includes/api/ApiUndelete.php',
'ApiUpload' => 'includes/api/ApiUpload.php',
'ApiUserrights' => 'includes/api/ApiUserrights.php',
'ApiWatch' => 'includes/api/ApiWatch.php',
+ 'UsageException' => 'includes/api/ApiMain.php',
# includes/cache
'CacheDependency' => 'includes/cache/CacheDependency.php',
@@ -384,19 +423,21 @@ $wgAutoloadLocalClasses = array(
'LinkCache' => 'includes/cache/LinkCache.php',
'MessageCache' => 'includes/cache/MessageCache.php',
'ObjectFileCache' => 'includes/cache/ObjectFileCache.php',
+ 'ProcessCacheLRU' => 'includes/cache/ProcessCacheLRU.php',
'ResourceFileCache' => 'includes/cache/ResourceFileCache.php',
'SquidUpdate' => 'includes/cache/SquidUpdate.php',
'TitleDependency' => 'includes/cache/CacheDependency.php',
'TitleListDependency' => 'includes/cache/CacheDependency.php',
- 'UsageException' => 'includes/api/ApiMain.php',
-
# includes/context
'ContextSource' => 'includes/context/ContextSource.php',
'DerivativeContext' => 'includes/context/DerivativeContext.php',
'IContextSource' => 'includes/context/IContextSource.php',
'RequestContext' => 'includes/context/RequestContext.php',
+ # includes/dao
+ 'IDBAccessObject' => 'includes/dao/IDBAccessObject.php',
+
# includes/db
'Blob' => 'includes/db/DatabaseUtility.php',
'ChronologyProtector' => 'includes/db/LBFactory.php',
@@ -411,9 +452,12 @@ $wgAutoloadLocalClasses = array(
'DatabaseSqlite' => 'includes/db/DatabaseSqlite.php',
'DatabaseSqliteStandalone' => 'includes/db/DatabaseSqlite.php',
'DatabaseType' => 'includes/db/Database.php',
+ 'DBAccessError' => 'includes/db/LBFactory.php',
'DBConnectionError' => 'includes/db/DatabaseError.php',
'DBError' => 'includes/db/DatabaseError.php',
'DBObject' => 'includes/db/DatabaseUtility.php',
+ 'IORMRow' => 'includes/db/IORMRow.php',
+ 'IORMTable' => 'includes/db/IORMTable.php',
'DBMasterPos' => 'includes/db/DatabaseUtility.php',
'DBQueryError' => 'includes/db/DatabaseError.php',
'DBUnexpectedError' => 'includes/db/DatabaseError.php',
@@ -421,7 +465,10 @@ $wgAutoloadLocalClasses = array(
'Field' => 'includes/db/DatabaseUtility.php',
'IBM_DB2Blob' => 'includes/db/DatabaseIbm_db2.php',
'IBM_DB2Field' => 'includes/db/DatabaseIbm_db2.php',
+ 'IBM_DB2Helper' => 'includes/db/DatabaseIbm_db2.php',
+ 'IBM_DB2Result' => 'includes/db/DatabaseIbm_db2.php',
'LBFactory' => 'includes/db/LBFactory.php',
+ 'LBFactory_Fake' => 'includes/db/LBFactory.php',
'LBFactory_Multi' => 'includes/db/LBFactory_Multi.php',
'LBFactory_Simple' => 'includes/db/LBFactory.php',
'LBFactory_Single' => 'includes/db/LBFactory_Single.php',
@@ -431,12 +478,20 @@ $wgAutoloadLocalClasses = array(
'LoadMonitor' => 'includes/db/LoadMonitor.php',
'LoadMonitor_MySQL' => 'includes/db/LoadMonitor.php',
'LoadMonitor_Null' => 'includes/db/LoadMonitor.php',
+ 'MssqlField' => 'includes/db/DatabaseMssql.php',
+ 'MssqlResult' => 'includes/db/DatabaseMssql.php',
'MySQLField' => 'includes/db/DatabaseMysql.php',
'MySQLMasterPos' => 'includes/db/DatabaseMysql.php',
'ORAField' => 'includes/db/DatabaseOracle.php',
'ORAResult' => 'includes/db/DatabaseOracle.php',
+ 'ORMIterator' => 'includes/db/ORMIterator.php',
+ 'ORMResult' => 'includes/db/ORMResult.php',
+ 'ORMRow' => 'includes/db/ORMRow.php',
+ 'ORMTable' => 'includes/db/ORMTable.php',
'PostgresField' => 'includes/db/DatabasePostgres.php',
+ 'PostgresTransactionState' => 'includes/db/DatabasePostgres.php',
'ResultWrapper' => 'includes/db/DatabaseUtility.php',
+ 'SavepointPostgres' => 'includes/db/DatabasePostgres.php',
'SQLiteField' => 'includes/db/DatabaseSqlite.php',
# includes/debug
@@ -466,6 +521,50 @@ $wgAutoloadLocalClasses = array(
'ExternalUser_MediaWiki' => 'includes/extauth/MediaWiki.php',
'ExternalUser_vB' => 'includes/extauth/vB.php',
+ # includes/filebackend
+ 'FileBackendGroup' => 'includes/filebackend/FileBackendGroup.php',
+ 'FileBackend' => 'includes/filebackend/FileBackend.php',
+ 'FileBackendStore' => 'includes/filebackend/FileBackendStore.php',
+ 'FileBackendStoreShardListIterator' => 'includes/filebackend/FileBackendStore.php',
+ 'FileBackendStoreShardDirIterator' => 'includes/filebackend/FileBackendStore.php',
+ 'FileBackendStoreShardFileIterator' => 'includes/filebackend/FileBackendStore.php',
+ 'FileBackendMultiWrite' => 'includes/filebackend/FileBackendMultiWrite.php',
+ 'FileBackendStoreOpHandle' => 'includes/filebackend/FileBackendStore.php',
+ 'FSFile' => 'includes/filebackend/FSFile.php',
+ 'FSFileBackend' => 'includes/filebackend/FSFileBackend.php',
+ 'FSFileBackendList' => 'includes/filebackend/FSFileBackend.php',
+ 'FSFileBackendDirList' => 'includes/filebackend/FSFileBackend.php',
+ 'FSFileBackendFileList' => 'includes/filebackend/FSFileBackend.php',
+ 'FSFileOpHandle' => 'includes/filebackend/FSFileBackend.php',
+ 'SwiftFileBackend' => 'includes/filebackend/SwiftFileBackend.php',
+ 'SwiftFileBackendList' => 'includes/filebackend/SwiftFileBackend.php',
+ 'SwiftFileBackendDirList' => 'includes/filebackend/SwiftFileBackend.php',
+ 'SwiftFileBackendFileList' => 'includes/filebackend/SwiftFileBackend.php',
+ 'SwiftFileOpHandle' => 'includes/filebackend/SwiftFileBackend.php',
+ 'TempFSFile' => 'includes/filebackend/TempFSFile.php',
+ 'FileJournal' => 'includes/filebackend/filejournal/FileJournal.php',
+ 'DBFileJournal' => 'includes/filebackend/filejournal/DBFileJournal.php',
+ 'NullFileJournal' => 'includes/filebackend/filejournal/FileJournal.php',
+ 'LockManagerGroup' => 'includes/filebackend/lockmanager/LockManagerGroup.php',
+ 'LockManager' => 'includes/filebackend/lockmanager/LockManager.php',
+ 'ScopedLock' => 'includes/filebackend/lockmanager/LockManager.php',
+ 'FSLockManager' => 'includes/filebackend/lockmanager/FSLockManager.php',
+ 'DBLockManager' => 'includes/filebackend/lockmanager/DBLockManager.php',
+ 'LSLockManager' => 'includes/filebackend/lockmanager/LSLockManager.php',
+ 'MemcLockManager' => 'includes/filebackend/lockmanager/MemcLockManager.php',
+ 'QuorumLockManager' => 'includes/filebackend/lockmanager/LockManager.php',
+ 'MySqlLockManager'=> 'includes/filebackend/lockmanager/DBLockManager.php',
+ 'NullLockManager' => 'includes/filebackend/lockmanager/LockManager.php',
+ 'FileOp' => 'includes/filebackend/FileOp.php',
+ 'FileOpBatch' => 'includes/filebackend/FileOpBatch.php',
+ 'StoreFileOp' => 'includes/filebackend/FileOp.php',
+ 'CopyFileOp' => 'includes/filebackend/FileOp.php',
+ 'MoveFileOp' => 'includes/filebackend/FileOp.php',
+ 'DeleteFileOp' => 'includes/filebackend/FileOp.php',
+ 'ConcatenateFileOp' => 'includes/filebackend/FileOp.php',
+ 'CreateFileOp' => 'includes/filebackend/FileOp.php',
+ 'NullFileOp' => 'includes/filebackend/FileOp.php',
+
# includes/filerepo
'FileRepo' => 'includes/filerepo/FileRepo.php',
'FileRepoStatus' => 'includes/filerepo/FileRepoStatus.php',
@@ -476,6 +575,7 @@ $wgAutoloadLocalClasses = array(
'LocalRepo' => 'includes/filerepo/LocalRepo.php',
'NullRepo' => 'includes/filerepo/NullRepo.php',
'RepoGroup' => 'includes/filerepo/RepoGroup.php',
+ 'TempFileRepo' => 'includes/filerepo/FileRepo.php',
# includes/filerepo/file
'ArchivedFile' => 'includes/filerepo/file/ArchivedFile.php',
@@ -488,36 +588,6 @@ $wgAutoloadLocalClasses = array(
'LocalFileRestoreBatch' => 'includes/filerepo/file/LocalFile.php',
'OldLocalFile' => 'includes/filerepo/file/OldLocalFile.php',
'UnregisteredLocalFile' => 'includes/filerepo/file/UnregisteredLocalFile.php',
- 'FSFile' => 'includes/filerepo/backend/FSFile.php',
- 'TempFSFile' => 'includes/filerepo/backend/TempFSFile.php',
-
- # includes/filerepo/backend
- 'FileBackendGroup' => 'includes/filerepo/backend/FileBackendGroup.php',
- 'FileBackend' => 'includes/filerepo/backend/FileBackend.php',
- 'FileBackendStore' => 'includes/filerepo/backend/FileBackend.php',
- 'FileBackendMultiWrite' => 'includes/filerepo/backend/FileBackendMultiWrite.php',
- 'FileBackendStoreShardListIterator' => 'includes/filerepo/backend/FileBackend.php',
- 'FSFileBackend' => 'includes/filerepo/backend/FSFileBackend.php',
- 'FSFileBackendFileList' => 'includes/filerepo/backend/FSFileBackend.php',
- 'SwiftFileBackend' => 'includes/filerepo/backend/SwiftFileBackend.php',
- 'SwiftFileBackendFileList' => 'includes/filerepo/backend/SwiftFileBackend.php',
- 'LockManagerGroup' => 'includes/filerepo/backend/lockmanager/LockManagerGroup.php',
- 'LockManager' => 'includes/filerepo/backend/lockmanager/LockManager.php',
- 'ScopedLock' => 'includes/filerepo/backend/lockmanager/LockManager.php',
- 'FSLockManager' => 'includes/filerepo/backend/lockmanager/FSLockManager.php',
- 'DBLockManager' => 'includes/filerepo/backend/lockmanager/DBLockManager.php',
- 'LSLockManager' => 'includes/filerepo/backend/lockmanager/LSLockManager.php',
- 'MySqlLockManager'=> 'includes/filerepo/backend/lockmanager/DBLockManager.php',
- 'NullLockManager' => 'includes/filerepo/backend/lockmanager/LockManager.php',
- 'FileOp' => 'includes/filerepo/backend/FileOp.php',
- 'FileOpScopedPHPTimeout' => 'includes/filerepo/backend/FileOp.php',
- 'StoreFileOp' => 'includes/filerepo/backend/FileOp.php',
- 'CopyFileOp' => 'includes/filerepo/backend/FileOp.php',
- 'MoveFileOp' => 'includes/filerepo/backend/FileOp.php',
- 'DeleteFileOp' => 'includes/filerepo/backend/FileOp.php',
- 'ConcatenateFileOp' => 'includes/filerepo/backend/FileOp.php',
- 'CreateFileOp' => 'includes/filerepo/backend/FileOp.php',
- 'NullFileOp' => 'includes/filerepo/backend/FileOp.php',
# includes/installer
'CliInstaller' => 'includes/installer/CliInstaller.php',
@@ -563,7 +633,7 @@ $wgAutoloadLocalClasses = array(
'DoubleRedirectJob' => 'includes/job/DoubleRedirectJob.php',
'EmaillingJob' => 'includes/job/EmaillingJob.php',
'EnotifNotifyJob' => 'includes/job/EnotifNotifyJob.php',
- 'Job' => 'includes/job/JobQueue.php',
+ 'Job' => 'includes/job/Job.php',
'RefreshLinksJob' => 'includes/job/RefreshLinksJob.php',
'RefreshLinksJob2' => 'includes/job/RefreshLinksJob.php',
'UploadFromUrlJob' => 'includes/job/UploadFromUrlJob.php',
@@ -575,13 +645,19 @@ $wgAutoloadLocalClasses = array(
# includes/libs
'CSSJanus' => 'includes/libs/CSSJanus.php',
+ 'CSSJanus_Tokenizer' => 'includes/libs/CSSJanus.php',
'CSSMin' => 'includes/libs/CSSMin.php',
+ 'GenericArrayObject' => 'includes/libs/GenericArrayObject.php',
'HttpStatus' => 'includes/libs/HttpStatus.php',
'IEContentAnalyzer' => 'includes/libs/IEContentAnalyzer.php',
'IEUrlExtension' => 'includes/libs/IEUrlExtension.php',
'JavaScriptMinifier' => 'includes/libs/JavaScriptMinifier.php',
+ 'JSCompilerContext' => 'includes/libs/jsminplus.php',
'JSMinPlus' => 'includes/libs/jsminplus.php',
+ 'JSNode' => 'includes/libs/jsminplus.php',
'JSParser' => 'includes/libs/jsminplus.php',
+ 'JSToken' => 'includes/libs/jsminplus.php',
+ 'JSTokenizer' => 'includes/libs/jsminplus.php',
# includes/logging
'DatabaseLogEntry' => 'includes/logging/LogEntry.php',
@@ -613,17 +689,18 @@ $wgAutoloadLocalClasses = array(
'FormatMetadata' => 'includes/media/FormatMetadata.php',
'GIFHandler' => 'includes/media/GIF.php',
'GIFMetadataExtractor' => 'includes/media/GIFMetadataExtractor.php',
- 'ImageHandler' => 'includes/media/Generic.php',
+ 'ImageHandler' => 'includes/media/ImageHandler.php',
'IPTC' => 'includes/media/IPTC.php',
'JpegHandler' => 'includes/media/Jpeg.php',
'JpegMetadataExtractor' => 'includes/media/JpegMetadataExtractor.php',
- 'MediaHandler' => 'includes/media/Generic.php',
+ 'MediaHandler' => 'includes/media/MediaHandler.php',
'MediaTransformError' => 'includes/media/MediaTransformOutput.php',
'MediaTransformOutput' => 'includes/media/MediaTransformOutput.php',
'PNGHandler' => 'includes/media/PNG.php',
'PNGMetadataExtractor' => 'includes/media/PNGMetadataExtractor.php',
'SvgHandler' => 'includes/media/SVG.php',
'SVGMetadataExtractor' => 'includes/media/SVGMetadataExtractor.php',
+ 'SVGReader' => 'includes/media/SVGMetadataExtractor.php',
'ThumbnailImage' => 'includes/media/MediaTransformOutput.php',
'TiffHandler' => 'includes/media/Tiff.php',
'TransformParameterError' => 'includes/media/MediaTransformOutput.php',
@@ -645,16 +722,20 @@ $wgAutoloadLocalClasses = array(
'HashBagOStuff' => 'includes/objectcache/HashBagOStuff.php',
'MediaWikiBagOStuff' => 'includes/objectcache/SqlBagOStuff.php',
'MemCachedClientforWiki' => 'includes/objectcache/MemcachedClient.php',
+ 'MemcachedBagOStuff' => 'includes/objectcache/MemcachedBagOStuff.php',
+ 'MemcachedPeclBagOStuff' => 'includes/objectcache/MemcachedPeclBagOStuff.php',
'MemcachedPhpBagOStuff' => 'includes/objectcache/MemcachedPhpBagOStuff.php',
'MultiWriteBagOStuff' => 'includes/objectcache/MultiWriteBagOStuff.php',
'MWMemcached' => 'includes/objectcache/MemcachedClient.php',
'ObjectCache' => 'includes/objectcache/ObjectCache.php',
+ 'ObjectCacheSessionHandler' => 'includes/objectcache/ObjectCacheSessionHandler.php',
+ 'RedisBagOStuff' => 'includes/objectcache/RedisBagOStuff.php',
'SqlBagOStuff' => 'includes/objectcache/SqlBagOStuff.php',
'WinCacheBagOStuff' => 'includes/objectcache/WinCacheBagOStuff.php',
'XCacheBagOStuff' => 'includes/objectcache/XCacheBagOStuff.php',
# includes/parser
- 'CacheTime' => 'includes/parser/ParserOutput.php',
+ 'CacheTime' => 'includes/parser/CacheTime.php',
'CoreLinkFunctions' => 'includes/parser/CoreLinkFunctions.php',
'CoreParserFunctions' => 'includes/parser/CoreParserFunctions.php',
'CoreTagHooks' => 'includes/parser/CoreTagHooks.php',
@@ -662,6 +743,7 @@ $wgAutoloadLocalClasses = array(
'LinkHolderArray' => 'includes/parser/LinkHolderArray.php',
'LinkMarkerReplacer' => 'includes/parser/Parser_LinkHooks.php',
'MWTidy' => 'includes/parser/Tidy.php',
+ 'MWTidyWrapper' => 'includes/parser/Tidy.php',
'PPCustomFrame_DOM' => 'includes/parser/Preprocessor_DOM.php',
'PPCustomFrame_Hash' => 'includes/parser/Preprocessor_Hash.php',
'PPCustomFrame_HipHop' => 'includes/parser/Preprocessor_HipHop.hphp',
@@ -727,11 +809,13 @@ $wgAutoloadLocalClasses = array(
'ResourceLoaderUserModule' => 'includes/resourceloader/ResourceLoaderUserModule.php',
'ResourceLoaderUserOptionsModule' => 'includes/resourceloader/ResourceLoaderUserOptionsModule.php',
'ResourceLoaderUserTokensModule' => 'includes/resourceloader/ResourceLoaderUserTokensModule.php',
+ 'ResourceLoaderLanguageDataModule' => 'includes/resourceloader/ResourceLoaderLanguageDataModule.php',
'ResourceLoaderWikiModule' => 'includes/resourceloader/ResourceLoaderWikiModule.php',
# includes/revisiondelete
'RevDel_ArchivedFileItem' => 'includes/revisiondelete/RevisionDelete.php',
'RevDel_ArchivedFileList' => 'includes/revisiondelete/RevisionDelete.php',
+ 'RevDel_ArchivedRevisionItem' => 'includes/revisiondelete/RevisionDelete.php',
'RevDel_ArchiveItem' => 'includes/revisiondelete/RevisionDelete.php',
'RevDel_ArchiveList' => 'includes/revisiondelete/RevisionDelete.php',
'RevDel_FileItem' => 'includes/revisiondelete/RevisionDelete.php',
@@ -747,6 +831,7 @@ $wgAutoloadLocalClasses = array(
'RevisionDeleteUser' => 'includes/revisiondelete/RevisionDeleteUser.php',
# includes/search
+ 'MssqlSearchResultSet' => 'includes/search/SearchMssql.php',
'MySQLSearchResultSet' => 'includes/search/SearchMySQL.php',
'PostgresSearchResult' => 'includes/search/SearchPostgres.php',
'PostgresSearchResultSet' => 'includes/search/SearchPostgres.php',
@@ -756,6 +841,7 @@ $wgAutoloadLocalClasses = array(
'SearchIBM_DB2' => 'includes/search/SearchIBM_DB2.php',
'SearchMssql' => 'includes/search/SearchMssql.php',
'SearchMySQL' => 'includes/search/SearchMySQL.php',
+ 'SearchNearMatchResultSet' => 'includes/search/SearchEngine.php',
'SearchOracle' => 'includes/search/SearchOracle.php',
'SearchPostgres' => 'includes/search/SearchPostgres.php',
'SearchResult' => 'includes/search/SearchEngine.php',
@@ -773,6 +859,7 @@ $wgAutoloadLocalClasses = array(
'AncientPagesPage' => 'includes/specials/SpecialAncientpages.php',
'BlockListPager' => 'includes/specials/SpecialBlockList.php',
'BrokenRedirectsPage' => 'includes/specials/SpecialBrokenRedirects.php',
+ 'CategoryPager' => 'includes/specials/SpecialCategories.php',
'ContribsPager' => 'includes/specials/SpecialContributions.php',
'DBLockForm' => 'includes/specials/SpecialLockdb.php',
'DBUnlockForm' => 'includes/specials/SpecialUnlockdb.php',
@@ -781,11 +868,14 @@ $wgAutoloadLocalClasses = array(
'DeletedContributionsPage' => 'includes/specials/SpecialDeletedContributions.php',
'DisambiguationsPage' => 'includes/specials/SpecialDisambiguations.php',
'DoubleRedirectsPage' => 'includes/specials/SpecialDoubleRedirects.php',
+ 'EditWatchlistCheckboxSeriesField' => 'includes/specials/SpecialEditWatchlist.php',
+ 'EditWatchlistNormalHTMLForm' => 'includes/specials/SpecialEditWatchlist.php',
'EmailConfirmation' => 'includes/specials/SpecialConfirmemail.php',
'EmailInvalidation' => 'includes/specials/SpecialConfirmemail.php',
'FewestrevisionsPage' => 'includes/specials/SpecialFewestrevisions.php',
'FileDuplicateSearchPage' => 'includes/specials/SpecialFileDuplicateSearch.php',
'HTMLBlockedUsersItemSelect' => 'includes/specials/SpecialBlockList.php',
+ 'ImageListPager' => 'includes/specials/SpecialListfiles.php',
'ImportReporter' => 'includes/specials/SpecialImport.php',
'IPBlockForm' => 'includes/specials/SpecialBlock.php',
'LinkSearchPage' => 'includes/specials/SpecialLinkSearch.php',
@@ -793,17 +883,22 @@ $wgAutoloadLocalClasses = array(
'LoginForm' => 'includes/specials/SpecialUserlogin.php',
'LonelyPagesPage' => 'includes/specials/SpecialLonelypages.php',
'LongPagesPage' => 'includes/specials/SpecialLongpages.php',
+ 'MergeHistoryPager' => 'includes/specials/SpecialMergeHistory.php',
'MIMEsearchPage' => 'includes/specials/SpecialMIMEsearch.php',
'MostcategoriesPage' => 'includes/specials/SpecialMostcategories.php',
'MostimagesPage' => 'includes/specials/SpecialMostimages.php',
+ 'MostinterwikisPage' => 'includes/specials/SpecialMostinterwikis.php',
'MostlinkedCategoriesPage' => 'includes/specials/SpecialMostlinkedcategories.php',
'MostlinkedPage' => 'includes/specials/SpecialMostlinked.php',
'MostlinkedTemplatesPage' => 'includes/specials/SpecialMostlinkedtemplates.php',
'MostrevisionsPage' => 'includes/specials/SpecialMostrevisions.php',
'MovePageForm' => 'includes/specials/SpecialMovepage.php',
+ 'NewFilesPager' => 'includes/specials/SpecialNewimages.php',
'NewPagesPager' => 'includes/specials/SpecialNewpages.php',
'PageArchive' => 'includes/specials/SpecialUndelete.php',
'PopularPagesPage' => 'includes/specials/SpecialPopularpages.php',
+ 'ProtectedPagesPager' => 'includes/specials/SpecialProtectedpages.php',
+ 'ProtectedTitlesPager' => 'includes/specials/SpecialProtectedtitles.php',
'RandomPage' => 'includes/specials/SpecialRandompage.php',
'ShortPagesPage' => 'includes/specials/SpecialShortpages.php',
'SpecialActiveUsers' => 'includes/specials/SpecialActiveusers.php',
@@ -814,6 +909,7 @@ $wgAutoloadLocalClasses = array(
'SpecialBlockList' => 'includes/specials/SpecialBlockList.php',
'SpecialBlockme' => 'includes/specials/SpecialBlockme.php',
'SpecialBookSources' => 'includes/specials/SpecialBooksources.php',
+ 'SpecialCachedPage' => 'includes/specials/SpecialCachedPage.php',
'SpecialCategories' => 'includes/specials/SpecialCategories.php',
'SpecialChangeEmail' => 'includes/specials/SpecialChangeEmail.php',
'SpecialChangePassword' => 'includes/specials/SpecialChangePassword.php',
@@ -853,10 +949,11 @@ $wgAutoloadLocalClasses = array(
'SpecialUnlockdb' => 'includes/specials/SpecialUnlockdb.php',
'SpecialUpload' => 'includes/specials/SpecialUpload.php',
'SpecialUploadStash' => 'includes/specials/SpecialUploadStash.php',
+ 'SpecialUploadStashTooLargeException' => 'includes/specials/SpecialUploadStash.php',
'SpecialUserlogout' => 'includes/specials/SpecialUserlogout.php',
'SpecialVersion' => 'includes/specials/SpecialVersion.php',
'SpecialWatchlist' => 'includes/specials/SpecialWatchlist.php',
- 'SpecialWhatlinkshere' => 'includes/specials/SpecialWhatlinkshere.php',
+ 'SpecialWhatLinksHere' => 'includes/specials/SpecialWhatlinkshere.php',
'UncategorizedCategoriesPage' => 'includes/specials/SpecialUncategorizedcategories.php',
'UncategorizedImagesPage' => 'includes/specials/SpecialUncategorizedimages.php',
'UncategorizedPagesPage' => 'includes/specials/SpecialUncategorizedpages.php',
@@ -865,6 +962,8 @@ $wgAutoloadLocalClasses = array(
'UnusedimagesPage' => 'includes/specials/SpecialUnusedimages.php',
'UnusedtemplatesPage' => 'includes/specials/SpecialUnusedtemplates.php',
'UnwatchedpagesPage' => 'includes/specials/SpecialUnwatchedpages.php',
+ 'UploadChunkFileException' => 'includes/upload/UploadFromChunks.php',
+ 'UploadChunkZeroLengthFileException' => 'includes/upload/UploadFromChunks.php',
'UploadForm' => 'includes/specials/SpecialUpload.php',
'UploadSourceField' => 'includes/specials/SpecialUpload.php',
'UserrightsPage' => 'includes/specials/SpecialUserrights.php',
@@ -899,9 +998,12 @@ $wgAutoloadLocalClasses = array(
'UploadStashNoSuchKeyException' => 'includes/upload/UploadStash.php',
# languages
+ 'ConverterRule' => 'languages/LanguageConverter.php',
'FakeConverter' => 'languages/Language.php',
'Language' => 'languages/Language.php',
'LanguageConverter' => 'languages/LanguageConverter.php',
+ 'CLDRPluralRuleEvaluator' => 'languages/utils/CLDRPluralRuleEvaluator.php',
+ 'CLDRPluralRuleError' => 'languages/utils/CLDRPluralRuleEvaluator.php',
# maintenance
'ConvertLinks' => 'maintenance/convertLinks.php',
@@ -928,6 +1030,7 @@ $wgAutoloadLocalClasses = array(
# maintenance/language
'csvStatsOutput' => 'maintenance/language/StatOutputs.php',
+ 'extensionLanguages' => 'maintenance/language/languages.inc',
'languages' => 'maintenance/language/languages.inc',
'MessageWriter' => 'maintenance/language/writeMessagesArray.inc',
'statsOutput' => 'maintenance/language/StatOutputs.php',
@@ -938,16 +1041,26 @@ $wgAutoloadLocalClasses = array(
'AnsiTermColorer' => 'maintenance/term/MWTerm.php',
'DummyTermColorer' => 'maintenance/term/MWTerm.php',
+ # mw-config
+ 'InstallerOverrides' => 'mw-config/overrides.php',
+ 'MyLocalSettingsGenerator' => 'mw-config/overrides.php',
+
# tests
'DbTestPreviewer' => 'tests/testHelpers.inc',
'DbTestRecorder' => 'tests/testHelpers.inc',
+ 'DelayedParserTest' => 'tests/testHelpers.inc',
'TestFileIterator' => 'tests/testHelpers.inc',
'TestRecorder' => 'tests/testHelpers.inc',
+ # tests/phpunit/includes
+ 'GenericArrayObjectTest' => 'tests/phpunit/includes/libs/GenericArrayObjectTest.php',
+
+ # tests/phpunit/includes/db
+ 'ORMRowTest' => 'tests/phpunit/includes/db/ORMRowTest.php',
+
# tests/parser
'ParserTest' => 'tests/parser/parserTest.inc',
'ParserTestParserHook' => 'tests/parser/parserTestsParserHook.php',
- 'ParserTestStaticParserHook' => 'tests/parser/parserTestsStaticParserHook.php',
# tests/selenium
'Selenium' => 'tests/selenium/Selenium.php',
@@ -958,6 +1071,23 @@ $wgAutoloadLocalClasses = array(
'SeleniumTestListener' => 'tests/selenium/SeleniumTestListener.php',
'SeleniumTestSuite' => 'tests/selenium/SeleniumTestSuite.php',
'SeleniumConfig' => 'tests/selenium/SeleniumConfig.php',
+
+ # skins
+ 'CologneBlueTemplate' => 'skins/CologneBlue.php',
+ 'ModernTemplate' => 'skins/Modern.php',
+ 'MonoBookTemplate' => 'skins/MonoBook.php',
+ 'NostalgiaTemplate' => 'skins/Nostalgia.php',
+ 'SkinChick' => 'skins/Chick.php',
+ 'SkinCologneBlue' => 'skins/CologneBlue.php',
+ 'SkinModern' => 'skins/Modern.php',
+ 'SkinMonoBook' => 'skins/MonoBook.php',
+ 'SkinMySkin' => 'skins/MySkin.php',
+ 'SkinNostalgia' => 'skins/Nostalgia.php',
+ 'SkinSimple' => 'skins/Simple.php',
+ 'SkinStandard' => 'skins/Standard.php',
+ 'SkinVector' => 'skins/Vector.php',
+ 'StandardTemplate' => 'skins/Standard.php',
+ 'VectorTemplate' => 'skins/Vector.php',
);
class AutoLoader {
@@ -972,6 +1102,14 @@ class AutoLoader {
static function autoload( $className ) {
global $wgAutoloadClasses, $wgAutoloadLocalClasses;
+ // Workaround for PHP bug <https://bugs.php.net/bug.php?id=49143> (5.3.2. is broken, it's fixed in 5.3.6).
+ // Strip leading backslashes from class names. When namespaces are used, leading backslashes are used to indicate
+ // the top-level namespace, e.g. \foo\Bar. When used like this in the code, the leading backslash isn't passed to
+ // the auto-loader ($className would be 'foo\Bar'). However, if a class is accessed using a string instead of a
+ // class literal (e.g. $class = '\foo\Bar'; new $class()), then some versions of PHP do not strip the leading
+ // backlash in this case, causing autoloading to fail.
+ $className = ltrim( $className, '\\' );
+
if ( isset( $wgAutoloadLocalClasses[$className] ) ) {
$filename = $wgAutoloadLocalClasses[$className];
} elseif ( isset( $wgAutoloadClasses[$className] ) ) {
@@ -1014,6 +1152,7 @@ class AutoLoader {
* Sanitizer that have define()s outside of their class definition. Of course
* this wouldn't be necessary if everything in MediaWiki was class-based. Sigh.
*
+ * @param $class string
* @return Boolean Return the results of class_exists() so we know if we were successful
*/
static function loadClass( $class ) {
diff --git a/includes/Autopromote.php b/includes/Autopromote.php
index a2336030..9c77855d 100644
--- a/includes/Autopromote.php
+++ b/includes/Autopromote.php
@@ -1,9 +1,30 @@
<?php
/**
+ * Automatic user rights promotion based on conditions specified
+ * in $wgAutopromote.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ * @file
+ */
+
+/**
* This class checks if user can get extra rights
* because of conditions specified in $wgAutopromote
*/
-
class Autopromote {
/**
* Get the groups for the given user based on $wgAutopromote.
@@ -32,7 +53,7 @@ class Autopromote {
*
* Does not return groups the user already belongs to or has once belonged.
*
- * @param $user The user to get the groups for
+ * @param $user User The user to get the groups for
* @param $event String key in $wgAutopromoteOnce (each one has groups/criteria)
*
* @return array Groups the user should be promoted to.
diff --git a/includes/BacklinkCache.php b/includes/BacklinkCache.php
index d17104f8..05bf3186 100644
--- a/includes/BacklinkCache.php
+++ b/includes/BacklinkCache.php
@@ -1,7 +1,28 @@
<?php
/**
- * File for BacklinkCache class
+ * Class for fetching backlink lists, approximate backlink counts and
+ * partitions.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
* @file
+ * @author Tim Starling
+ * @copyright © 2009, Tim Starling, Domas Mituzas
+ * @copyright © 2010, Max Sem
+ * @copyright © 2011, Antoine Musso
*/
/**
@@ -18,13 +39,10 @@
* Introduced by r47317
*
* @internal documentation reviewed on 18 Mar 2011 by hashar
- *
- * @author Tim Starling
- * @copyright © 2009, Tim Starling, Domas Mituzas
- * @copyright © 2010, Max Sem
- * @copyright © 2011, Antoine Musso
*/
class BacklinkCache {
+ /** @var ProcessCacheLRU */
+ protected static $cache;
/**
* Multi dimensions array representing batches. Keys are:
@@ -65,13 +83,33 @@ class BacklinkCache {
/**
* Create a new BacklinkCache
- * @param Title $title : Title object to create a backlink cache for.
+ *
+ * @param Title $title : Title object to create a backlink cache for
*/
- function __construct( $title ) {
+ public function __construct( Title $title ) {
$this->title = $title;
}
/**
+ * Create a new BacklinkCache or reuse any existing one.
+ * Currently, only one cache instance can exist; callers that
+ * need multiple backlink cache objects should keep them in scope.
+ *
+ * @param Title $title : Title object to get a backlink cache for
+ * @return BacklinkCache
+ */
+ public static function get( Title $title ) {
+ if ( !self::$cache ) { // init cache
+ self::$cache = new ProcessCacheLRU( 1 );
+ }
+ $dbKey = $title->getPrefixedDBkey();
+ if ( !self::$cache->has( $dbKey, 'obj' ) ) {
+ self::$cache->set( $dbKey, 'obj', new self( $title ) );
+ }
+ return self::$cache->get( $dbKey, 'obj' );
+ }
+
+ /**
* Serialization handler, diasallows to serialize the database to prevent
* failures after this class is deserialized from cache with dead DB
* connection.
@@ -103,7 +141,7 @@ class BacklinkCache {
/**
* Get the slave connection to the database
* When non existing, will initialize the connection.
- * @return Database object
+ * @return DatabaseBase object
*/
protected function getDB() {
if ( !isset( $this->db ) ) {
@@ -179,6 +217,7 @@ class BacklinkCache {
/**
* Get the field name prefix for a given table
* @param $table String
+ * @return null|string
*/
protected function getPrefix( $table ) {
static $prefixes = array(
@@ -206,6 +245,7 @@ class BacklinkCache {
* Get the SQL condition array for selecting backlinks, with a join
* on the page table.
* @param $table String
+ * @return array|null
*/
protected function getConditions( $table ) {
$prefix = $this->getPrefix( $table );
@@ -285,7 +325,7 @@ class BacklinkCache {
*/
public function partition( $table, $batchSize ) {
- // 1) try partition cache ...
+ // 1) try partition cache ...
if ( isset( $this->partitionCache[$table][$batchSize] ) ) {
wfDebug( __METHOD__ . ": got from partition cache\n" );
@@ -340,7 +380,7 @@ class BacklinkCache {
* Partition a DB result with backlinks in it into batches
* @param $res ResultWrapper database result
* @param $batchSize integer
- * @return array @see
+ * @return array @see
*/
protected function partitionResult( $res, $batchSize ) {
$batches = array();
diff --git a/includes/Block.php b/includes/Block.php
index d80edb5e..732699dc 100644
--- a/includes/Block.php
+++ b/includes/Block.php
@@ -28,11 +28,15 @@ class Block {
$mBlockEmail,
$mDisableUsertalk,
- $mCreateAccount;
+ $mCreateAccount,
+ $mParentBlockId;
/// @var User|String
protected $target;
+ // @var Integer Hack for foreign blocking (CentralAuth)
+ protected $forcedTargetID;
+
/// @var Block::TYPE_ constant. Can only be USER, IP or RANGE internally
protected $type;
@@ -72,7 +76,7 @@ class Block {
$this->setTarget( $address );
if ( $this->target instanceof User && $user ) {
- $this->target->setId( $user ); // needed for foreign users
+ $this->forcedTargetID = $user; // needed for foreign users
}
if ( $by ) { // local user
$this->setBlocker( User::newFromID( $by ) );
@@ -122,18 +126,43 @@ class Block {
$dbr = wfGetDB( DB_SLAVE );
$res = $dbr->selectRow(
'ipblocks',
- '*',
+ self::selectFields(),
array( 'ipb_id' => $id ),
__METHOD__
);
if ( $res ) {
- return Block::newFromRow( $res );
+ return self::newFromRow( $res );
} else {
return null;
}
}
/**
+ * Return the list of ipblocks fields that should be selected to create
+ * a new block.
+ * @return array
+ */
+ public static function selectFields() {
+ return array(
+ 'ipb_id',
+ 'ipb_address',
+ 'ipb_by',
+ 'ipb_by_text',
+ 'ipb_reason',
+ 'ipb_timestamp',
+ 'ipb_auto',
+ 'ipb_anon_only',
+ 'ipb_create_account',
+ 'ipb_enable_autoblock',
+ 'ipb_expiry',
+ 'ipb_deleted',
+ 'ipb_block_email',
+ 'ipb_allow_usertalk',
+ 'ipb_parent_block_id',
+ );
+ }
+
+ /**
* Check if two blocks are effectively equal. Doesn't check irrelevant things like
* the blocking user or the block timestamp, only things which affect the blocked user *
*
@@ -243,7 +272,7 @@ class Block {
}
}
- $res = $db->select( 'ipblocks', '*', $conds, __METHOD__ );
+ $res = $db->select( 'ipblocks', self::selectFields(), $conds, __METHOD__ );
# This result could contain a block on the user, a block on the IP, and a russian-doll
# set of rangeblocks. We want to choose the most specific one, so keep a leader board.
@@ -256,7 +285,7 @@ class Block {
$bestBlockPreventsEdit = null;
foreach( $res as $row ){
- $block = Block::newFromRow( $row );
+ $block = self::newFromRow( $row );
# Don't use expired blocks
if( $block->deleteIfExpired() ){
@@ -365,6 +394,7 @@ class Block {
$this->mAuto = $row->ipb_auto;
$this->mHideName = $row->ipb_deleted;
$this->mId = $row->ipb_id;
+ $this->mParentBlockId = $row->ipb_parent_block_id;
// I wish I didn't have to do this
$db = wfGetDB( DB_SLAVE );
@@ -408,6 +438,7 @@ class Block {
}
$dbw = wfGetDB( DB_MASTER );
+ $dbw->delete( 'ipblocks', array( 'ipb_parent_block_id' => $this->getId() ), __METHOD__ );
$dbw->delete( 'ipblocks', array( 'ipb_id' => $this->getId() ), __METHOD__ );
return $dbw->affectedRows() > 0;
@@ -483,9 +514,15 @@ class Block {
}
$expiry = $db->encodeExpiry( $this->mExpiry );
+ if ( $this->forcedTargetID ) {
+ $uid = $this->forcedTargetID;
+ } else {
+ $uid = $this->target instanceof User ? $this->target->getID() : 0;
+ }
+
$a = array(
'ipb_address' => (string)$this->target,
- 'ipb_user' => $this->target instanceof User ? $this->target->getID() : 0,
+ 'ipb_user' => $uid,
'ipb_by' => $this->getBy(),
'ipb_by_text' => $this->getByName(),
'ipb_reason' => $this->mReason,
@@ -499,7 +536,8 @@ class Block {
'ipb_range_end' => $this->getRangeEnd(),
'ipb_deleted' => intval( $this->mHideName ), // typecast required for SQLite
'ipb_block_email' => $this->prevents( 'sendemail' ),
- 'ipb_allow_usertalk' => !$this->prevents( 'editownusertalk' )
+ 'ipb_allow_usertalk' => !$this->prevents( 'editownusertalk' ),
+ 'ipb_parent_block_id' => $this->mParentBlockId
);
return $a;
@@ -575,7 +613,7 @@ class Block {
$key = wfMemcKey( 'ipb', 'autoblock', 'whitelist' );
$lines = $wgMemc->get( $key );
if ( !$lines ) {
- $lines = explode( "\n", wfMsgForContentNoTrans( 'autoblock_whitelist' ) );
+ $lines = explode( "\n", wfMessage( 'autoblock_whitelist' )->inContentLanguage()->plain() );
$wgMemc->set( $key, $lines, 3600 * 24 );
}
@@ -649,7 +687,7 @@ class Block {
wfDebug( "Autoblocking {$this->getTarget()}@" . $autoblockIP . "\n" );
$autoblock->setTarget( $autoblockIP );
$autoblock->setBlocker( $this->getBlocker() );
- $autoblock->mReason = wfMsgForContent( 'autoblocker', $this->getTarget(), $this->mReason );
+ $autoblock->mReason = wfMessage( 'autoblocker', $this->getTarget(), $this->mReason )->inContentLanguage()->text();
$timestamp = wfTimestampNow();
$autoblock->mTimestamp = $timestamp;
$autoblock->mAuto = 1;
@@ -657,6 +695,7 @@ class Block {
# Continue suppressing the name if needed
$autoblock->mHideName = $this->mHideName;
$autoblock->prevents( 'editownusertalk', $this->prevents( 'editownusertalk' ) );
+ $autoblock->mParentBlockId = $this->mId;
if ( $this->mExpiry == 'infinity' ) {
# Original block was indefinite, start an autoblock now
@@ -896,7 +935,7 @@ class Block {
* Encode expiry for DB
*
* @param $expiry String: timestamp for expiry, or
- * @param $db Database object
+ * @param $db DatabaseBase object
* @return String
* @deprecated since 1.18; use $dbw->encodeExpiry() instead
*/
@@ -964,41 +1003,6 @@ class Block {
}
/**
- * Convert a DB-encoded expiry into a real string that humans can read.
- *
- * @param $encoded_expiry String: Database encoded expiry time
- * @return Html-escaped String
- * @deprecated since 1.18; use $wgLang->formatExpiry() instead
- */
- public static function formatExpiry( $encoded_expiry ) {
- wfDeprecated( __METHOD__, '1.18' );
-
- global $wgContLang;
- static $msg = null;
-
- if ( is_null( $msg ) ) {
- $msg = array();
- $keys = array( 'infiniteblock', 'expiringblock' );
-
- foreach ( $keys as $key ) {
- $msg[$key] = wfMsgHtml( $key );
- }
- }
-
- $expiry = $wgContLang->formatExpiry( $encoded_expiry, TS_MW );
- if ( $expiry == wfGetDB( DB_SLAVE )->getInfinity() ) {
- $expirystr = $msg['infiniteblock'];
- } else {
- global $wgLang;
- $expiredatestr = htmlspecialchars( $wgLang->date( $expiry, true ) );
- $expiretimestr = htmlspecialchars( $wgLang->time( $expiry, true ) );
- $expirystr = wfMsgReplaceArgs( $msg['expiringblock'], array( $expiredatestr, $expiretimestr ) );
- }
-
- return $expirystr;
- }
-
- /**
* Convert a submitted expiry time, which may be relative ("2 weeks", etc) or absolute
* ("24 May 2034"), into an absolute timestamp we can put into the database.
* @param $expiry String: whatever was typed into the form
@@ -1066,8 +1070,6 @@ class Block {
* @return array( User|String, Block::TYPE_ constant )
*/
public static function parseTarget( $target ) {
- $target = trim( $target );
-
# We may have been through this before
if( $target instanceof User ){
if( IP::isValid( $target->getName() ) ){
@@ -1079,6 +1081,8 @@ class Block {
return array( null, null );
}
+ $target = trim( $target );
+
if ( IP::isValid( $target ) ) {
# We can still create a User if it's an IP address, but we need to turn
# off validation checking (which would exclude IP addresses)
diff --git a/includes/CacheHelper.php b/includes/CacheHelper.php
new file mode 100644
index 00000000..ac46fc42
--- /dev/null
+++ b/includes/CacheHelper.php
@@ -0,0 +1,392 @@
+<?php
+/**
+ * Cache of various elements in a single cache entry.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ * @file
+ * @licence GNU GPL v2 or later
+ * @author Jeroen De Dauw < jeroendedauw@gmail.com >
+ */
+
+/**
+ * Interface for all classes implementing CacheHelper functionality.
+ *
+ * @since 1.20
+ */
+interface ICacheHelper {
+
+ /**
+ * Sets if the cache should be enabled or not.
+ *
+ * @since 1.20
+ * @param boolean $cacheEnabled
+ */
+ function setCacheEnabled( $cacheEnabled );
+
+ /**
+ * Initializes the caching.
+ * Should be called before the first time anything is added via addCachedHTML.
+ *
+ * @since 1.20
+ *
+ * @param integer|null $cacheExpiry Sets the cache expiry, either ttl in seconds or unix timestamp.
+ * @param boolean|null $cacheEnabled Sets if the cache should be enabled or not.
+ */
+ function startCache( $cacheExpiry = null, $cacheEnabled = null );
+
+ /**
+ * Get a cached value if available or compute it if not and then cache it if possible.
+ * The provided $computeFunction is only called when the computation needs to happen
+ * and should return a result value. $args are arguments that will be passed to the
+ * compute function when called.
+ *
+ * @since 1.20
+ *
+ * @param {function} $computeFunction
+ * @param array|mixed $args
+ * @param string|null $key
+ *
+ * @return mixed
+ */
+ function getCachedValue( $computeFunction, $args = array(), $key = null );
+
+ /**
+ * Saves the HTML to the cache in case it got recomputed.
+ * Should be called after the last time anything is added via addCachedHTML.
+ *
+ * @since 1.20
+ */
+ function saveCache();
+
+ /**
+ * Sets the time to live for the cache, in seconds or a unix timestamp
+ * indicating the point of expiry...
+ *
+ * @since 1.20
+ *
+ * @param integer $cacheExpiry
+ */
+ function setExpiry( $cacheExpiry );
+
+}
+
+/**
+ * Helper class for caching various elements in a single cache entry.
+ *
+ * To get a cached value or compute it, use getCachedValue like this:
+ * $this->getCachedValue( $callback );
+ *
+ * To add HTML that should be cached, use addCachedHTML like this:
+ * $this->addCachedHTML( $callback );
+ *
+ * The callback function is only called when needed, so do all your expensive
+ * computations here. This function should returns the HTML to be cached.
+ * It should not add anything to the PageOutput object!
+ *
+ * Before the first addCachedHTML call, you should call $this->startCache();
+ * After adding the last HTML that should be cached, call $this->saveCache();
+ *
+ * @since 1.20
+ */
+class CacheHelper implements ICacheHelper {
+
+ /**
+ * The time to live for the cache, in seconds or a unix timestamp indicating the point of expiry.
+ *
+ * @since 1.20
+ * @var integer
+ */
+ protected $cacheExpiry = 3600;
+
+ /**
+ * List of HTML chunks to be cached (if !hasCached) or that where cached (of hasCached).
+ * If not cached already, then the newly computed chunks are added here,
+ * if it as cached already, chunks are removed from this list as they are needed.
+ *
+ * @since 1.20
+ * @var array
+ */
+ protected $cachedChunks;
+
+ /**
+ * Indicates if the to be cached content was already cached.
+ * Null if this information is not available yet.
+ *
+ * @since 1.20
+ * @var boolean|null
+ */
+ protected $hasCached = null;
+
+ /**
+ * If the cache is enabled or not.
+ *
+ * @since 1.20
+ * @var boolean
+ */
+ protected $cacheEnabled = true;
+
+ /**
+ * Function that gets called when initialization is done.
+ *
+ * @since 1.20
+ * @var callable
+ */
+ protected $onInitHandler = false;
+
+ /**
+ * Elements to build a cache key with.
+ *
+ * @since 1.20
+ * @var array
+ */
+ protected $cacheKey = array();
+
+ /**
+ * Sets if the cache should be enabled or not.
+ *
+ * @since 1.20
+ * @param boolean $cacheEnabled
+ */
+ public function setCacheEnabled( $cacheEnabled ) {
+ $this->cacheEnabled = $cacheEnabled;
+ }
+
+ /**
+ * Initializes the caching.
+ * Should be called before the first time anything is added via addCachedHTML.
+ *
+ * @since 1.20
+ *
+ * @param integer|null $cacheExpiry Sets the cache expiry, either ttl in seconds or unix timestamp.
+ * @param boolean|null $cacheEnabled Sets if the cache should be enabled or not.
+ */
+ public function startCache( $cacheExpiry = null, $cacheEnabled = null ) {
+ if ( is_null( $this->hasCached ) ) {
+ if ( !is_null( $cacheExpiry ) ) {
+ $this->cacheExpiry = $cacheExpiry;
+ }
+
+ if ( !is_null( $cacheEnabled ) ) {
+ $this->setCacheEnabled( $cacheEnabled );
+ }
+
+ $this->initCaching();
+ }
+ }
+
+ /**
+ * Returns a message that notifies the user he/she is looking at
+ * a cached version of the page, including a refresh link.
+ *
+ * @since 1.20
+ *
+ * @param IContextSource $context
+ * @param boolean $includePurgeLink
+ *
+ * @return string
+ */
+ public function getCachedNotice( IContextSource $context, $includePurgeLink = true ) {
+ if ( $this->cacheExpiry < 86400 * 3650 ) {
+ $message = $context->msg(
+ 'cachedspecial-viewing-cached-ttl',
+ $context->getLanguage()->formatDuration( $this->cacheExpiry )
+ )->escaped();
+ }
+ else {
+ $message = $context->msg(
+ 'cachedspecial-viewing-cached-ts'
+ )->escaped();
+ }
+
+ if ( $includePurgeLink ) {
+ $refreshArgs = $context->getRequest()->getQueryValues();
+ unset( $refreshArgs['title'] );
+ $refreshArgs['action'] = 'purge';
+
+ $subPage = $context->getTitle()->getFullText();
+ $subPage = explode( '/', $subPage, 2 );
+ $subPage = count( $subPage ) > 1 ? $subPage[1] : false;
+
+ $message .= ' ' . Linker::link(
+ $context->getTitle( $subPage ),
+ $context->msg( 'cachedspecial-refresh-now' )->escaped(),
+ array(),
+ $refreshArgs
+ );
+ }
+
+ return $message;
+ }
+
+ /**
+ * Initializes the caching if not already done so.
+ * Should be called before any of the caching functionality is used.
+ *
+ * @since 1.20
+ */
+ protected function initCaching() {
+ if ( $this->cacheEnabled && is_null( $this->hasCached ) ) {
+ $cachedChunks = wfGetCache( CACHE_ANYTHING )->get( $this->getCacheKeyString() );
+
+ $this->hasCached = is_array( $cachedChunks );
+ $this->cachedChunks = $this->hasCached ? $cachedChunks : array();
+
+ if ( $this->onInitHandler !== false ) {
+ call_user_func( $this->onInitHandler, $this->hasCached );
+ }
+ }
+ }
+
+ /**
+ * Get a cached value if available or compute it if not and then cache it if possible.
+ * The provided $computeFunction is only called when the computation needs to happen
+ * and should return a result value. $args are arguments that will be passed to the
+ * compute function when called.
+ *
+ * @since 1.20
+ *
+ * @param {function} $computeFunction
+ * @param array|mixed $args
+ * @param string|null $key
+ *
+ * @return mixed
+ */
+ public function getCachedValue( $computeFunction, $args = array(), $key = null ) {
+ $this->initCaching();
+
+ if ( $this->cacheEnabled && $this->hasCached ) {
+ $value = null;
+
+ if ( is_null( $key ) ) {
+ $itemKey = array_keys( array_slice( $this->cachedChunks, 0, 1 ) );
+ $itemKey = array_shift( $itemKey );
+
+ if ( !is_integer( $itemKey ) ) {
+ wfWarn( "Attempted to get item with non-numeric key while the next item in the queue has a key ($itemKey) in " . __METHOD__ );
+ }
+ elseif ( is_null( $itemKey ) ) {
+ wfWarn( "Attempted to get an item while the queue is empty in " . __METHOD__ );
+ }
+ else {
+ $value = array_shift( $this->cachedChunks );
+ }
+ }
+ else {
+ if ( array_key_exists( $key, $this->cachedChunks ) ) {
+ $value = $this->cachedChunks[$key];
+ unset( $this->cachedChunks[$key] );
+ }
+ else {
+ wfWarn( "There is no item with key '$key' in this->cachedChunks in " . __METHOD__ );
+ }
+ }
+ }
+ else {
+ if ( !is_array( $args ) ) {
+ $args = array( $args );
+ }
+
+ $value = call_user_func_array( $computeFunction, $args );
+
+ if ( $this->cacheEnabled ) {
+ if ( is_null( $key ) ) {
+ $this->cachedChunks[] = $value;
+ }
+ else {
+ $this->cachedChunks[$key] = $value;
+ }
+ }
+ }
+
+ return $value;
+ }
+
+ /**
+ * Saves the HTML to the cache in case it got recomputed.
+ * Should be called after the last time anything is added via addCachedHTML.
+ *
+ * @since 1.20
+ */
+ public function saveCache() {
+ if ( $this->cacheEnabled && $this->hasCached === false && !empty( $this->cachedChunks ) ) {
+ wfGetCache( CACHE_ANYTHING )->set( $this->getCacheKeyString(), $this->cachedChunks, $this->cacheExpiry );
+ }
+ }
+
+ /**
+ * Sets the time to live for the cache, in seconds or a unix timestamp
+ * indicating the point of expiry...
+ *
+ * @since 1.20
+ *
+ * @param integer $cacheExpiry
+ */
+ public function setExpiry( $cacheExpiry ) {
+ $this->cacheExpiry = $cacheExpiry;
+ }
+
+ /**
+ * Returns the cache key to use to cache this page's HTML output.
+ * Is constructed from the special page name and language code.
+ *
+ * @since 1.20
+ *
+ * @return string
+ * @throws MWException
+ */
+ protected function getCacheKeyString() {
+ if ( $this->cacheKey === array() ) {
+ throw new MWException( 'No cache key set, so cannot obtain or save the CacheHelper values.' );
+ }
+
+ return call_user_func_array( 'wfMemcKey', $this->cacheKey );
+ }
+
+ /**
+ * Sets the cache key that should be used.
+ *
+ * @since 1.20
+ *
+ * @param array $cacheKey
+ */
+ public function setCacheKey( array $cacheKey ) {
+ $this->cacheKey = $cacheKey;
+ }
+
+ /**
+ * Rebuild the content, even if it's already cached.
+ * This effectively has the same effect as purging the cache,
+ * since it will be overridden with the new value on the next request.
+ *
+ * @since 1.20
+ */
+ public function rebuildOnDemand() {
+ $this->hasCached = false;
+ }
+
+ /**
+ * Sets a function that gets called when initialization of the cache is done.
+ *
+ * @since 1.20
+ *
+ * @param $handlerFunction
+ */
+ public function setOnInitializedHandler( $handlerFunction ) {
+ $this->onInitHandler = $handlerFunction;
+ }
+
+}
diff --git a/includes/Category.php b/includes/Category.php
index 9d9b5a67..b7b12e8a 100644
--- a/includes/Category.php
+++ b/includes/Category.php
@@ -1,14 +1,33 @@
<?php
/**
+ * Representation for a category.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ * @file
+ * @author Simetrical
+ */
+
+/**
* 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;
@@ -103,7 +122,7 @@ class Category {
* Factory function.
*
* @param $title Title for the category page
- * @return category|false on a totally invalid name
+ * @return Category|bool on a totally invalid name
*/
public static function newFromTitle( $title ) {
$cat = new self();
@@ -185,7 +204,7 @@ class Category {
public function getFileCount() { return $this->getX( 'mFiles' ); }
/**
- * @return Title|false Title for this category, or false on failure.
+ * @return Title|bool Title for this category, or false on failure.
*/
public function getTitle() {
if ( $this->mTitle ) return $this->mTitle;
@@ -231,7 +250,10 @@ class Category {
);
}
- /** Generic accessor */
+ /**
+ * Generic accessor
+ * @return bool
+ */
private function getX( $key ) {
if ( !$this->initialize() ) {
return false;
@@ -257,7 +279,7 @@ class Category {
}
$dbw = wfGetDB( DB_MASTER );
- $dbw->begin();
+ $dbw->begin( __METHOD__ );
# Insert the row if it doesn't exist yet (e.g., this is being run via
# update.php from a pre-1.16 schema). TODO: This will cause lots and
@@ -275,13 +297,13 @@ class Category {
'IGNORE'
);
- $cond1 = $dbw->conditional( 'page_namespace=' . NS_CATEGORY, 1, 'NULL' );
- $cond2 = $dbw->conditional( 'page_namespace=' . NS_FILE, 1, 'NULL' );
+ $cond1 = $dbw->conditional( array( 'page_namespace' => NS_CATEGORY ), 1, 'NULL' );
+ $cond2 = $dbw->conditional( array( 'page_namespace' => NS_FILE ), 1, 'NULL' );
$result = $dbw->selectRow(
array( 'categorylinks', 'page' ),
- array( 'COUNT(*) AS pages',
- "COUNT($cond1) AS subcats",
- "COUNT($cond2) AS files"
+ array( 'pages' => 'COUNT(*)',
+ 'subcats' => "COUNT($cond1)",
+ 'files' => "COUNT($cond2)"
),
array( 'cl_to' => $this->mName, 'page_id = cl_from' ),
__METHOD__,
@@ -297,7 +319,7 @@ class Category {
array( 'cat_title' => $this->mName ),
__METHOD__
);
- $dbw->commit();
+ $dbw->commit( __METHOD__ );
# Now we should update our local counts.
$this->mPages = $result->pages;
diff --git a/includes/CategoryPage.php b/includes/CategoryPage.php
index eab7a356..32e270e8 100644
--- a/includes/CategoryPage.php
+++ b/includes/CategoryPage.php
@@ -1,14 +1,26 @@
<?php
/**
- * Class for viewing MediaWiki category description pages.
+ * Special handling for category description pages.
* Modelled after ImagePage.php.
*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
* @file
*/
-if ( !defined( 'MEDIAWIKI' ) )
- die( 1 );
-
/**
* Special handling for category description pages, showing pages,
* subcategories and file that belong to the category
@@ -29,6 +41,7 @@ class CategoryPage extends Article {
/**
* Constructor from a page id
* @param $id Int article ID to load
+ * @return CategoryPage|null
*/
public static function newFromID( $id ) {
$t = Title::newFromID( $id );
diff --git a/includes/CategoryViewer.php b/includes/CategoryViewer.php
index e8e91423..3bb2bc9b 100644
--- a/includes/CategoryViewer.php
+++ b/includes/CategoryViewer.php
@@ -1,7 +1,24 @@
<?php
-
-if ( !defined( 'MEDIAWIKI' ) )
- die( 1 );
+/**
+ * List and paging of category members.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ * @file
+ */
class CategoryViewer extends ContextSource {
var $limit, $from, $until,
@@ -105,7 +122,7 @@ class CategoryViewer extends ContextSource {
// Give a proper message if category is empty
if ( $r == '' ) {
- $r = wfMsgExt( 'category-empty', array( 'parse' ) );
+ $r = $this->msg( 'category-empty' )->parseAsBlock();
}
$lang = $this->getLanguage();
@@ -172,7 +189,8 @@ class CategoryViewer extends ContextSource {
*
* @param Title $title
* @param string $sortkey The human-readable sortkey (before transforming to icu or whatever).
- */
+ * @return string
+ */
function getSubcategorySortChar( $title, $sortkey ) {
global $wgContLang;
@@ -351,7 +369,7 @@ class CategoryViewer extends ContextSource {
if ( $rescnt > 0 ) {
# Showing subcategories
$r .= "<div id=\"mw-subcategories\">\n";
- $r .= '<h2>' . wfMsg( 'subcategories' ) . "</h2>\n";
+ $r .= '<h2>' . $this->msg( 'subcategories' )->text() . "</h2>\n";
$r .= $countmsg;
$r .= $this->getSectionPagingLinks( 'subcat' );
$r .= $this->formatList( $this->children, $this->children_start_char );
@@ -365,7 +383,7 @@ class CategoryViewer extends ContextSource {
* @return string
*/
function getPagesSection() {
- $ti = htmlspecialchars( $this->title->getText() );
+ $ti = wfEscapeWikiText( $this->title->getText() );
# Don't show articles section if there are none.
$r = '';
@@ -380,7 +398,7 @@ class CategoryViewer extends ContextSource {
if ( $rescnt > 0 ) {
$r = "<div id=\"mw-pages\">\n";
- $r .= '<h2>' . wfMsg( 'category_header', $ti ) . "</h2>\n";
+ $r .= '<h2>' . $this->msg( 'category_header', $ti )->text() . "</h2>\n";
$r .= $countmsg;
$r .= $this->getSectionPagingLinks( 'page' );
$r .= $this->formatList( $this->articles, $this->articles_start_char );
@@ -401,7 +419,7 @@ class CategoryViewer extends ContextSource {
$countmsg = $this->getCountMessage( $rescnt, $dbcnt, 'file' );
$r .= "<div id=\"mw-category-media\">\n";
- $r .= '<h2>' . wfMsg( 'category-media-header', htmlspecialchars( $this->title->getText() ) ) . "</h2>\n";
+ $r .= '<h2>' . $this->msg( 'category-media-header', wfEscapeWikiText( $this->title->getText() ) )->text() . "</h2>\n";
$r .= $countmsg;
$r .= $this->getSectionPagingLinks( 'file' );
if ( $this->showGallery ) {
@@ -486,11 +504,11 @@ class CategoryViewer extends ContextSource {
# Split into three columns
$columns = array_chunk( $columns, ceil( count( $columns ) / 3 ), true /* preserve keys */ );
- $ret = '<table width="100%"><tr valign="top">';
+ $ret = '<table style="width: 100%;"><tr style="vertical-align: top;">';
$prevchar = null;
foreach ( $columns as $column ) {
- $ret .= '<td width="33.3%">';
+ $ret .= '<td style="width: 33.3%;">';
$colContents = array();
# Kind of like array_flip() here, but we keep duplicates in an
@@ -508,7 +526,7 @@ class CategoryViewer extends ContextSource {
if ( $first && $char === $prevchar ) {
# We're continuing a previous chunk at the top of a new
# column, so add " cont." after the letter.
- $ret .= ' ' . wfMsgHtml( 'listingcontinuesabbrev' );
+ $ret .= ' ' . wfMessage( 'listingcontinuesabbrev' )->escaped();
}
$ret .= "</h3>\n";
@@ -558,7 +576,7 @@ class CategoryViewer extends ContextSource {
* @return String HTML
*/
private function pagingLinks( $first, $last, $type = '' ) {
- $prevLink = wfMessage( 'prevn' )->numParams( $this->limit )->escaped();
+ $prevLink = $this->msg( 'prevn' )->numParams( $this->limit )->escaped();
if ( $first != '' ) {
$prevQuery = $this->query;
@@ -572,7 +590,7 @@ class CategoryViewer extends ContextSource {
);
}
- $nextLink = wfMessage( 'nextn' )->numParams( $this->limit )->escaped();
+ $nextLink = $this->msg( 'nextn' )->numParams( $this->limit )->escaped();
if ( $last != '' ) {
$lastQuery = $this->query;
@@ -586,7 +604,7 @@ class CategoryViewer extends ContextSource {
);
}
- return "($prevLink) ($nextLink)";
+ return $this->msg('categoryviewer-pagedlinks')->rawParams($prevLink, $nextLink)->escaped();
}
/**
@@ -670,8 +688,8 @@ class CategoryViewer extends ContextSource {
$this->cat->refreshCounts();
} else {
# Case 3: hopeless. Don't give a total count at all.
- return wfMessage( "category-$type-count-limited" )->numParams( $rescnt )->parseAsBlock();
+ return $this->msg( "category-$type-count-limited" )->numParams( $rescnt )->parseAsBlock();
}
- return wfMessage( "category-$type-count" )->numParams( $rescnt, $totalcnt )->parseAsBlock();
+ return $this->msg( "category-$type-count" )->numParams( $rescnt, $totalcnt )->parseAsBlock();
}
}
diff --git a/includes/Categoryfinder.php b/includes/Categoryfinder.php
index 4a8ed709..e2b6a0ca 100644
--- a/includes/Categoryfinder.php
+++ b/includes/Categoryfinder.php
@@ -1,5 +1,26 @@
<?php
/**
+ * Recent changes filtering by category.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ * @file
+ */
+
+/**
* The "Categoryfinder" class takes a list of articles, creates an internal
* representation of all their parent categories (as well as parents of
* parents etc.). From this representation, it determines which of these
diff --git a/includes/Cdb.php b/includes/Cdb.php
index 94aa1925..ae2e5b18 100644
--- a/includes/Cdb.php
+++ b/includes/Cdb.php
@@ -1,6 +1,21 @@
<?php
/**
- * Native CDB file reader and writer
+ * Native CDB file reader and writer.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * http://www.gnu.org/copyleft/gpl.html
*
* @file
*/
diff --git a/includes/Cdb_PHP.php b/includes/Cdb_PHP.php
index 53175272..02be65f3 100644
--- a/includes/Cdb_PHP.php
+++ b/includes/Cdb_PHP.php
@@ -6,6 +6,21 @@
* * Exception thrown if sizes or offsets are between 2GB and 4GB
* * Some variables renamed
*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
* @file
*/
@@ -51,7 +66,7 @@ class CdbFunctions {
/**
* The CDB hash function.
*
- * @param $s
+ * @param $s string
*
* @return
*/
diff --git a/includes/ChangeTags.php b/includes/ChangeTags.php
index 63d37327..0ebc926f 100644
--- a/includes/ChangeTags.php
+++ b/includes/ChangeTags.php
@@ -1,9 +1,25 @@
<?php
/**
- * Functions related to change tags.
+ * Recent changes tagging.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * http://www.gnu.org/copyleft/gpl.html
*
* @file
*/
+
class ChangeTags {
/**
@@ -19,6 +35,8 @@ class ChangeTags {
*
*/
static function formatSummaryRow( $tags, $page ) {
+ global $wgLang;
+
if( !$tags )
return array( '', array() );
@@ -35,7 +53,7 @@ class ChangeTags {
);
$classes[] = Sanitizer::escapeClass( "mw-tag-$tag" );
}
- $markers = '(' . implode( ', ', $displayTags ) . ')';
+ $markers = wfMessage( 'parentheses' )->rawParams( $wgLang->commaList( $displayTags ) )->text();
$markers = Xml::tags( 'span', array( 'class' => 'mw-tag-markers' ), $markers );
return array( $markers, $classes );
@@ -209,17 +227,17 @@ class ChangeTags {
if ( !$wgUseTagFilter || !count( self::listDefinedTags() ) )
return $fullForm ? '' : array();
- $data = array( Html::rawElement( 'label', array( 'for' => 'tagfilter' ), wfMsgExt( 'tag-filter', 'parseinline' ) ),
- Xml::input( 'tagfilter', 20, $selected ) );
+ $data = array( Html::rawElement( 'label', array( 'for' => 'tagfilter' ), wfMessage( 'tag-filter' )->parse() ),
+ Xml::input( 'tagfilter', 20, $selected, array( 'class' => 'mw-tagfilter-input' ) ) );
if ( !$fullForm ) {
return $data;
}
$html = implode( '&#160;', $data );
- $html .= "\n" . Xml::element( 'input', array( 'type' => 'submit', 'value' => wfMsg( 'tag-filter-submit' ) ) );
+ $html .= "\n" . Xml::element( 'input', array( 'type' => 'submit', 'value' => wfMessage( 'tag-filter-submit' )->text() ) );
$html .= "\n" . Html::hidden( 'title', $title->getPrefixedText() );
- $html = Xml::tags( 'form', array( 'action' => $title->getLocalURL(), 'method' => 'get' ), $html );
+ $html = Xml::tags( 'form', array( 'action' => $title->getLocalURL(), 'class' => 'mw-tagfilter-form', 'method' => 'get' ), $html );
return $html;
}
diff --git a/includes/ChangesFeed.php b/includes/ChangesFeed.php
index bcedf2f3..ee4c2d64 100644
--- a/includes/ChangesFeed.php
+++ b/includes/ChangesFeed.php
@@ -1,4 +1,24 @@
<?php
+/**
+ * Feed for list of changes.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ * @file
+ */
/**
* Feed to Special:RecentChanges and Special:RecentChangesLiked
@@ -51,13 +71,13 @@ class ChangesFeed {
* @param $rows ResultWrapper object with rows in recentchanges table
* @param $lastmod Integer: timestamp of the last item in the recentchanges table (only used for the cache key)
* @param $opts FormOptions as in SpecialRecentChanges::getDefaultOptions()
- * @return null or true
+ * @return null|bool True or null
*/
public function execute( $feed, $rows, $lastmod, $opts ) {
global $wgLang, $wgRenderHashAppend;
if ( !FeedUtils::checkFeedOutput( $this->format ) ) {
- return;
+ return null;
}
$optionsHash = md5( serialize( $opts->getAllValues() ) ) . $wgRenderHashAppend;
@@ -107,7 +127,7 @@ class ChangesFeed {
* @param $lastmod Integer: timestamp of the last item in the recentchanges table
* @param $timekey String: memcached key of the last modification
* @param $key String: memcached key of the content
- * @return feed's content on cache hit or false on cache miss
+ * @return string|bool feed's content on cache hit or false on cache miss
*/
public function loadFromCache( $lastmod, $timekey, $key ) {
global $wgFeedCacheTimeout, $wgOut, $messageMemc;
@@ -186,7 +206,7 @@ class ChangesFeed {
FeedUtils::formatDiff( $obj ),
$url,
$obj->rc_timestamp,
- ($obj->rc_deleted & Revision::DELETED_USER) ? wfMsgHtml('rev-deleted-user') : $obj->rc_user_text,
+ ( $obj->rc_deleted & Revision::DELETED_USER ) ? wfMessage( 'rev-deleted-user' )->escaped() : $obj->rc_user_text,
$talkpage
);
$feed->outItem( $item );
diff --git a/includes/ChangesList.php b/includes/ChangesList.php
index fd97e0cb..84677124 100644
--- a/includes/ChangesList.php
+++ b/includes/ChangesList.php
@@ -1,10 +1,27 @@
<?php
/**
- * Classes to show various lists of changes:
+ * Classes to show lists of changes.
+ *
+ * These can be:
* - watchlist
* - related changes
* - recent changes
*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
* @file
*/
@@ -63,7 +80,7 @@ class ChangesList extends ContextSource {
* This first argument used to be an User object.
*
* @deprecated in 1.18; use newFromContext() instead
- * @param $unused Unused
+ * @param $unused string|User Unused
* @return ChangesList|EnhancedChangesList|OldChangesList derivative
*/
public static function newFromUser( $unused ) {
@@ -91,7 +108,7 @@ class ChangesList extends ContextSource {
}
/**
- * Sets the list to use a <li class="watchlist-(namespace)-(page)"> tag
+ * Sets the list to use a "<li class='watchlist-(namespace)-(page)'>" tag
* @param $value Boolean
*/
public function setWatchlistDivs( $value = true ) {
@@ -106,7 +123,7 @@ class ChangesList extends ContextSource {
if( !isset( $this->message ) ) {
foreach ( explode( ' ', 'cur diff hist last blocklink history ' .
'semicolon-separator pipe-separator' ) as $msg ) {
- $this->message[$msg] = wfMsgExt( $msg, array( 'escapenoentities' ) );
+ $this->message[$msg] = $this->msg( $msg )->escaped();
}
}
}
@@ -128,7 +145,7 @@ class ChangesList extends ContextSource {
}
/**
- * Provide the <abbr> element appropriate to a given abbreviated flag,
+ * Provide the "<abbr>" element appropriate to a given abbreviated flag,
* namely the flag indicating a new page, a minor edit, a bot edit, or an
* unpatrolled edit. By default in English it will contain "N", "m", "b",
* "!" respectively, plus it will have an appropriate title and class.
@@ -146,8 +163,8 @@ class ChangesList extends ContextSource {
'unpatrolled' => array( 'unpatrolledletter', 'recentchanges-label-unpatrolled' ),
);
foreach( $messages as &$value ) {
- $value[0] = wfMsgExt( $value[0], 'escapenoentities' );
- $value[1] = wfMsgExt( $value[1], 'escapenoentities' );
+ $value[0] = wfMessage( $value[0] )->escaped();
+ $value[1] = wfMessage( $value[1] )->escaped();
}
}
@@ -175,6 +192,7 @@ class ChangesList extends ContextSource {
$this->rcCacheIndex = 0;
$this->lastdate = '';
$this->rclistOpen = false;
+ $this->getOutput()->addModuleStyles( 'mediawiki.special.changeslist' );
return '';
}
@@ -182,22 +200,31 @@ class ChangesList extends ContextSource {
* Show formatted char difference
* @param $old Integer: bytes
* @param $new Integer: bytes
+ * @param $context IContextSource context to use
* @return String
*/
- public static function showCharacterDifference( $old, $new ) {
- global $wgRCChangedSizeThreshold, $wgLang, $wgMiserMode;
+ public static function showCharacterDifference( $old, $new, IContextSource $context = null ) {
+ global $wgRCChangedSizeThreshold, $wgMiserMode;
+
+ if ( !$context ) {
+ $context = RequestContext::getMain();
+ }
+
+ $new = (int)$new;
+ $old = (int)$old;
$szdiff = $new - $old;
- $code = $wgLang->getCode();
+ $lang = $context->getLanguage();
+ $code = $lang->getCode();
static $fastCharDiff = array();
if ( !isset($fastCharDiff[$code]) ) {
- $fastCharDiff[$code] = $wgMiserMode || wfMsgNoTrans( 'rc-change-size' ) === '$1';
+ $fastCharDiff[$code] = $wgMiserMode || $context->msg( 'rc-change-size' )->plain() === '$1';
}
- $formattedSize = $wgLang->formatNum($szdiff);
+ $formattedSize = $lang->formatNum( $szdiff );
if ( !$fastCharDiff[$code] ) {
- $formattedSize = wfMsgExt( 'rc-change-size', array( 'parsemag' ), $formattedSize );
+ $formattedSize = $context->msg( 'rc-change-size', $formattedSize )->text();
}
if( abs( $szdiff ) > abs( $wgRCChangedSizeThreshold ) ) {
@@ -217,11 +244,34 @@ class ChangesList extends ContextSource {
$formattedSizeClass = 'mw-plusminus-neg';
}
- $formattedTotalSize = wfMsgExt( 'rc-change-size-new', 'parsemag', $wgLang->formatNum( $new ) );
+ $formattedTotalSize = $context->msg( 'rc-change-size-new' )->numParams( $new )->text();
return Html::element( $tag,
array( 'dir' => 'ltr', 'class' => $formattedSizeClass, 'title' => $formattedTotalSize ),
- wfMessage( 'parentheses', $formattedSize )->plain() ) . $wgLang->getDirMark();
+ $context->msg( 'parentheses', $formattedSize )->plain() ) . $lang->getDirMark();
+ }
+
+ /**
+ * Format the character difference of one or several changes.
+ *
+ * @param $old RecentChange
+ * @param $new RecentChange last change to use, if not provided, $old will be used
+ * @return string HTML fragment
+ */
+ public function formatCharacterDifference( RecentChange $old, RecentChange $new = null ) {
+ $oldlen = $old->mAttribs['rc_old_len'];
+
+ if ( $new ) {
+ $newlen = $new->mAttribs['rc_new_len'];
+ } else {
+ $newlen = $old->mAttribs['rc_new_len'];
+ }
+
+ if( $oldlen === null || $newlen === null ) {
+ return '';
+ }
+
+ return self::showCharacterDifference( $oldlen, $newlen, $this->getContext() );
}
/**
@@ -238,7 +288,7 @@ class ChangesList extends ContextSource {
public function insertDateHeader( &$s, $rc_timestamp ) {
# Make date header if necessary
- $date = $this->getLanguage()->date( $rc_timestamp, true, true );
+ $date = $this->getLanguage()->userDate( $rc_timestamp, $this->getUser() );
if( $date != $this->lastdate ) {
if( $this->lastdate != '' ) {
$s .= "</ul>\n";
@@ -252,7 +302,7 @@ class ChangesList extends ContextSource {
public function insertLog( &$s, $title, $logtype ) {
$page = new LogPage( $logtype );
$logname = $page->getName()->escaped();
- $s .= '(' . Linker::linkKnown( $title, $logname ) . ')';
+ $s .= $this->msg( 'parentheses' )->rawParams( Linker::linkKnown( $title, $logname ) )->escaped();
}
/**
@@ -284,9 +334,9 @@ class ChangesList extends ContextSource {
$query
);
}
- $s .= '(' . $diffLink . $this->message['pipe-separator'];
+ $diffhist = $diffLink . $this->message['pipe-separator'];
# History link
- $s .= Linker::linkKnown(
+ $diffhist .= Linker::linkKnown(
$rc->getTitle(),
$this->message['hist'],
array(),
@@ -295,7 +345,7 @@ class ChangesList extends ContextSource {
'action' => 'history'
)
);
- $s .= ') . . ';
+ $s .= $this->msg( 'parentheses' )->rawParams( $diffhist )->escaped() . ' <span class="mw-changeslist-separator">. .</span> ';
}
/**
@@ -316,16 +366,14 @@ class ChangesList extends ContextSource {
$articlelink = Linker::linkKnown(
$rc->getTitle(),
null,
- array(),
+ array( 'class' => 'mw-changeslist-title' ),
$params
);
if( $this->isDeleted($rc,Revision::DELETED_TEXT) ) {
$articlelink = '<span class="history-deleted">' . $articlelink . '</span>';
}
- # Bolden pages watched by this user
- if( $watched ) {
- $articlelink = "<strong class=\"mw-watched\">{$articlelink}</strong>";
- }
+ # To allow for boldening pages watched by this user
+ $articlelink = "<span class=\"mw-title\">{$articlelink}</span>";
# RTL/LTR marker
$articlelink .= $this->getLanguage()->getDirMark();
@@ -340,8 +388,8 @@ class ChangesList extends ContextSource {
* @param $rc RecentChange
*/
public function insertTimestamp( &$s, $rc ) {
- $s .= $this->message['semicolon-separator'] .
- $this->getLanguage()->time( $rc->mAttribs['rc_timestamp'], true, true ) . ' . . ';
+ $s .= $this->message['semicolon-separator'] . '<span class="mw-changeslist-date">' .
+ $this->getLanguage()->userTime( $rc->mAttribs['rc_timestamp'], $this->getUser() ) . '</span> <span class="mw-changeslist-separator">. .</span> ';
}
/**
@@ -352,7 +400,7 @@ class ChangesList extends ContextSource {
*/
public function insertUserRelatedLinks( &$s, &$rc ) {
if( $this->isDeleted( $rc, Revision::DELETED_USER ) ) {
- $s .= ' <span class="history-deleted">' . wfMsgHtml( 'rev-deleted-user' ) . '</span>';
+ $s .= ' <span class="history-deleted">' . $this->msg( 'rev-deleted-user' )->escaped() . '</span>';
} else {
$s .= $this->getLanguage()->getDirMark() . Linker::userLink( $rc->mAttribs['rc_user'],
$rc->mAttribs['rc_user_text'] );
@@ -364,22 +412,25 @@ class ChangesList extends ContextSource {
* Insert a formatted action
*
* @param $rc RecentChange
+ * @return string
*/
public function insertLogEntry( $rc ) {
$formatter = LogFormatter::newFromRow( $rc->mAttribs );
+ $formatter->setContext( $this->getContext() );
$formatter->setShowUserToolLinks( true );
$mark = $this->getLanguage()->getDirMark();
return $formatter->getActionText() . " $mark" . $formatter->getComment();
}
- /**
+ /**
* Insert a formatted comment
* @param $rc RecentChange
+ * @return string
*/
public function insertComment( $rc ) {
if( $rc->mAttribs['rc_type'] != RC_MOVE && $rc->mAttribs['rc_type'] != RC_MOVE_OVER_REDIRECT ) {
if( $this->isDeleted( $rc, Revision::DELETED_COMMENT ) ) {
- return ' <span class="history-deleted">' . wfMsgHtml( 'rev-deleted-comment' ) . '</span>';
+ return ' <span class="history-deleted">' . $this->msg( 'rev-deleted-comment' )->escaped() . '</span>';
} else {
return Linker::commentBlock( $rc->mAttribs['rc_comment'], $rc->getTitle() );
}
@@ -397,13 +448,13 @@ class ChangesList extends ContextSource {
/**
* Returns the string which indicates the number of watching users
+ * @return string
*/
protected function numberofWatchingusers( $count ) {
static $cache = array();
if( $count > 0 ) {
if( !isset( $cache[$count] ) ) {
- $cache[$count] = wfMsgExt( 'number_of_watching_users_RCview',
- array('parsemag', 'escape' ), $this->getLanguage()->formatNum( $count ) );
+ $cache[$count] = $this->msg( 'number_of_watching_users_RCview' )->numParams( $count )->escaped();
}
return $cache[$count];
} else {
@@ -456,7 +507,7 @@ class ChangesList extends ContextSource {
* @param $rc RecentChange
*/
public function insertRollback( &$s, &$rc ) {
- if( !$rc->mAttribs['rc_new'] && $rc->mAttribs['rc_this_oldid'] && $rc->mAttribs['rc_cur_id'] ) {
+ if( $rc->mAttribs['rc_type'] != RC_NEW && $rc->mAttribs['rc_this_oldid'] && $rc->mAttribs['rc_cur_id'] ) {
$page = $rc->getTitle();
/** Check for rollback and edit permissions, disallow special pages, and only
* show a link on the top-most revision */
@@ -497,7 +548,7 @@ class ChangesList extends ContextSource {
if ( !$rc->mAttribs['rc_patrolled'] ) {
if ( $this->getUser()->useRCPatrol() ) {
$unpatrolled = true;
- } elseif ( $this->getUser()->useNPPatrol() && $rc->mAttribs['rc_new'] ) {
+ } elseif ( $this->getUser()->useNPPatrol() && $rc->mAttribs['rc_type'] == RC_NEW ) {
$unpatrolled = true;
}
}
@@ -513,7 +564,10 @@ class OldChangesList extends ChangesList {
/**
* Format a line using the old system (aka without any javascript).
*
- * @param $rc RecentChange
+ * @param $rc RecentChange, passed by reference
+ * @param $watched Bool (default false)
+ * @param $linenumber Int (default null)
+ * @return string
*/
public function recentChangesLine( &$rc, $watched = false, $linenumber = null ) {
global $wgRCShowChangedSize;
@@ -537,11 +591,15 @@ class OldChangesList extends ChangesList {
}
}
+ // Indicate watched status on the line to allow for more
+ // comprehensive styling.
+ $classes[] = $watched ? 'mw-changeslist-line-watched' : 'mw-changeslist-line-not-watched';
+
// Moved pages (very very old, not supported anymore)
if( $rc->mAttribs['rc_type'] == RC_MOVE || $rc->mAttribs['rc_type'] == RC_MOVE_OVER_REDIRECT ) {
// Log entries
} elseif( $rc->mAttribs['rc_log_type'] ) {
- $logtitle = Title::newFromText( 'Log/'.$rc->mAttribs['rc_log_type'], NS_SPECIAL );
+ $logtitle = SpecialPage::getTitleFor( 'Log', $rc->mAttribs['rc_log_type'] );
$this->insertLog( $s, $logtitle, $rc->mAttribs['rc_log_type'] );
// Log entries (old format) or log targets, and special pages
} elseif( $rc->mAttribs['rc_namespace'] == NS_SPECIAL ) {
@@ -555,7 +613,7 @@ class OldChangesList extends ChangesList {
# M, N, b and ! (minor, new, bot and unpatrolled)
$s .= $this->recentChangesFlags(
array(
- 'newpage' => $rc->mAttribs['rc_new'],
+ 'newpage' => $rc->mAttribs['rc_type'] == RC_NEW,
'minor' => $rc->mAttribs['rc_minor'],
'unpatrolled' => $unpatrolled,
'bot' => $rc->mAttribs['rc_bot']
@@ -567,10 +625,10 @@ class OldChangesList extends ChangesList {
# Edit/log timestamp
$this->insertTimestamp( $s, $rc );
# Bytes added or removed
- if( $wgRCShowChangedSize ) {
- $cd = $rc->getCharacterDifference();
- if( $cd != '' ) {
- $s .= "$cd . . ";
+ if ( $wgRCShowChangedSize ) {
+ $cd = $this->formatCharacterDifference( $rc );
+ if ( $cd !== '' ) {
+ $s .= $cd . ' <span class="mw-changeslist-separator">. .</span> ';
}
}
@@ -593,8 +651,7 @@ class OldChangesList extends ChangesList {
# How many users watch this page
if( $rc->numberofWatchingusers > 0 ) {
- $s .= ' ' . wfMsgExt( 'number_of_watching_users_RCview',
- array( 'parsemag', 'escape' ), $this->getLanguage()->formatNum( $rc->numberofWatchingusers ) );
+ $s .= ' ' . $this->numberofWatchingusers( $rc->numberofWatchingusers );
}
if( $this->watchlist ) {
@@ -646,7 +703,7 @@ class EnhancedChangesList extends ChangesList {
$curIdEq = array( 'curid' => $rc->mAttribs['rc_cur_id'] );
# If it's a new day, add the headline and flush the cache
- $date = $this->getLanguage()->date( $rc->mAttribs['rc_timestamp'], true );
+ $date = $this->getLanguage()->userDate( $rc->mAttribs['rc_timestamp'], $this->getUser() );
$ret = '';
if( $date != $this->lastdate ) {
# Process current cache
@@ -675,7 +732,7 @@ class EnhancedChangesList extends ChangesList {
$logtitle = SpecialPage::getTitleFor( 'Log', $logType );
$logpage = new LogPage( $logType );
$logname = $logpage->getName()->escaped();
- $clink = '(' . Linker::linkKnown( $logtitle, $logname ) . ')';
+ $clink = $this->msg( 'parentheses' )->rawParams( Linker::linkKnown( $logtitle, $logname ) )->escaped();
} else {
$clink = Linker::link( $rc->getTitle() );
}
@@ -694,7 +751,7 @@ class EnhancedChangesList extends ChangesList {
$showdifflinks = false;
}
- $time = $this->getLanguage()->time( $rc->mAttribs['rc_timestamp'], true, true );
+ $time = $this->getLanguage()->userTime( $rc->mAttribs['rc_timestamp'], $this->getUser() );
$rc->watched = $watched;
$rc->link = $clink;
$rc->timestamp = $time;
@@ -743,7 +800,7 @@ class EnhancedChangesList extends ChangesList {
# Make user links
if( $this->isDeleted( $rc, Revision::DELETED_USER ) ) {
- $rc->userlink = ' <span class="history-deleted">' . wfMsgHtml( 'rev-deleted-user' ) . '</span>';
+ $rc->userlink = ' <span class="history-deleted">' . $this->msg( 'rev-deleted-user' )->escaped() . '</span>';
} else {
$rc->userlink = Linker::userLink( $rc->mAttribs['rc_user'], $rc->mAttribs['rc_user_text'] );
$rc->usertalklink = Linker::userToolLinks( $rc->mAttribs['rc_user'], $rc->mAttribs['rc_user_text'] );
@@ -779,6 +836,7 @@ class EnhancedChangesList extends ChangesList {
/**
* Enhanced RC group
+ * @return string
*/
protected function recentChangesBlockGroup( $block ) {
global $wgRCShowChangedSize;
@@ -786,14 +844,16 @@ class EnhancedChangesList extends ChangesList {
wfProfileIn( __METHOD__ );
# Add the namespace and title of the block as part of the class
+ $classes = array( 'mw-collapsible', 'mw-collapsed', 'mw-enhanced-rc' );
if ( $block[0]->mAttribs['rc_log_type'] ) {
# Log entry
- $classes = 'mw-collapsible mw-collapsed mw-enhanced-rc ' . Sanitizer::escapeClass( 'mw-changeslist-log-'
+ $classes[] = Sanitizer::escapeClass( 'mw-changeslist-log-'
. $block[0]->mAttribs['rc_log_type'] . '-' . $block[0]->mAttribs['rc_title'] );
} else {
- $classes = 'mw-collapsible mw-collapsed mw-enhanced-rc ' . Sanitizer::escapeClass( 'mw-changeslist-ns'
+ $classes[] = Sanitizer::escapeClass( 'mw-changeslist-ns'
. $block[0]->mAttribs['rc_namespace'] . '-' . $block[0]->mAttribs['rc_title'] );
}
+ $classes[] = $block[0]->watched ? 'mw-changeslist-line-watched' : 'mw-changeslist-line-not-watched';
$r = Html::openElement( 'table', array( 'class' => $classes ) ) .
Html::openElement( 'tr' );
@@ -808,7 +868,7 @@ class EnhancedChangesList extends ChangesList {
$allLogs = true;
foreach( $block as $rcObj ) {
$oldid = $rcObj->mAttribs['rc_last_oldid'];
- if( $rcObj->mAttribs['rc_new'] ) {
+ if( $rcObj->mAttribs['rc_type'] == RC_NEW ) {
$isnew = true;
}
// If all log actions to this page were hidden, then don't
@@ -847,24 +907,17 @@ class EnhancedChangesList extends ChangesList {
$text = $userlink;
$text .= $this->getLanguage()->getDirMark();
if( $count > 1 ) {
- $text .= ' (' . $this->getLanguage()->formatNum( $count ) . '×)';
+ $text .= ' ' . $this->msg( 'parentheses' )->rawParams( $this->getLanguage()->formatNum( $count ) . '×' )->escaped();
}
array_push( $users, $text );
}
- $users = ' <span class="changedby">[' .
- implode( $this->message['semicolon-separator'], $users ) . ']</span>';
+ $users = ' <span class="changedby">'
+ . $this->msg( 'brackets' )->rawParams(
+ implode( $this->message['semicolon-separator'], $users )
+ )->escaped() . '</span>';
- # Title for <a> tags
- $expandTitle = htmlspecialchars( wfMsg( 'rc-enhanced-expand' ) );
- $closeTitle = htmlspecialchars( wfMsg( 'rc-enhanced-hide' ) );
-
- $tl = "<span class='mw-collapsible-toggle'>"
- . "<span class='mw-rc-openarrow'>"
- . "<a href='#' title='$expandTitle'>{$this->sideArrow()}</a>"
- . "</span><span class='mw-rc-closearrow'>"
- . "<a href='#' title='$closeTitle'>{$this->downArrow()}</a>"
- . "</span></span>";
+ $tl = '<span class="mw-collapsible-toggle mw-enhancedchanges-arrow"></span>';
$r .= "<td>$tl</td>";
# Main line
@@ -880,7 +933,7 @@ class EnhancedChangesList extends ChangesList {
# Article link
if( $namehidden ) {
- $r .= ' <span class="history-deleted">' . wfMsgHtml( 'rev-deleted-event' ) . '</span>';
+ $r .= ' <span class="history-deleted">' . $this->msg( 'rev-deleted-event' )->escaped() . '</span>';
} elseif( $allLogs ) {
$r .= $this->maybeWatchedLink( $block[0]->link, $block[0]->watched );
} else {
@@ -894,22 +947,22 @@ class EnhancedChangesList extends ChangesList {
$n = count($block);
static $nchanges = array();
if ( !isset( $nchanges[$n] ) ) {
- $nchanges[$n] = wfMsgExt( 'nchanges', array( 'parsemag', 'escape' ), $this->getLanguage()->formatNum( $n ) );
+ $nchanges[$n] = $this->msg( 'nchanges' )->numParams( $n )->escaped();
}
# Total change link
$r .= ' ';
+ $logtext = '';
if( !$allLogs ) {
- $r .= '(';
if( !ChangesList::userCan( $rcObj, Revision::DELETED_TEXT, $this->getUser() ) ) {
- $r .= $nchanges[$n];
+ $logtext .= $nchanges[$n];
} elseif( $isnew ) {
- $r .= $nchanges[$n];
+ $logtext .= $nchanges[$n];
} else {
$params = $queryParams;
$params['diff'] = $currentRevision;
$params['oldid'] = $oldid;
- $r .= Linker::link(
+ $logtext .= Linker::link(
$block[0]->getTitle(),
$nchanges[$n],
array(),
@@ -923,20 +976,25 @@ class EnhancedChangesList extends ChangesList {
if( $allLogs ) {
// don't show history link for logs
} elseif( $namehidden || !$block[0]->getTitle()->exists() ) {
- $r .= $this->message['pipe-separator'] . $this->message['hist'] . ')';
+ $logtext .= $this->message['pipe-separator'] . $this->message['hist'];
} else {
$params = $queryParams;
$params['action'] = 'history';
- $r .= $this->message['pipe-separator'] .
+ $logtext .= $this->message['pipe-separator'] .
Linker::linkKnown(
$block[0]->getTitle(),
$this->message['hist'],
array(),
$params
- ) . ')';
+ );
}
- $r .= ' . . ';
+
+ if( $logtext !== '' ) {
+ $r .= $this->msg( 'parentheses' )->rawParams( $logtext )->escaped();
+ }
+
+ $r .= ' <span class="mw-changeslist-separator">. .</span> ';
# Character difference (does not apply if only log items)
if( $wgRCShowChangedSize && !$allLogs ) {
@@ -950,13 +1008,12 @@ class EnhancedChangesList extends ChangesList {
$first--;
}
# Get net change
- $chardiff = $rcObj->getCharacterDifference( $block[$first]->mAttribs['rc_old_len'],
- $block[$last]->mAttribs['rc_new_len'] );
+ $chardiff = $this->formatCharacterDifference( $block[$first], $block[$last] );
if( $chardiff == '' ) {
$r .= ' ';
} else {
- $r .= ' ' . $chardiff. ' . . ';
+ $r .= ' ' . $chardiff. ' <span class="mw-changeslist-separator">. .</span> ';
}
}
@@ -969,10 +1026,9 @@ class EnhancedChangesList extends ChangesList {
$classes = array();
$type = $rcObj->mAttribs['rc_type'];
- #$r .= '<tr><td valign="top">'.$this->spacerArrow();
$r .= '<tr><td></td><td class="mw-enhanced-rc">';
$r .= $this->recentChangesFlags( array(
- 'newpage' => $rcObj->mAttribs['rc_new'],
+ 'newpage' => $type == RC_NEW,
'minor' => $rcObj->mAttribs['rc_minor'],
'unpatrolled' => $rcObj->unpatrolled,
'bot' => $rcObj->mAttribs['rc_bot'],
@@ -1008,17 +1064,16 @@ class EnhancedChangesList extends ChangesList {
$r .= $link . '</span>';
if ( !$type == RC_LOG || $type == RC_NEW ) {
- $r .= ' (';
- $r .= $rcObj->curlink;
- $r .= $this->message['pipe-separator'];
- $r .= $rcObj->lastlink;
- $r .= ')';
+ $r .= ' ' . $this->msg( 'parentheses' )->rawParams( $rcObj->curlink . $this->message['pipe-separator'] . $rcObj->lastlink )->escaped();
}
- $r .= ' . . ';
+ $r .= ' <span class="mw-changeslist-separator">. .</span> ';
# Character diff
- if( $wgRCShowChangedSize && $rcObj->getCharacterDifference() ) {
- $r .= $rcObj->getCharacterDifference() . ' . . ' ;
+ if ( $wgRCShowChangedSize ) {
+ $cd = $this->formatCharacterDifference( $rcObj );
+ if ( $cd !== '' ) {
+ $r .= $cd . ' <span class="mw-changeslist-separator">. .</span> ';
+ }
}
if ( $rcObj->mAttribs['rc_type'] == RC_LOG ) {
@@ -1051,7 +1106,7 @@ class EnhancedChangesList extends ChangesList {
* @param $dir String: one of '', 'd', 'l', 'r'
* @param $alt String: text
* @param $title String: text
- * @return String: HTML <img> tag
+ * @return String: HTML "<img>" tag
*/
protected function arrow( $dir, $alt='', $title='' ) {
global $wgStylePath;
@@ -1064,26 +1119,25 @@ class EnhancedChangesList extends ChangesList {
/**
* Generate HTML for a right- or left-facing arrow,
* depending on language direction.
- * @return String: HTML <img> tag
+ * @return String: HTML "<img>" tag
*/
protected function sideArrow() {
- global $wgLang;
- $dir = $wgLang->isRTL() ? 'l' : 'r';
- return $this->arrow( $dir, '+', wfMsg( 'rc-enhanced-expand' ) );
+ $dir = $this->getLanguage()->isRTL() ? 'l' : 'r';
+ return $this->arrow( $dir, '+', $this->msg( 'rc-enhanced-expand' )->text() );
}
/**
* Generate HTML for a down-facing arrow
* depending on language direction.
- * @return String: HTML <img> tag
+ * @return String: HTML "<img>" tag
*/
protected function downArrow() {
- return $this->arrow( 'd', '-', wfMsg( 'rc-enhanced-hide' ) );
+ return $this->arrow( 'd', '-', $this->msg( 'rc-enhanced-hide' )->text() );
}
/**
* Generate HTML for a spacer image
- * @return String: HTML <img> tag
+ * @return String: HTML "<img>" tag
*/
protected function spacerArrow() {
return $this->arrow( '', codepointToUtf8( 0xa0 ) ); // non-breaking space
@@ -1103,18 +1157,20 @@ class EnhancedChangesList extends ChangesList {
$type = $rcObj->mAttribs['rc_type'];
$logType = $rcObj->mAttribs['rc_log_type'];
+ $classes = array( 'mw-enhanced-rc' );
if( $logType ) {
# Log entry
- $classes = 'mw-enhanced-rc ' . Sanitizer::escapeClass( 'mw-changeslist-log-'
+ $classes[] = Sanitizer::escapeClass( 'mw-changeslist-log-'
. $logType . '-' . $rcObj->mAttribs['rc_title'] );
} else {
- $classes = 'mw-enhanced-rc ' . Sanitizer::escapeClass( 'mw-changeslist-ns' .
+ $classes[] = Sanitizer::escapeClass( 'mw-changeslist-ns' .
$rcObj->mAttribs['rc_namespace'] . '-' . $rcObj->mAttribs['rc_title'] );
}
+ $classes[] = $rcObj->watched ? 'mw-changeslist-line-watched' : 'mw-changeslist-line-not-watched';
$r = Html::openElement( 'table', array( 'class' => $classes ) ) .
Html::openElement( 'tr' );
- $r .= '<td class="mw-enhanced-rc">' . $this->spacerArrow();
+ $r .= '<td class="mw-enhanced-rc"><span class="mw-enhancedchanges-arrow mw-enhancedchanges-arrow-space"></span>';
# Flag and Timestamp
if( $type == RC_MOVE || $type == RC_MOVE_OVER_REDIRECT ) {
$r .= '&#160;&#160;&#160;&#160;'; // 4 flags -> 4 spaces
@@ -1129,39 +1185,41 @@ class EnhancedChangesList extends ChangesList {
$r .= '&#160;'.$rcObj->timestamp.'&#160;</td><td>';
# Article or log link
if( $logType ) {
- $logtitle = SpecialPage::getTitleFor( 'Log', $logType );
- $logname = LogPage::logName( $logType );
- $r .= '(' . Linker::linkKnown( $logtitle, htmlspecialchars( $logname ) ) . ')';
+ $logPage = new LogPage( $logType );
+ $logTitle = SpecialPage::getTitleFor( 'Log', $logType );
+ $logName = $logPage->getName()->escaped();
+ $r .= $this->msg( 'parentheses' )->rawParams( Linker::linkKnown( $logTitle, $logName ) )->escaped();
} else {
$this->insertArticleLink( $r, $rcObj, $rcObj->unpatrolled, $rcObj->watched );
}
# Diff and hist links
if ( $type != RC_LOG ) {
- $r .= ' ('. $rcObj->difflink . $this->message['pipe-separator'];
$query['action'] = 'history';
- $r .= Linker::linkKnown(
+ $r .= ' ' . $this->msg( 'parentheses' )->rawParams( $rcObj->difflink . $this->message['pipe-separator'] . Linker::linkKnown(
$rcObj->getTitle(),
$this->message['hist'],
array(),
$query
- ) . ')';
+ ) )->escaped();
}
- $r .= ' . . ';
+ $r .= ' <span class="mw-changeslist-separator">. .</span> ';
# Character diff
- if( $wgRCShowChangedSize && ($cd = $rcObj->getCharacterDifference()) ) {
- $r .= "$cd . . ";
+ if ( $wgRCShowChangedSize ) {
+ $cd = $this->formatCharacterDifference( $rcObj );
+ if ( $cd !== '' ) {
+ $r .= $cd . ' <span class="mw-changeslist-separator">. .</span> ';
+ }
}
if ( $type == RC_LOG ) {
$r .= $this->insertLogEntry( $rcObj );
- } else {
+ } else {
$r .= ' '.$rcObj->userlink . $rcObj->usertalklink;
$r .= $this->insertComment( $rcObj );
- $r .= $this->insertRollback( $r, $rcObj );
+ $this->insertRollback( $r, $rcObj );
}
# Tags
- $classes = explode( ' ', $classes );
$this->insertTags( $r, $rcObj, $classes );
# Show how many people are watching this if enabled
$r .= $this->numberofWatchingusers($rcObj->numberofWatchingusers);
diff --git a/includes/Collation.php b/includes/Collation.php
index 0c510b78..ad2b94b1 100644
--- a/includes/Collation.php
+++ b/includes/Collation.php
@@ -1,4 +1,24 @@
<?php
+/**
+ * Database row sorting.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ * @file
+ */
abstract class Collation {
static $instance;
@@ -311,7 +331,7 @@ class IcuCollation extends Collation {
* -1, 0 or 1 in the style of strcmp().
* @param $target string The target value to find.
*
- * @return The item index of the lower bound, or false if the target value
+ * @return int|bool The item index of the lower bound, or false if the target value
* sorts before all items.
*/
function findLowerBound( $valueCallback, $valueCount, $comparisonCallback, $target ) {
diff --git a/includes/ConfEditor.php b/includes/ConfEditor.php
index 42a7173d..b68fc762 100644
--- a/includes/ConfEditor.php
+++ b/includes/ConfEditor.php
@@ -1,4 +1,24 @@
<?php
+/**
+ * Configuration file editor.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ * @file
+ */
/**
* This is a state machine style parser with two internal stacks:
@@ -139,6 +159,7 @@ class ConfEditor {
* insert
* Insert a new element at the start of the array.
*
+ * @return string
*/
public function edit( $ops ) {
$this->parse();
@@ -371,6 +392,7 @@ class ConfEditor {
* Finds the source byte region which you would want to delete, if $pathName
* was to be deleted. Includes the leading spaces and tabs, the trailing line
* break, and any comments in between.
+ * @return array
*/
function findDeletionRegion( $pathName ) {
if ( !isset( $this->pathInfo[$pathName] ) ) {
@@ -428,6 +450,7 @@ class ConfEditor {
* or semicolon.
*
* The end position is the past-the-end (end + 1) value as per convention.
+ * @return array
*/
function findValueRegion( $pathName ) {
if ( !isset( $this->pathInfo[$pathName] ) ) {
@@ -444,6 +467,7 @@ class ConfEditor {
* Find the path name of the last element in the array.
* If the array is empty, this will return the \@extra interstitial element.
* If the specified path is not found or is not an array, it will return false.
+ * @return bool|int|string
*/
function findLastArrayElement( $path ) {
// Try for a real element
@@ -480,6 +504,7 @@ class ConfEditor {
* Find the path name of first element in the array.
* If the array is empty, this will return the \@extra interstitial element.
* If the specified path is not found or is not an array, it will return false.
+ * @return bool|int|string
*/
function findFirstArrayElement( $path ) {
// Try for an ordinary element
@@ -504,6 +529,7 @@ class ConfEditor {
/**
* Get the indent string which sits after a given start position.
* Returns false if the position is not at the start of the line.
+ * @return array
*/
function getIndent( $pos, $key = false, $arrowPos = false ) {
$arrowIndent = ' ';
@@ -725,6 +751,7 @@ class ConfEditor {
/**
* Create a ConfEditorToken from an element of token_get_all()
+ * @return ConfEditorToken
*/
function newTokenObj( $internalToken ) {
if ( is_array( $internalToken ) ) {
@@ -776,6 +803,7 @@ class ConfEditor {
/**
* Get the token $offset steps ahead of the current position.
* $offset may be negative, to get tokens behind the current position.
+ * @return ConfEditorToken
*/
function getTokenAhead( $offset ) {
$pos = $this->pos + $offset;
@@ -821,6 +849,7 @@ class ConfEditor {
/**
* Pop a state from the state stack.
+ * @return mixed
*/
function popState() {
return array_pop( $this->stateStack );
@@ -829,6 +858,7 @@ class ConfEditor {
/**
* Returns true if the user input path is valid.
* This exists to allow "/" and "@" to be reserved for string path keys
+ * @return bool
*/
function validatePath( $path ) {
return strpos( $path, '/' ) === false && substr( $path, 0, 1 ) != '@';
@@ -949,6 +979,7 @@ class ConfEditor {
/**
* Get a readable name for the given token type.
+ * @return string
*/
function getTypeName( $type ) {
if ( is_int( $type ) ) {
@@ -962,6 +993,7 @@ class ConfEditor {
* Looks ahead to see if the given type is the next token type, starting
* from the current position plus the given offset. Skips any intervening
* whitespace.
+ * @return bool
*/
function isAhead( $type, $offset = 0 ) {
$ahead = $offset;
diff --git a/includes/Cookie.php b/includes/Cookie.php
index 76739ccc..7984d63e 100644
--- a/includes/Cookie.php
+++ b/includes/Cookie.php
@@ -1,6 +1,24 @@
<?php
/**
- * @defgroup HTTP HTTP
+ * Cookie for HTTP requests.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ * @file
+ * @ingroup HTTP
*/
class Cookie {
@@ -62,8 +80,8 @@ class Cookie {
* A better method might be to use a blacklist like
* http://publicsuffix.org/
*
- * @fixme fails to detect 3-letter top-level domains
- * @fixme fails to detect 2-letter top-level domains for single-domain use (probably not a big problem in practice, but there are test cases)
+ * @todo fixme fails to detect 3-letter top-level domains
+ * @todo fixme fails to detect 2-letter top-level domains for single-domain use (probably not a big problem in practice, but there are test cases)
*
* @param $domain String: the domain to validate
* @param $originDomain String: (optional) the domain the cookie originates from
@@ -193,6 +211,7 @@ class CookieJar {
/**
* @see Cookie::serializeToHttpRequest
+ * @return string
*/
public function serializeToHttpRequest( $path, $domain ) {
$cookies = array();
@@ -213,6 +232,7 @@ class CookieJar {
*
* @param $cookie String
* @param $domain String: cookie's domain
+ * @return null
*/
public function parseCookieResponseHeader ( $cookie, $domain ) {
$len = strlen( 'Set-Cookie:' );
diff --git a/includes/CryptRand.php b/includes/CryptRand.php
index e4be1b37..858eebf2 100644
--- a/includes/CryptRand.php
+++ b/includes/CryptRand.php
@@ -5,6 +5,21 @@
* This is based in part on Drupal code as well as what we used in our own code
* prior to introduction of this class.
*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
* @author Daniel Friesen
* @file
*/
@@ -54,7 +69,7 @@ class MWCryptRand {
// It'll also vary slightly across different machines
$state = serialize( $_SERVER );
- // To try and vary the system information of the state a bit more
+ // To try vary the system information of the state a bit more
// by including the system's hostname into the state
$state .= wfHostname();
@@ -63,13 +78,22 @@ class MWCryptRand {
// Include some information about the filesystem's current state in the random state
$files = array();
+
// We know this file is here so grab some info about ourself
$files[] = __FILE__;
+
+ // We must also have a parent folder, and with the usual file structure, a grandparent
+ $files[] = __DIR__;
+ $files[] = dirname( __DIR__ );
+
// The config file is likely the most often edited file we know should be around
- // so if the constant with it's location is defined include it's stat info into the state
+ // so include its stat info into the state.
+ // The constant with its location will almost always be defined, as WebStart.php defines
+ // MW_CONFIG_FILE to $IP/LocalSettings.php unless being configured with MW_CONFIG_CALLBACK (eg. the installer)
if ( defined( 'MW_CONFIG_FILE' ) ) {
$files[] = MW_CONFIG_FILE;
}
+
foreach ( $files as $file ) {
wfSuppressWarnings();
$stat = stat( $file );
@@ -275,7 +299,7 @@ class MWCryptRand {
if ( strlen( $buffer ) < $bytes ) {
// If available make use of mcrypt_create_iv URANDOM source to generate randomness
// On unix-like systems this reads from /dev/urandom but does it without any buffering
- // and bypasses openbasdir restrictions so it's preferable to reading directly
+ // and bypasses openbasedir restrictions, so it's preferable to reading directly
// On Windows starting in PHP 5.3.0 Windows' native CryptGenRandom is used to generate
// entropy so this is also preferable to just trying to read urandom because it may work
// on Windows systems as well.
@@ -294,9 +318,10 @@ class MWCryptRand {
}
if ( strlen( $buffer ) < $bytes ) {
- // If available make use of openssl's random_pesudo_bytes method to attempt to generate randomness.
+ // If available make use of openssl's random_pseudo_bytes method to attempt to generate randomness.
// However don't do this on Windows with PHP < 5.3.4 due to a bug:
// http://stackoverflow.com/questions/1940168/openssl-random-pseudo-bytes-is-slow-php
+ // http://git.php.net/?p=php-src.git;a=commitdiff;h=cd62a70863c261b07f6dadedad9464f7e213cad5
if ( function_exists( 'openssl_random_pseudo_bytes' )
&& ( !wfIsWindows() || version_compare( PHP_VERSION, '5.3.4', '>=' ) )
) {
diff --git a/includes/DataUpdate.php b/includes/DataUpdate.php
new file mode 100644
index 00000000..377b64c0
--- /dev/null
+++ b/includes/DataUpdate.php
@@ -0,0 +1,124 @@
+<?php
+/**
+ * Base code for update jobs that do something with some secondary
+ * data extracted from article.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ * @file
+ */
+
+/**
+ * Abstract base class for update jobs that do something with some secondary
+ * data extracted from article.
+ *
+ * @note: subclasses should NOT start or commit transactions in their doUpdate() method,
+ * a transaction will automatically be wrapped around the update. If need be,
+ * subclasses can override the beginTransaction() and commitTransaction() methods.
+ */
+abstract class DataUpdate implements DeferrableUpdate {
+
+ /**
+ * Constructor
+ */
+ public function __construct( ) {
+ # noop
+ }
+
+ /**
+ * Begin an appropriate transaction, if any.
+ * This default implementation does nothing.
+ */
+ public function beginTransaction() {
+ //noop
+ }
+
+ /**
+ * Commit the transaction started via beginTransaction, if any.
+ * This default implementation does nothing.
+ */
+ public function commitTransaction() {
+ //noop
+ }
+
+ /**
+ * Abort / roll back the transaction started via beginTransaction, if any.
+ * This default implementation does nothing.
+ */
+ public function rollbackTransaction() {
+ //noop
+ }
+
+ /**
+ * Convenience method, calls doUpdate() on every DataUpdate in the array.
+ *
+ * This methods supports transactions logic by first calling beginTransaction()
+ * on all updates in the array, then calling doUpdate() on each, and, if all goes well,
+ * then calling commitTransaction() on each update. If an error occurrs,
+ * rollbackTransaction() will be called on any update object that had beginTranscation()
+ * called but not yet commitTransaction().
+ *
+ * This allows for limited transactional logic across multiple backends for storing
+ * secondary data.
+ *
+ * @static
+ * @param $updates array a list of DataUpdate instances
+ */
+ public static function runUpdates( $updates ) {
+ if ( empty( $updates ) ) return; # nothing to do
+
+ $open_transactions = array();
+ $exception = null;
+
+ /**
+ * @var $update DataUpdate
+ * @var $trans DataUpdate
+ */
+
+ try {
+ // begin transactions
+ foreach ( $updates as $update ) {
+ $update->beginTransaction();
+ $open_transactions[] = $update;
+ }
+
+ // do work
+ foreach ( $updates as $update ) {
+ $update->doUpdate();
+ }
+
+ // commit transactions
+ while ( count( $open_transactions ) > 0 ) {
+ $trans = array_pop( $open_transactions );
+ $trans->commitTransaction();
+ }
+ } catch ( Exception $ex ) {
+ $exception = $ex;
+ wfDebug( "Caught exception, will rethrow after rollback: " . $ex->getMessage() );
+ }
+
+ // rollback remaining transactions
+ while ( count( $open_transactions ) > 0 ) {
+ $trans = array_pop( $open_transactions );
+ $trans->rollbackTransaction();
+ }
+
+ if ( $exception ) {
+ throw $exception; // rethrow after cleanup
+ }
+ }
+
+}
diff --git a/includes/DefaultSettings.php b/includes/DefaultSettings.php
index ef1ef402..8216beb8 100644
--- a/includes/DefaultSettings.php
+++ b/includes/DefaultSettings.php
@@ -1,6 +1,7 @@
<?php
/**
- * @file
+ * Default values for MediaWiki configuration settings.
+ *
*
* NEVER EDIT THIS FILE
*
@@ -15,25 +16,50 @@
*
* Documentation is in the source and on:
* http://www.mediawiki.org/wiki/Manual:Configuration_settings
+ *
+ * @warning Note: this (and other things) will break if the autoloader is not
+ * enabled. Please include includes/AutoLoader.php before including this file.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ * @file
+ */
+
+/**
+ * @defgroup Globalsettings Global settings
*/
/**
* @cond file_level_code
- * This is not a valid entry point, perform no further processing unless MEDIAWIKI is defined
+ * This is not a valid entry point, perform no further processing unless
+ * MEDIAWIKI is defined
*/
if( !defined( 'MEDIAWIKI' ) ) {
echo "This file is part of MediaWiki and is not a valid entry point\n";
die( 1 );
}
-# Create a site configuration object. Not used for much in a default install.
-# Note: this (and other things) will break if the autoloader is not enabled.
-# Please include includes/AutoLoader.php before including this file.
+/**
+ * wgConf hold the site configuration.
+ * Not used for much in a default install.
+ */
$wgConf = new SiteConfiguration;
-/** @endcond */
/** MediaWiki version number */
-$wgVersion = '1.19.3';
+$wgVersion = '1.20.2';
/** Name of the site. It must be changed in LocalSettings.php */
$wgSitename = 'MediaWiki';
@@ -41,10 +67,10 @@ $wgSitename = 'MediaWiki';
/**
* URL of the server.
*
- * Example:
- * <code>
+ * @par Example:
+ * @code
* $wgServer = 'http://example.com';
- * </code>
+ * @endcode
*
* This is usually detected correctly by MediaWiki. If MediaWiki detects the
* wrong server, it will redirect incorrectly after you save a page. In that
@@ -110,28 +136,6 @@ $wgUsePathInfo =
*/
$wgScriptExtension = '.php';
-/**
- * The URL path to index.php.
- *
- * Will default to "{$wgScriptPath}/index{$wgScriptExtension}" in Setup.php
- */
-$wgScript = false;
-
-/**
- * The URL path to redirect.php. This is a script that is used by the Nostalgia
- * skin.
- *
- * Will default to "{$wgScriptPath}/redirect{$wgScriptExtension}" in Setup.php
- */
-$wgRedirectScript = false;
-
-/**
- * The URL path to load.php.
- *
- * Defaults to "{$wgScriptPath}/load{$wgScriptExtension}".
- */
-$wgLoadScript = false;
-
/**@}*/
@@ -154,7 +158,30 @@ $wgLoadScript = false;
*/
/**
- * The URL path of the skins directory. Will default to "{$wgScriptPath}/skins" in Setup.php
+ * The URL path to index.php.
+ *
+ * Defaults to "{$wgScriptPath}/index{$wgScriptExtension}".
+ */
+$wgScript = false;
+
+/**
+ * The URL path to redirect.php. This is a script that is used by the Nostalgia
+ * skin.
+ *
+ * Defaults to "{$wgScriptPath}/redirect{$wgScriptExtension}".
+ */
+$wgRedirectScript = false;
+
+/**
+ * The URL path to load.php.
+ *
+ * Defaults to "{$wgScriptPath}/load{$wgScriptExtension}".
+ */
+$wgLoadScript = false;
+
+/**
+ * The URL path of the skins directory.
+ * Defaults to "{$wgScriptPath}/skins".
*/
$wgStylePath = false;
$wgStyleSheetPath = &$wgStylePath;
@@ -173,7 +200,8 @@ $wgLocalStylePath = false;
$wgExtensionAssetsPath = false;
/**
- * Filesystem stylesheets directory. Will default to "{$IP}/skins" in Setup.php
+ * Filesystem stylesheets directory.
+ * Defaults to "{$IP}/skins".
*/
$wgStyleDirectory = false;
@@ -181,29 +209,31 @@ $wgStyleDirectory = false;
* The URL path for primary article page views. This path should contain $1,
* which is replaced by the article title.
*
- * Will default to "{$wgScript}/$1" or "{$wgScript}?title=$1" in Setup.php,
+ * Defaults to "{$wgScript}/$1" or "{$wgScript}?title=$1",
* depending on $wgUsePathInfo.
*/
$wgArticlePath = false;
/**
- * The URL path for the images directory. Will default to "{$wgScriptPath}/images" in Setup.php
+ * The URL path for the images directory.
+ * Defaults to "{$wgScriptPath}/images".
*/
$wgUploadPath = false;
/**
- * The maximum age of temporary (incomplete) uploaded files
+ * The filesystem path of the images directory. Defaults to "{$IP}/images".
*/
-$wgUploadStashMaxAge = 6 * 3600; // 6 hours
+$wgUploadDirectory = false;
/**
- * The filesystem path of the images directory. Defaults to "{$IP}/images".
+ * Directory where the cached page will be saved.
+ * Defaults to "{$wgUploadDirectory}/cache".
*/
-$wgUploadDirectory = false;
+$wgFileCacheDirectory = false;
/**
* The URL path of the wiki logo. The logo size should be 135x135 pixels.
- * Will default to "{$wgStylePath}/common/images/wiki.png" in Setup.php
+ * Defaults to "{$wgStylePath}/common/images/wiki.png".
*/
$wgLogo = false;
@@ -222,7 +252,16 @@ $wgAppleTouchIcon = false;
* The local filesystem path to a temporary directory. This is not required to
* be web accessible.
*
- * Will default to "{$wgUploadDirectory}/tmp" in Setup.php
+ * When this setting is set to false, its value will be set through a call
+ * to wfTempDir(). See that methods implementation for the actual detection
+ * logic.
+ *
+ * Developers should use the global function wfTempDir() instead of this
+ * variable.
+ *
+ * @see wfTempDir()
+ * @note Default changed to false in MediaWiki 1.20.
+ *
*/
$wgTmpDirectory = false;
@@ -242,11 +281,16 @@ $wgUploadStashScalerBaseUrl = false;
/**
* To set 'pretty' URL paths for actions other than
- * plain page views, add to this array. For instance:
+ * plain page views, add to this array.
+ *
+ * @par Example:
+ * Set pretty URL for the edit action:
+ * @code
* 'edit' => "$wgScriptPath/edit/$1"
+ * @endcode
*
- * There must be an appropriate script or rewrite rule
- * in place to handle these URLs.
+ * There must be an appropriate script or rewrite rule in place to handle these
+ * URLs.
*/
$wgActionPaths = array();
@@ -260,11 +304,16 @@ $wgActionPaths = array();
/** Uploads have to be specially set up to be secure */
$wgEnableUploads = false;
+/**
+ * The maximum age of temporary (incomplete) uploaded files
+ */
+$wgUploadStashMaxAge = 6 * 3600; // 6 hours
+
/** Allows to move images and other media files */
$wgAllowImageMoving = true;
/**
- * These are additional characters that should be replaced with '-' in file names
+ * These are additional characters that should be replaced with '-' in filenames
*/
$wgIllegalFileChars = ":";
@@ -274,9 +323,10 @@ $wgIllegalFileChars = ":";
$wgFileStore = array();
/**
- * What directory to place deleted uploads in
+ * What directory to place deleted uploads in.
+ * Defaults to "{$wgUploadDirectory}/deleted".
*/
-$wgDeletedDirectory = false; // Defaults to $wgUploadDirectory/deleted
+$wgDeletedDirectory = false;
/**
* Set this to true if you use img_auth and want the user to see details on why access failed.
@@ -308,11 +358,15 @@ $wgImgAuthPublicTest = true;
*
* For most core repos:
* - zones Associative array of zone names that each map to an array with:
- * container : backend container name the zone is in
- * directory : root path within container for the zone
- * Zones default to using <repo name>-<zone> as the
- * container name and the container root as the zone directory.
- * - url Base public URL
+ * container : backend container name the zone is in
+ * directory : root path within container for the zone
+ * url : base URL to the root of the zone
+ * handlerUrl : base script handled URL to the root of the zone
+ * (see FileRepo::getZoneHandlerUrl() function)
+ * Zones default to using "<repo name>-<zone name>" as the container name
+ * and default to using the container root as the zone's root directory.
+ * Nesting of zone locations within other zones should be avoided.
+ * - url Public zone URL. The 'zones' settings take precedence.
* - hashLevels The number of directory levels for hash-based division of files
* - thumbScriptUrl The URL for thumb.php (optional, not recommended)
* - transformVia404 Whether to skip media file transformation on parse and rely on a 404
@@ -329,9 +383,11 @@ $wgImgAuthPublicTest = true;
* is 0644.
* - directory The local filesystem directory where public files are stored. Not used for
* some remote repos.
- * - thumbDir The base thumbnail directory. Defaults to <directory>/thumb.
- * - thumbUrl The base thumbnail URL. Defaults to <url>/thumb.
- *
+ * - thumbDir The base thumbnail directory. Defaults to "<directory>/thumb".
+ * - thumbUrl The base thumbnail URL. Defaults to "<url>/thumb".
+ * - isPrivate Set this if measures should always be taken to keep the files private.
+ * One should not trust this to assure that the files are not web readable;
+ * the server configuration should be done manually depending on the backend.
*
* These settings describe a foreign MediaWiki installation. They are optional, and will be ignored
* for local repositories:
@@ -343,7 +399,9 @@ $wgImgAuthPublicTest = true;
*
* - articleUrl Equivalent to $wgArticlePath, e.g. http://en.wikipedia.org/wiki/$1
* - fetchDescription Fetch the text of the remote file description page. Equivalent to
- * $wgFetchCommonsDescriptions.
+ * $wgFetchCommonsDescriptions.
+ * - abbrvThreshold File names over this size will use the short form of thumbnail names.
+ * Short thumbnail names only have the width, parameters, and the extension.
*
* ForeignDBRepo:
* - dbType, dbServer, dbUser, dbPassword, dbName, dbFlags
@@ -380,10 +438,11 @@ $wgUseInstantCommons = false;
* File backend structure configuration.
* This is an array of file backend configuration arrays.
* Each backend configuration has the following parameters:
- * 'name' : A unique name for the backend
- * 'class' : The file backend class to use
- * 'wikiId' : A unique string that identifies the wiki (container prefix)
- * 'lockManager' : The name of a lock manager (see $wgLockManagers)
+ * - 'name' : A unique name for the backend
+ * - 'class' : The file backend class to use
+ * - 'wikiId' : A unique string that identifies the wiki (container prefix)
+ * - 'lockManager' : The name of a lock manager (see $wgLockManagers)
+ *
* Additional parameters are specific to the class used.
*/
$wgFileBackends = array();
@@ -391,8 +450,8 @@ $wgFileBackends = array();
/**
* Array of configuration arrays for each lock manager.
* Each backend configuration has the following parameters:
- * 'name' : A unique name for the lock manger
- * 'class' : The lock manger class to use
+ * - 'name' : A unique name for the lock manager
+ * - 'class' : The lock manger class to use
* Additional parameters are specific to the class used.
*/
$wgLockManagers = array();
@@ -401,12 +460,13 @@ $wgLockManagers = array();
* Show EXIF data, on by default if available.
* Requires PHP's EXIF extension: http://www.php.net/manual/en/ref.exif.php
*
- * NOTE FOR WINDOWS USERS:
- * To enable EXIF functions, add the following lines to the
- * "Windows extensions" section of php.ini:
- *
+ * @note FOR WINDOWS USERS:
+ * To enable EXIF functions, add the following lines to the "Windows
+ * extensions" section of php.ini:
+ * @code{.ini}
* extension=extensions/php_mbstring.dll
* extension=extensions/php_exif.dll
+ * @endcode
*/
$wgShowEXIF = function_exists( 'exif_read_data' );
@@ -431,23 +491,32 @@ $wgUpdateCompatibleMetadata = false;
* $wgForeignFileRepos variable.
*/
$wgUseSharedUploads = false;
+
/** Full path on the web server where shared uploads can be found */
$wgSharedUploadPath = "http://commons.wikimedia.org/shared/images";
+
/** Fetch commons image description pages and display them on the local wiki? */
$wgFetchCommonsDescriptions = false;
+
/** Path on the file system where shared uploads can be found. */
$wgSharedUploadDirectory = "/var/www/wiki3/images";
+
/** DB name with metadata about shared directory. Set this to false if the uploads do not come from a wiki. */
$wgSharedUploadDBname = false;
+
/** Optional table prefix used in database. */
$wgSharedUploadDBprefix = '';
+
/** Cache shared metadata in memcached. Don't do this if the commons wiki is in a different memcached domain */
$wgCacheSharedUploads = true;
+
/**
-* Allow for upload to be copied from an URL. Requires Special:Upload?source=web
-* The timeout for copy uploads is set by $wgHTTPTimeout.
-*/
+ * Allow for upload to be copied from an URL.
+ * The timeout for copy uploads is set by $wgHTTPTimeout.
+ * You have to assign the user right 'upload_by_url' to a user group, to use this.
+ */
$wgAllowCopyUploads = false;
+
/**
* Allow asynchronous copy uploads.
* This feature is experimental and broken as of r81612.
@@ -455,16 +524,31 @@ $wgAllowCopyUploads = false;
$wgAllowAsyncCopyUploads = false;
/**
+ * A list of domains copy uploads can come from
+ *
+ * @since 1.20
+ */
+$wgCopyUploadsDomains = array();
+
+/**
+ * Proxy to use for copy upload requests.
+ * @since 1.20
+ */
+$wgCopyUploadProxy = false;
+
+/**
* Max size for uploads, in bytes. If not set to an array, applies to all
* uploads. If set to an array, per upload type maximums can be set, using the
* file and url keys. If the * key is set this value will be used as maximum
* for non-specified types.
*
- * For example:
+ * @par Example:
+ * @code
* $wgMaxUploadSize = array(
* '*' => 250 * 1024,
* 'url' => 500 * 1024,
* );
+ * @endcode
* Sets the maximum for all uploads to 250 kB except for upload-by-url, which
* will have a maximum of 500 kB.
*
@@ -474,27 +558,37 @@ $wgMaxUploadSize = 1024*1024*100; # 100MB
/**
* Point the upload navigation link to an external URL
* Useful if you want to use a shared repository by default
- * without disabling local uploads (use $wgEnableUploads = false for that)
- * e.g. $wgUploadNavigationUrl = 'http://commons.wikimedia.org/wiki/Special:Upload';
+ * without disabling local uploads (use $wgEnableUploads = false for that).
+ *
+ * @par Example:
+ * @code
+ * $wgUploadNavigationUrl = 'http://commons.wikimedia.org/wiki/Special:Upload';
+ * @endcode
*/
$wgUploadNavigationUrl = false;
/**
* Point the upload link for missing files to an external URL, as with
- * $wgUploadNavigationUrl. The URL will get (?|&)wpDestFile=<filename>
+ * $wgUploadNavigationUrl. The URL will get "(?|&)wpDestFile=<filename>"
* appended to it as appropriate.
*/
$wgUploadMissingFileUrl = false;
/**
- * Give a path here to use thumb.php for thumbnail generation on client request, instead of
- * generating them on render and outputting a static URL. This is necessary if some of your
- * apache servers don't have read/write access to the thumbnail path.
+ * Give a path here to use thumb.php for thumbnail generation on client
+ * request, instead of generating them on render and outputting a static URL.
+ * This is necessary if some of your apache servers don't have read/write
+ * access to the thumbnail path.
*
- * Example:
+ * @par Example:
+ * @code
* $wgThumbnailScriptPath = "{$wgScriptPath}/thumb{$wgScriptExtension}";
+ * @endcode
*/
$wgThumbnailScriptPath = false;
+/**
+ * @see $wgThumbnailScriptPath
+ */
$wgSharedThumbnailScriptPath = false;
/**
@@ -507,7 +601,8 @@ $wgSharedThumbnailScriptPath = false;
* maintenance/rebuildImages.php to register them in the database. This is no
* longer recommended, use maintenance/importImages.php instead.
*
- * Note that this variable may be ignored if $wgLocalFileRepo is set.
+ * @note That this variable may be ignored if $wgLocalFileRepo is set.
+ * @todo Deprecate the setting and ultimately remove it from Core.
*/
$wgHashedUploadDirectory = true;
@@ -532,13 +627,17 @@ $wgRepositoryBaseUrl = "http://commons.wikimedia.org/wiki/File:";
* This is the list of preferred extensions for uploading files. Uploading files
* with extensions not in this list will trigger a warning.
*
- * WARNING: If you add any OpenOffice or Microsoft Office file formats here,
+ * @warning If you add any OpenOffice or Microsoft Office file formats here,
* such as odt or doc, and untrusted users are allowed to upload files, then
* your wiki will be vulnerable to cross-site request forgery (CSRF).
*/
$wgFileExtensions = array( 'png', 'gif', 'jpg', 'jpeg' );
-/** Files with these extensions will never be allowed as uploads. */
+/**
+ * Files with these extensions will never be allowed as uploads.
+ * An array of file extensions to blacklist. You should append to this array
+ * if you want to blacklist additional files.
+ * */
$wgFileBlacklist = array(
# HTML may contain cookie-stealing JavaScript and web bugs
'html', 'htm', 'js', 'jsb', 'mhtml', 'mht', 'xhtml', 'xht',
@@ -576,7 +675,7 @@ $wgAllowJavaUploads = false;
/**
* This is a flag to determine whether or not to check file extensions on upload.
*
- * WARNING: setting this to false is insecure for public wikis.
+ * @warning Setting this to false is insecure for public wikis.
*/
$wgCheckFileExtensions = true;
@@ -584,18 +683,21 @@ $wgCheckFileExtensions = true;
* If this is turned off, users may override the warning for files not covered
* by $wgFileExtensions.
*
- * WARNING: setting this to false is insecure for public wikis.
+ * @warning Setting this to false is insecure for public wikis.
*/
$wgStrictFileExtensions = true;
/**
* Setting this to true will disable the upload system's checks for HTML/JavaScript.
- * THIS IS VERY DANGEROUS on a publicly editable site, so USE wgGroupPermissions
- * TO RESTRICT UPLOADING to only those that you trust
+ *
+ * @warning THIS IS VERY DANGEROUS on a publicly editable site, so USE
+ * $wgGroupPermissions TO RESTRICT UPLOADING to only those that you trust
*/
$wgDisableUploadScriptChecks = false;
-/** Warn if uploaded files are larger than this (in bytes), or false to disable*/
+/**
+ * Warn if uploaded files are larger than this (in bytes), or false to disable
+ */
$wgUploadSizeWarning = false;
/**
@@ -622,18 +724,18 @@ $wgTrustedMediaFormats = array(
* Each entry in the array maps a MIME type to a class name
*/
$wgMediaHandlers = array(
- 'image/jpeg' => 'JpegHandler',
- 'image/png' => 'PNGHandler',
- 'image/gif' => 'GIFHandler',
- 'image/tiff' => 'TiffHandler',
+ 'image/jpeg' => 'JpegHandler',
+ 'image/png' => 'PNGHandler',
+ 'image/gif' => 'GIFHandler',
+ 'image/tiff' => 'TiffHandler',
'image/x-ms-bmp' => 'BmpHandler',
- 'image/x-bmp' => 'BmpHandler',
- 'image/x-xcf' => 'XCFHandler',
- 'image/svg+xml' => 'SvgHandler', // official
- 'image/svg' => 'SvgHandler', // compat
+ 'image/x-bmp' => 'BmpHandler',
+ 'image/x-xcf' => 'XCFHandler',
+ 'image/svg+xml' => 'SvgHandler', // official
+ 'image/svg' => 'SvgHandler', // compat
'image/vnd.djvu' => 'DjVuHandler', // official
- 'image/x.djvu' => 'DjVuHandler', // compat
- 'image/x-djvu' => 'DjVuHandler', // compat
+ 'image/x.djvu' => 'DjVuHandler', // compat
+ 'image/x-djvu' => 'DjVuHandler', // compat
);
/**
@@ -667,17 +769,18 @@ $wgImageMagickTempDir = false;
* %s will be replaced with the source path, %d with the destination
* %w and %h will be replaced with the width and height.
*
- * Example for GraphicMagick:
- * <code>
+ * @par Example for GraphicMagick:
+ * @code
* $wgCustomConvertCommand = "gm convert %s -resize %wx%h %d"
- * </code>
+ * @endcode
*
* Leave as false to skip this.
*/
$wgCustomConvertCommand = false;
/**
- * Some tests and extensions use exiv2 to manipulate the EXIF metadata in some image formats.
+ * Some tests and extensions use exiv2 to manipulate the EXIF metadata in some
+ * image formats.
*/
$wgExiv2Command = '/usr/bin/exiv2';
@@ -699,22 +802,31 @@ $wgSVGConverters = array(
'imgserv' => '$path/imgserv-wrapper -i svg -o png -w$width $input $output',
'ImagickExt' => array( 'SvgHandler::rasterizeImagickExt' ),
);
+
/** Pick a converter defined in $wgSVGConverters */
$wgSVGConverter = 'ImageMagick';
+
/** If not in the executable PATH, specify the SVG converter path. */
$wgSVGConverterPath = '';
+
/** Don't scale a SVG larger than this */
$wgSVGMaxSize = 2048;
+
/** Don't read SVG metadata beyond this point.
- * Default is 1024*256 bytes */
+ * Default is 1024*256 bytes
+ */
$wgSVGMetadataCutoff = 262144;
/**
- * MediaWiki will reject HTMLesque tags in uploaded files due to idiotic browsers which can't
- * perform basic stuff like MIME detection and which are vulnerable to further idiots uploading
- * crap files as images. When this directive is on, <title> will be allowed in files with
- * an "image/svg+xml" MIME type. You should leave this disabled if your web server is misconfigured
- * and doesn't send appropriate MIME types for SVG images.
+ * Disallow <title> element in SVG files.
+ *
+ * MediaWiki will reject HTMLesque tags in uploaded files due to idiotic
+ * browsers which can not perform basic stuff like MIME detection and which are
+ * vulnerable to further idiots uploading crap files as images.
+ *
+ * When this directive is on, "<title>" will be allowed in files with an
+ * "image/svg+xml" MIME type. You should leave this disabled if your web server
+ * is misconfigured and doesn't send appropriate MIME types for SVG images.
*/
$wgAllowTitlesInSVG = false;
@@ -744,13 +856,13 @@ $wgMaxAnimatedGifArea = 1.25e7;
* For inline display, we need to convert to PNG or JPEG.
* Note scaling should work with ImageMagick, but may not with GD scaling.
*
- * Example:
- * <code>
+ * @par Example:
+ * @code
* // PNG is lossless, but inefficient for photos
* $wgTiffThumbnailType = array( 'png', 'image/png' );
* // JPEG is good for photos, but has no transparency support. Bad for diagrams.
* $wgTiffThumbnailType = array( 'jpg', 'image/jpeg' );
- * </code>
+ * @endcode
*/
$wgTiffThumbnailType = false;
@@ -763,7 +875,7 @@ $wgMaxAnimatedGifArea = 1.25e7;
$wgThumbnailEpoch = '20030516000000';
/**
- * If set, inline scaled images will still produce <img> tags ready for
+ * If set, inline scaled images will still produce "<img>" tags ready for
* output instead of showing an error message.
*
* This may be useful if errors are transitory, especially if the site
@@ -855,20 +967,6 @@ $wgAntivirusSetup = array(
'messagepattern' => '/.*?:(.*)/sim',
),
-
- #setup for f-prot
- 'f-prot' => array (
- 'command' => "f-prot ",
-
- 'codemap' => array (
- "0" => AV_NO_VIRUS, # no virus
- "3" => AV_VIRUS_FOUND, # virus found
- "6" => AV_VIRUS_FOUND, # virus found
- "*" => AV_SCAN_FAILED, # else scan failed
- ),
-
- 'messagepattern' => '/.*?Infection:(.*)$/m',
- ),
);
@@ -898,10 +996,11 @@ $wgLoadFileinfoExtension = false;
* the mime type to standard output.
* The name of the file to process will be appended to the command given here.
* If not set or NULL, mime_content_type will be used if available.
- * Example:
- * <code>
+ *
+ * @par Example:
+ * @code
* #$wgMimeDetectorCommand = "file -bi"; # use external mime detector (Linux)
- * </code>
+ * @endcode
*/
$wgMimeDetectorCommand = null;
@@ -937,8 +1036,7 @@ $wgImageLimits = array(
array( 640, 480 ),
array( 800, 600 ),
array( 1024, 768 ),
- array( 1280, 1024 ),
- array( 10000, 10000 )
+ array( 1280, 1024 )
);
/**
@@ -956,7 +1054,7 @@ $wgThumbLimits = array(
);
/**
- * Default parameters for the <gallery> tag
+ * Default parameters for the "<gallery>" tag
*/
$wgGalleryOptions = array (
'imagesPerRow' => 0, // Default number of images per-row in the gallery. 0 -> Adapt to screensize
@@ -979,7 +1077,10 @@ $wgThumbUpright = 0.75;
$wgDirectoryMode = 0777;
/**
- * DJVU settings
+ * @name DJVU settings
+ * @{
+ */
+/**
* Path of the djvudump executable
* Enable this and $wgDjvuRenderer to enable djvu rendering
*/
@@ -1004,15 +1105,18 @@ $wgDjvuTxt = null;
* Path of the djvutoxml executable
* This works like djvudump except much, much slower as of version 3.5.
*
- * For now I recommend you use djvudump instead. The djvuxml output is
+ * For now we recommend you use djvudump instead. The djvuxml output is
* probably more stable, so we'll switch back to it as soon as they fix
* the efficiency problem.
* http://sourceforge.net/tracker/index.php?func=detail&aid=1704049&group_id=32953&atid=406583
+ *
+ * @par Example:
+ * @code
+ * $wgDjvuToXML = 'djvutoxml';
+ * @endcode
*/
-# $wgDjvuToXML = 'djvutoxml';
$wgDjvuToXML = null;
-
/**
* Shell command for the DJVU post processor
* Default: pnmtopng, since ddjvu generates ppm output
@@ -1023,6 +1127,7 @@ $wgDjvuPostProcessor = 'pnmtojpeg';
* File extension for the DJVU post processor output
*/
$wgDjvuOutputExtension = 'jpg';
+/** @} */ # end of DJvu }
/** @} */ # end of file uploads }
@@ -1099,17 +1204,21 @@ $wgNewPasswordExpiry = 3600 * 24 * 7;
$wgUserEmailConfirmationTokenExpiry = 7 * 24 * 60 * 60;
/**
- * SMTP Mode
+ * SMTP Mode.
+ *
* For using a direct (authenticated) SMTP server connection.
* Default to false or fill an array :
- * <code>
- * "host" => 'SMTP domain',
- * "IDHost" => 'domain for MessageID',
- * "port" => "25",
- * "auth" => true/false,
- * "username" => user,
- * "password" => password
- * </code>
+ *
+ * @code
+ * $wgSMTP = array(
+ * 'host' => 'SMTP domain',
+ * 'IDHost' => 'domain for MessageID',
+ * 'port' => '25',
+ * 'auth' => [true|false],
+ * 'username' => [SMTP username],
+ * 'password' => [SMTP password],
+ * );
+ * @endcode
*/
$wgSMTP = false;
@@ -1131,9 +1240,9 @@ $wgEnotifFromEditor = false;
# It call this to be a "user-preferences-option (UPO)"
/**
- * Require email authentication before sending mail to an email addres. This is
- * highly recommended. It prevents MediaWiki from being used as an open spam
- * relay.
+ * Require email authentication before sending mail to an email address.
+ * This is highly recommended. It prevents MediaWiki from being used as an open
+ * spam relay.
*/
$wgEmailAuthentication = true;
@@ -1211,6 +1320,10 @@ $wgDBuser = 'wikiuser';
$wgDBpassword = '';
/** Database type */
$wgDBtype = 'mysql';
+/** Whether to use SSL in DB connection. */
+$wgDBssl = false;
+/** Whether to use compression in DB connection. */
+$wgDBcompress = false;
/** Separate username for maintenance tasks. Leave as null to use the default. */
$wgDBadminuser = null;
@@ -1295,6 +1408,9 @@ $wgSharedTables = array( 'user', 'user_properties' );
* - DBO_TRX -- wrap entire request in a transaction
* - DBO_IGNORE -- ignore errors (not useful in LocalSettings.php)
* - DBO_NOBUFFER -- turn off buffering (not useful in LocalSettings.php)
+ * - DBO_PERSISTENT -- enables persistent database connections
+ * - DBO_SSL -- uses SSL/TLS encryption in database connections, if available
+ * - DBO_COMPRESS -- uses internal compression in database connections, if available
*
* - max lag: (optional) Maximum replication lag before a slave will taken out of rotation
* - max threads: (optional) Maximum number of running threads
@@ -1311,9 +1427,9 @@ $wgSharedTables = array( 'user', 'user_properties' );
* accidental misconfiguration or MediaWiki bugs, set read_only=1 on all your
* slaves in my.cnf. You can set read_only mode at runtime using:
*
- * <code>
+ * @code
* SET @@read_only=1;
- * </code>
+ * @endcode
*
* Since the effect of writing to a slave is so damaging and difficult to clean
* up, we at Wikimedia set read_only=1 in my.cnf on all our DB servers, even
@@ -1339,23 +1455,41 @@ $wgMasterWaitTimeout = 10;
/** File to log database errors to */
$wgDBerrorLog = false;
+/**
+ * Timezone to use in the error log.
+ * Defaults to the wiki timezone ($wgLocaltimezone).
+ *
+ * A list of useable timezones can found at:
+ * http://php.net/manual/en/timezones.php
+ *
+ * @par Examples:
+ * @code
+ * $wgLocaltimezone = 'UTC';
+ * $wgLocaltimezone = 'GMT';
+ * $wgLocaltimezone = 'PST8PDT';
+ * $wgLocaltimezone = 'Europe/Sweden';
+ * $wgLocaltimezone = 'CET';
+ * @endcode
+ *
+ * @since 1.20
+ */
+$wgDBerrorLogTZ = false;
+
/** When to give an error message */
$wgDBClusterTimeout = 10;
/**
- * Scale load balancer polling time so that under overload conditions, the database server
- * receives a SHOW STATUS query at an average interval of this many microseconds
+ * Scale load balancer polling time so that under overload conditions, the
+ * database server receives a SHOW STATUS query at an average interval of this
+ * many microseconds
*/
$wgDBAvgStatusPoll = 2000;
-/** Set to true if using InnoDB tables */
-$wgDBtransactions = false;
-
/**
* Set to true to engage MySQL 4.1/5.0 charset-related features;
* for now will just cause sending of 'SET NAMES=utf8' on connect.
*
- * WARNING: THIS IS EXPERIMENTAL!
+ * @warning THIS IS EXPERIMENTAL!
*
* May break if you're not using the table defs from mysql5/tables.sql.
* May break if you're upgrading an existing wiki if set differently.
@@ -1408,19 +1542,30 @@ $wgCompressRevisions = false;
/**
* External stores allow including content
- * from non database sources following URL links
+ * from non database sources following URL links.
*
* Short names of ExternalStore classes may be specified in an array here:
+ * @code
* $wgExternalStores = array("http","file","custom")...
+ * @endcode
*
* CAUTION: Access to database might lead to code execution
*/
$wgExternalStores = false;
/**
- * An array of external mysql servers, e.g.
- * $wgExternalServers = array( 'cluster1' => array( 'srv28', 'srv29', 'srv30' ) );
- * Used by LBFactory_Simple, may be ignored if $wgLBFactoryConf is set to another class.
+ * An array of external MySQL servers.
+ *
+ * @par Example:
+ * Create a cluster named 'cluster1' containing three servers:
+ * @code
+ * $wgExternalServers = array(
+ * 'cluster1' => array( 'srv28', 'srv29', 'srv30' )
+ * );
+ * @endcode
+ *
+ * Used by LBFactory_Simple, may be ignored if $wgLBFactoryConf is set to
+ * another class.
*/
$wgExternalServers = array();
@@ -1429,9 +1574,12 @@ $wgExternalServers = array();
* Part of a URL, e.g. DB://cluster1
*
* Can be an array instead of a single string, to enable data distribution. Keys
- * must be consecutive integers, starting at zero. Example:
+ * must be consecutive integers, starting at zero.
*
+ * @par Example:
+ * @code
* $wgDefaultExternalStore = array( 'DB://cluster1', 'DB://cluster2' );
+ * @endcode
*
* @var array
*/
@@ -1471,17 +1619,10 @@ $wgUseDumbLinkUpdate = false;
/**
* Anti-lock flags - bitfield
- * - ALF_PRELOAD_LINKS:
- * Preload links during link update for save
- * - ALF_PRELOAD_EXISTENCE:
- * Preload cur_id during replaceLinkHolders
* - ALF_NO_LINK_LOCK:
* Don't use locking reads when updating the link table. This is
* necessary for wikis with a high edit rate for performance
* reasons, but may cause link table inconsistency
- * - ALF_NO_BLOCK_LOCK:
- * As for ALF_LINK_LOCK, this flag is a necessity for high-traffic
- * wikis.
*/
$wgAntiLockFlags = 0;
@@ -1552,11 +1693,29 @@ $wgMessageCacheType = CACHE_ANYTHING;
$wgParserCacheType = CACHE_ANYTHING;
/**
+ * The cache type for storing session data. Used if $wgSessionsInObjectCache is true.
+ *
+ * For available types see $wgMainCacheType.
+ */
+$wgSessionCacheType = CACHE_ANYTHING;
+
+/**
+ * The cache type for storing language conversion tables,
+ * which are used when parsing certain text and interface messages.
+ *
+ * For available types see $wgMainCacheType.
+ *
+ * @since 1.20
+ */
+$wgLanguageConverterCacheType = CACHE_ANYTHING;
+
+/**
* Advanced object cache configuration.
*
* Use this to define the class names and constructor parameters which are used
* for the various cache types. Custom cache types may be defined here and
- * referenced from $wgMainCacheType, $wgMessageCacheType or $wgParserCacheType.
+ * referenced from $wgMainCacheType, $wgMessageCacheType, $wgParserCacheType,
+ * or $wgLanguageConverterCacheType.
*
* The format is an associative array where the key is a cache identifier, and
* the value is an associative array of parameters. The "class" parameter is the
@@ -1580,28 +1739,44 @@ $wgObjectCaches = array(
'xcache' => array( 'class' => 'XCacheBagOStuff' ),
'wincache' => array( 'class' => 'WinCacheBagOStuff' ),
'memcached-php' => array( 'class' => 'MemcachedPhpBagOStuff' ),
+ 'memcached-pecl' => array( 'class' => 'MemcachedPeclBagOStuff' ),
'hash' => array( 'class' => 'HashBagOStuff' ),
);
/**
- * The expiry time for the parser cache, in seconds. The default is 86.4k
- * seconds, otherwise known as a day.
+ * The expiry time for the parser cache, in seconds.
+ * The default is 86400 (one day).
*/
$wgParserCacheExpireTime = 86400;
/**
- * Select which DBA handler <http://www.php.net/manual/en/dba.requirements.php> to use as CACHE_DBA backend
+ * Select which DBA handler <http://www.php.net/manual/en/dba.requirements.php>
+ * to use as CACHE_DBA backend.
*/
$wgDBAhandler = 'db3';
/**
- * Store sessions in MemCached. This can be useful to improve performance, or to
- * avoid the locking behaviour of PHP's default session handler, which tends to
- * prevent multiple requests for the same user from acting concurrently.
+ * Deprecated alias for $wgSessionsInObjectCache.
+ *
+ * @deprecated Use $wgSessionsInObjectCache
*/
$wgSessionsInMemcached = false;
/**
+ * Store sessions in an object cache, configured by $wgSessionCacheType. This
+ * can be useful to improve performance, or to avoid the locking behaviour of
+ * PHP's default session handler, which tends to prevent multiple requests for
+ * the same user from acting concurrently.
+ */
+$wgSessionsInObjectCache = false;
+
+/**
+ * The expiry time to use for session storage when $wgSessionsInObjectCache is
+ * enabled, in seconds.
+ */
+$wgObjectCacheSessionExpiry = 3600;
+
+/**
* This is used for setting php's session.save_handler. In practice, you will
* almost never need to change this ever. Other options might be 'user' or
* 'session_mysql.' Setting to null skips setting this entirely (which might be
@@ -1624,7 +1799,7 @@ $wgMemCachedPersistent = false;
/**
* Read/write timeout for MemCached server communication, in microseconds.
*/
-$wgMemCachedTimeout = 100000;
+$wgMemCachedTimeout = 500000;
/**
* Set this to true to make a local copy of the message cache, for use in
@@ -1633,9 +1808,9 @@ $wgMemCachedTimeout = 100000;
$wgUseLocalMessageCache = false;
/**
- * Defines format of local cache
- * true - Serialized object
- * false - PHP source file (Warning - security risk)
+ * Defines format of local cache.
+ * - true: Serialized object
+ * - false: PHP source file (Warning - security risk)
*/
$wgLocalMessageCacheSerialized = true;
@@ -1648,23 +1823,23 @@ $wgAdaptiveMessageCache = false;
/**
* Localisation cache configuration. Associative array with keys:
- * class: The class to use. May be overridden by extensions.
+ * class: The class to use. May be overridden by extensions.
*
- * store: The location to store cache data. May be 'files', 'db' or
- * 'detect'. If set to "files", data will be in CDB files. If set
- * to "db", data will be stored to the database. If set to
- * "detect", files will be used if $wgCacheDirectory is set,
- * otherwise the database will be used.
+ * store: The location to store cache data. May be 'files', 'db' or
+ * 'detect'. If set to "files", data will be in CDB files. If set
+ * to "db", data will be stored to the database. If set to
+ * "detect", files will be used if $wgCacheDirectory is set,
+ * otherwise the database will be used.
*
- * storeClass: The class name for the underlying storage. If set to a class
- * name, it overrides the "store" setting.
+ * storeClass: The class name for the underlying storage. If set to a class
+ * name, it overrides the "store" setting.
*
- * storeDirectory: If the store class puts its data in files, this is the
- * directory it will use. If this is false, $wgCacheDirectory
- * will be used.
+ * storeDirectory: If the store class puts its data in files, this is the
+ * directory it will use. If this is false, $wgCacheDirectory
+ * will be used.
*
- * manualRecache: Set this to true to disable cache updates on web requests.
- * Use maintenance/rebuildLocalisationCache.php instead.
+ * manualRecache: Set this to true to disable cache updates on web requests.
+ * Use maintenance/rebuildLocalisationCache.php instead.
*/
$wgLocalisationCacheConf = array(
'class' => 'LocalisationCache',
@@ -1679,14 +1854,17 @@ $wgCachePages = true;
/**
* Set this to current time to invalidate all prior cached pages. Affects both
- * client- and server-side caching.
+ * client-side and server-side caching.
* You can get the current date on your server by using the command:
+ * @verbatim
* date +%Y%m%d%H%M%S
+ * @endverbatim
*/
$wgCacheEpoch = '20030516000000';
/**
* Bump this number when changing the global style sheets and JavaScript.
+ *
* It should be appended in the query string of static CSS and JS includes,
* to ensure that client-side caches do not keep obsolete copies of global
* styles.
@@ -1703,12 +1881,6 @@ $wgStyleVersion = '303';
$wgUseFileCache = false;
/**
- * Directory where the cached page will be saved.
- * Will default to "{$wgUploadDirectory}/cache" in Setup.php
- */
-$wgFileCacheDirectory = false;
-
-/**
* Depth of the subdirectory hierarchy to be created under
* $wgFileCacheDirectory. The subdirectories will be named based on
* the MD5 hash of the title. A value of 0 means all cache files will
@@ -1752,8 +1924,6 @@ $wgSidebarCacheExpiry = 86400;
/**
* When using the file cache, we can store the cached HTML gzipped to save disk
* space. Pages will then also be served compressed to clients that support it.
- * THIS IS NOT COMPATIBLE with ob_gzhandler which is now enabled if supported in
- * the default LocalSettings.php! If you enable this, remove that setting first.
*
* Requires zlib support enabled in PHP.
*/
@@ -1820,10 +1990,12 @@ $wgUseXVO = false;
$wgVaryOnXFP = false;
/**
- * Internal server name as known to Squid, if different. Example:
- * <code>
+ * Internal server name as known to Squid, if different.
+ *
+ * @par Example:
+ * @code
* $wgInternalServer = 'http://yourinternal.tld:8000';
- * </code>
+ * @endcode
*/
$wgInternalServer = false;
@@ -1860,22 +2032,61 @@ $wgSquidServersNoPurge = array();
$wgMaxSquidPurgeTitles = 400;
/**
+ * Routing configuration for HTCP multicast purging. Add elements here to
+ * enable HTCP and determine which purges are sent where. If set to an empty
+ * array, HTCP is disabled.
+ *
+ * Each key in this array is a regular expression to match against the purged
+ * URL, or an empty string to match all URLs. The purged URL is matched against
+ * the regexes in the order specified, and the first rule whose regex matches
+ * is used.
+ *
+ * Example configuration to send purges for upload.wikimedia.org to one
+ * multicast group and all other purges to another:
+ * @code
+ * $wgHTCPMulticastRouting = array(
+ * '|^https?://upload\.wikimedia\.org|' => array(
+ * 'host' => '239.128.0.113',
+ * 'port' => 4827,
+ * ),
+ * '' => array(
+ * 'host' => '239.128.0.112',
+ * 'port' => 4827,
+ * ),
+ * );
+ * @endcode
+ *
+ * @since 1.20
+ *
+ * @see $wgHTCPMulticastTTL
+ */
+$wgHTCPMulticastRouting = array();
+
+/**
* HTCP multicast address. Set this to a multicast IP address to enable HTCP.
*
* Note that MediaWiki uses the old non-RFC compliant HTCP format, which was
* present in the earliest Squid implementations of the protocol.
+ *
+ * This setting is DEPRECATED in favor of $wgHTCPMulticastRouting , and kept
+ * for backwards compatibility only. If $wgHTCPMulticastRouting is set, this
+ * setting is ignored. If $wgHTCPMulticastRouting is not set and this setting
+ * is, it is used to populate $wgHTCPMulticastRouting.
+ *
+ * @deprecated in favor of $wgHTCPMulticastRouting
*/
$wgHTCPMulticastAddress = false;
/**
* HTCP multicast port.
+ * @deprecated in favor of $wgHTCPMulticastRouting
* @see $wgHTCPMulticastAddress
*/
$wgHTCPPort = 4827;
/**
* HTCP multicast TTL.
- * @see $wgHTCPMulticastAddress
+ * @see $wgHTCPMulticastRouting
*/
$wgHTCPMulticastTTL = 1;
@@ -1894,11 +2105,12 @@ $wgLanguageCode = 'en';
/**
* Some languages need different word forms, usually for different cases.
- * Used in Language::convertGrammar(). Example:
+ * Used in Language::convertGrammar().
*
- * <code>
+ * @par Example:
+ * @code
* $wgGrammarForms['en']['genitive']['car'] = 'car\'s';
- * </code>
+ * @endcode
*/
$wgGrammarForms = array();
@@ -1981,7 +2193,7 @@ $wgAllUnicodeFixes = false;
* converting a wiki from MediaWiki 1.4 or earlier to UTF-8 without the
* burdensome mass conversion of old text data.
*
- * NOTE! This DOES NOT touch any fields other than old_text.Titles, comments,
+ * @note This DOES NOT touch any fields other than old_text. Titles, comments,
* user names, etc still must be converted en masse in the database before
* continuing as a UTF-8 wiki.
*/
@@ -2090,28 +2302,27 @@ $wgCanonicalLanguageLinks = true;
$wgDefaultLanguageVariant = false;
/**
- * Disabled variants array of language variant conversion. Example:
- * <code>
+ * Disabled variants array of language variant conversion.
+ *
+ * @par Example:
+ * @code
* $wgDisabledVariants[] = 'zh-mo';
* $wgDisabledVariants[] = 'zh-my';
- * </code>
- *
- * or:
- *
- * <code>
- * $wgDisabledVariants = array('zh-mo', 'zh-my');
- * </code>
+ * @endcode
*/
$wgDisabledVariants = array();
/**
* Like $wgArticlePath, but on multi-variant wikis, this provides a
* path format that describes which parts of the URL contain the
- * language variant. For Example:
+ * language variant.
*
- * $wgLanguageCode = 'sr';
- * $wgVariantArticlePath = '/$2/$1';
- * $wgArticlePath = '/wiki/$1';
+ * @par Example:
+ * @code
+ * $wgLanguageCode = 'sr';
+ * $wgVariantArticlePath = '/$2/$1';
+ * $wgArticlePath = '/wiki/$1';
+ * @endcode
*
* A link to /wiki/ would be redirected to /sr/Главна_страна
*
@@ -2128,19 +2339,23 @@ $wgVariantArticlePath = false;
$wgLoginLanguageSelector = false;
/**
- * When translating messages with wfMsg(), it is not always clear what should
- * be considered UI messages and what should be content messages.
+ * When translating messages with wfMessage(), it is not always clear what
+ * should be considered UI messages and what should be content messages.
*
* For example, for the English Wikipedia, there should be only one 'mainpage',
* so when getting the link for 'mainpage', we should treat it as site content
- * and call wfMsgForContent(), but for rendering the text of the link, we call
- * wfMsg(). The code behaves this way by default. However, sites like the
- * Wikimedia Commons do offer different versions of 'mainpage' and the like for
- * different languages. This array provides a way to override the default
- * behavior. For example, to allow language-specific main page and community
- * portal, set
- *
- * $wgForceUIMsgAsContentMsg = array( 'mainpage', 'portal-url' );
+ * and call ->inContentLanguage()->text(), but for rendering the text of the
+ * link, we call ->text(). The code behaves this way by default. However,
+ * sites like the Wikimedia Commons do offer different versions of 'mainpage'
+ * and the like for different languages. This array provides a way to override
+ * the default behavior.
+ *
+ * @par Example:
+ * To allow language-specific main page and community
+ * portal:
+ * @code
+ * $wgForceUIMsgAsContentMsg = array( 'mainpage', 'portal-url' );
+ * @endcode
*/
$wgForceUIMsgAsContentMsg = array();
@@ -2155,13 +2370,17 @@ $wgForceUIMsgAsContentMsg = array();
* Timezones can be translated by editing MediaWiki messages of type
* timezone-nameinlowercase like timezone-utc.
*
- * Examples:
- * <code>
+ * A list of useable timezones can found at:
+ * http://php.net/manual/en/timezones.php
+ *
+ * @par Examples:
+ * @code
+ * $wgLocaltimezone = 'UTC';
* $wgLocaltimezone = 'GMT';
* $wgLocaltimezone = 'PST8PDT';
* $wgLocaltimezone = 'Europe/Sweden';
* $wgLocaltimezone = 'CET';
- * </code>
+ * @endcode
*/
$wgLocaltimezone = null;
@@ -2182,7 +2401,7 @@ $wgLocalTZoffset = null;
* language variant conversion is disabled in interface messages. Setting this
* to true re-enables it.
*
- * This variable should be removed (implicitly false) in 1.20 or earlier.
+ * @todo This variable should be removed (implicitly false) in 1.20 or earlier.
*/
$wgBug34832TransitionalRollback = true;
@@ -2255,11 +2474,6 @@ $wgAllowRdfaAttributes = false;
$wgAllowMicrodataAttributes = false;
/**
- * Cleanup as much presentational html like valign -> css vertical-align as we can
- */
-$wgCleanupPresentationalAttributes = true;
-
-/**
* Should we try to make our HTML output well-formed XML? If set to false,
* output will be a few bytes shorter, and the HTML will arguably be more
* readable. If set to true, life will be much easier for the authors of
@@ -2279,10 +2493,14 @@ $wgWellFormedXml = true;
/**
* Permit other namespaces in addition to the w3.org default.
- * Use the prefix for the key and the namespace for the value. For
- * example:
+ *
+ * Use the prefix for the key and the namespace for the value.
+ *
+ * @par Example:
+ * @code
* $wgXhtmlNamespaces['svg'] = 'http://www.w3.org/2000/svg';
- * Normally we wouldn't have to define this in the root <html>
+ * @endCode
+ * Normally we wouldn't have to define this in the root "<html>"
* element, but IE needs it there in some circumstances.
*
* This is ignored if $wgHtml5 is true, for the same reason as
@@ -2293,7 +2511,7 @@ $wgXhtmlNamespaces = array();
/**
* Show IP address, for non-logged in users. It's necessary to switch this off
* for some forms of caching.
- * Will disable file cache.
+ * @warning Will disable file cache.
*/
$wgShowIPinHeader = true;
@@ -2464,15 +2682,16 @@ $wgExperimentalHtmlIds = false;
* The value should be either a string or an array. If it is a string it will be output
* directly as html, however some skins may choose to ignore it. An array is the preferred format
* for the icon, the following keys are used:
- * src: An absolute url to the image to use for the icon, this is recommended
+ * - src: An absolute url to the image to use for the icon, this is recommended
* but not required, however some skins will ignore icons without an image
- * url: The url to use in the <a> arround the text or icon, if not set an <a> will not be outputted
- * alt: This is the text form of the icon, it will be displayed without an image in
+ * - url: The url to use in the a element arround the text or icon, if not set an a element will not be outputted
+ * - alt: This is the text form of the icon, it will be displayed without an image in
* skins like Modern or if src is not set, and will otherwise be used as
* the alt="" for the image. This key is required.
- * width and height: If the icon specified by src is not of the standard size
+ * - width and height: If the icon specified by src is not of the standard size
* you can specify the size of image to use with these keys.
* Otherwise they will default to the standard 88x31.
+ * @todo Reformat documentation.
*/
$wgFooterIcons = array(
"copyright" => array(
@@ -2488,23 +2707,24 @@ $wgFooterIcons = array(
);
/**
- * Login / create account link behavior when it's possible for anonymous users to create an account
- * true = use a combined login / create account link
- * false = split login and create account into two separate links
+ * Login / create account link behavior when it's possible for anonymous users
+ * to create an account.
+ * - true = use a combined login / create account link
+ * - false = split login and create account into two separate links
*/
-$wgUseCombinedLoginLink = true;
+$wgUseCombinedLoginLink = false;
/**
- * Search form behavior for Vector skin only
- * true = use an icon search button
- * false = use Go & Search buttons
+ * Search form look for Vector skin only.
+ * - true = use an icon search button
+ * - false = use Go & Search buttons
*/
$wgVectorUseSimpleSearch = false;
/**
- * Watch and unwatch as an icon rather than a link for Vector skin only
- * true = use an icon watch/unwatch button
- * false = use watch/unwatch text link
+ * Watch and unwatch as an icon rather than a link for Vector skin only.
+ * - true = use an icon watch/unwatch button
+ * - false = use watch/unwatch text link
*/
$wgVectorUseIconWatch = false;
@@ -2534,6 +2754,16 @@ $wgBetterDirectionality = true;
*/
$wgSend404Code = true;
+
+/**
+ * The $wgShowRollbackEditCount variable is used to show how many edits will be
+ * rollback. The numeric value of the varible are the limit up to are counted.
+ * If the value is false or 0, the edits are not counted.
+ *
+ * @since 1.20
+ */
+$wgShowRollbackEditCount = 10;
+
/** @} */ # End of output format settings }
/*************************************************************************//**
@@ -2542,17 +2772,21 @@ $wgSend404Code = true;
*/
/**
- * Client-side resource modules. Extensions should add their module definitions
- * here.
+ * Client-side resource modules.
+ *
+ * Extensions should add their resource loader module definitions
+ * to the $wgResourceModules variable.
*
- * Example:
+ * @par Example:
+ * @code
* $wgResourceModules['ext.myExtension'] = array(
* 'scripts' => 'myExtension.js',
* 'styles' => 'myExtension.css',
* 'dependencies' => array( 'jquery.cookie', 'jquery.tabIndex' ),
- * 'localBasePath' => dirname( __FILE__ ),
+ * 'localBasePath' => __DIR__,
* 'remoteExtPath' => 'MyExtension',
* );
+ * @endcode
*/
$wgResourceModules = array();
@@ -2561,22 +2795,26 @@ $wgResourceModules = array();
* built-in source that is not in this array, but defined by
* ResourceLoader::__construct() so that it cannot be unset.
*
- * Example:
+ * @par Example:
+ * @code
* $wgResourceLoaderSources['foo'] = array(
* 'loadScript' => 'http://example.org/w/load.php',
* 'apiScript' => 'http://example.org/w/api.php'
* );
+ * @endcode
*/
$wgResourceLoaderSources = array();
/**
- * Default 'remoteBasePath' value for resource loader modules.
+ * Default 'remoteBasePath' value for instances of ResourceLoaderFileModule.
* If not set, then $wgScriptPath will be used as a fallback.
*/
$wgResourceBasePath = null;
/**
- * Maximum time in seconds to cache resources served by the resource loader
+ * Maximum time in seconds to cache resources served by the resource loader.
+ *
+ * @todo Document array structure
*/
$wgResourceLoaderMaxage = array(
'versioned' => array(
@@ -2592,8 +2830,9 @@ $wgResourceLoaderMaxage = array(
);
/**
- * The default debug mode (on/off) for of ResourceLoader requests. This will still
- * be overridden when the debug URL parameter is used.
+ * The default debug mode (on/off) for of ResourceLoader requests.
+ *
+ * This will still be overridden when the debug URL parameter is used.
*/
$wgResourceLoaderDebug = false;
@@ -2619,33 +2858,54 @@ $wgResourceLoaderMinifierMaxLineLength = 1000;
/**
* Whether to include the mediawiki.legacy JS library (old wikibits.js), and its
- * dependencies
+ * dependencies.
*/
$wgIncludeLegacyJavaScript = true;
/**
- * Whether to preload the mediawiki.util module as blocking module in the top queue.
- * Before MediaWiki 1.19, modules used to load slower/less asynchronous which allowed
- * modules to lack dependencies on 'popular' modules that were likely loaded already.
+ * Whether to preload the mediawiki.util module as blocking module in the top
+ * queue.
+ *
+ * Before MediaWiki 1.19, modules used to load slower/less asynchronous which
+ * allowed modules to lack dependencies on 'popular' modules that were likely
+ * loaded already.
+ *
* This setting is to aid scripts during migration by providing mediawiki.util
* unconditionally (which was the most commonly missed dependency).
- * It doesn't cover all missing dependencies obviously but should fix most of them.
+ * It doesn't cover all missing dependencies obviously but should fix most of
+ * them.
+ *
* This should be removed at some point after site/user scripts have been fixed.
- * Enable this if your wiki has a large amount of user/site scripts that are lacking
- * dependencies.
+ * Enable this if your wiki has a large amount of user/site scripts that are
+ * lacking dependencies.
+ * @todo Deprecate
*/
$wgPreloadJavaScriptMwUtil = false;
/**
- * Whether or not to assing configuration variables to the global window object.
- * If this is set to false, old code using deprecated variables like:
- * " if ( window.wgRestrictionEdit ) ..."
+ * Whether or not to assign configuration variables to the global window object.
+ *
+ * If this is set to false, old code using deprecated variables will no longer
+ * work.
+ *
+ * @par Example of legacy code:
+ * @code{,js}
+ * if ( window.wgRestrictionEdit ) { ... }
+ * @endcode
* or:
- * " if ( wgIsArticle ) ..."
- * will no longer work and needs to use mw.config instead. For example:
- * " if ( mw.config.exists('wgRestrictionEdit') )"
- * or
- * " if ( mw.config.get('wgIsArticle') )".
+ * @code{,js}
+ * if ( wgIsArticle ) { ... }
+ * @endcode
+ *
+ * Instead, one needs to use mw.config.
+ * @par Example using mw.config global configuration:
+ * @code{,js}
+ * if ( mw.config.exists('wgRestrictionEdit') ) { ... }
+ * @endcode
+ * or:
+ * @code{,js}
+ * if ( mw.config.get('wgIsArticle') ) { ... }
+ * @endcode
*/
$wgLegacyJavaScriptGlobals = true;
@@ -2663,8 +2923,8 @@ $wgLegacyJavaScriptGlobals = true;
$wgResourceLoaderMaxQueryLength = -1;
/**
- * If set to true, JavaScript modules loaded from wiki pages will be parsed prior
- * to minification to validate it.
+ * If set to true, JavaScript modules loaded from wiki pages will be parsed
+ * prior to minification to validate it.
*
* Parse errors will result in a JS exception being thrown during module load,
* which avoids breaking other modules loaded in the same request.
@@ -2682,7 +2942,7 @@ $wgResourceLoaderValidateJS = true;
$wgResourceLoaderValidateStaticJS = false;
/**
- * If set to true, asynchronous loading of bottom-queue scripts in the <head>
+ * If set to true, asynchronous loading of bottom-queue scripts in the "<head>"
* will be enabled. This is an experimental feature that's supposed to make
* JavaScript load faster.
*/
@@ -2718,19 +2978,25 @@ $wgMetaNamespaceTalk = false;
* names of existing namespaces. Extensions developers should use
* $wgCanonicalNamespaceNames.
*
- * PLEASE NOTE: Once you delete a namespace, the pages in that namespace will
+ * @warning Once you delete a namespace, the pages in that namespace will
* no longer be accessible. If you rename it, then you can access them through
* the new namespace name.
*
* Custom namespaces should start at 100 to avoid conflicting with standard
* namespaces, and should always follow the even/odd main/talk pattern.
+ *
+ * @par Example:
+ * @code
+ * $wgExtraNamespaces = array(
+ * 100 => "Hilfe",
+ * 101 => "Hilfe_Diskussion",
+ * 102 => "Aide",
+ * 103 => "Discussion_Aide"
+ * );
+ * @endcode
+ *
+ * @todo Add a note about maintenance/namespaceDupes.php
*/
-# $wgExtraNamespaces = array(
-# 100 => "Hilfe",
-# 101 => "Hilfe_Diskussion",
-# 102 => "Aide",
-# 103 => "Discussion_Aide"
-# );
$wgExtraNamespaces = array();
/**
@@ -2742,18 +3008,22 @@ $wgExtraNamespaces = array();
$wgExtraGenderNamespaces = array();
/**
- * Namespace aliases
+ * Namespace aliases.
+ *
* These are alternate names for the primary localised namespace names, which
* are defined by $wgExtraNamespaces and the language file. If a page is
* requested with such a prefix, the request will be redirected to the primary
* name.
*
* Set this to a map from namespace names to IDs.
- * Example:
+ *
+ * @par Example:
+ * @code
* $wgNamespaceAliases = array(
* 'Wikipedian' => NS_USER,
* 'Help' => 100,
* );
+ * @endcode
*/
$wgNamespaceAliases = array();
@@ -2768,8 +3038,8 @@ $wgNamespaceAliases = array();
* - + Enabled by default, but doesn't work with path to query rewrite rules, corrupted by apache
* - ? Enabled by default, but doesn't work with path to PATH_INFO rewrites
*
- * All three of these punctuation problems can be avoided by using an alias, instead of a
- * rewrite rule of either variety.
+ * All three of these punctuation problems can be avoided by using an alias,
+ * instead of a rewrite rule of either variety.
*
* The problem with % is that when using a path to query rewrite rule, URLs are
* double-unescaped: once by Apache's path conversion code, and again by PHP. So
@@ -2795,33 +3065,47 @@ $wgLocalInterwiki = false;
*/
$wgInterwikiExpiry = 10800;
-/** Interwiki caching settings.
- $wgInterwikiCache specifies path to constant database file
- This cdb database is generated by dumpInterwiki from maintenance
- and has such key formats:
- dbname:key - a simple key (e.g. enwiki:meta)
- _sitename:key - site-scope key (e.g. wiktionary:meta)
- __global:key - global-scope key (e.g. __global:meta)
- __sites:dbname - site mapping (e.g. __sites:enwiki)
- Sites mapping just specifies site name, other keys provide
- "local url" data layout.
- $wgInterwikiScopes specify number of domains to check for messages:
- 1 - Just wiki(db)-level
- 2 - wiki and global levels
- 3 - site levels
- $wgInterwikiFallbackSite - if unable to resolve from cache
+/**
+ * @name Interwiki caching settings.
+ * @{
+ */
+/**
+ *$wgInterwikiCache specifies path to constant database file.
+ *
+ * This cdb database is generated by dumpInterwiki from maintenance and has
+ * such key formats:
+ * - dbname:key - a simple key (e.g. enwiki:meta)
+ * - _sitename:key - site-scope key (e.g. wiktionary:meta)
+ * - __global:key - global-scope key (e.g. __global:meta)
+ * - __sites:dbname - site mapping (e.g. __sites:enwiki)
+ *
+ * Sites mapping just specifies site name, other keys provide "local url"
+ * data layout.
*/
$wgInterwikiCache = false;
+/**
+ * Specify number of domains to check for messages.
+ * - 1: Just wiki(db)-level
+ * - 2: wiki and global levels
+ * - 3: site levels
+ */
$wgInterwikiScopes = 3;
+/**
+ * $wgInterwikiFallbackSite - if unable to resolve from cache
+ */
$wgInterwikiFallbackSite = 'wiki';
+/** @} */ # end of Interwiki caching settings.
/**
* If local interwikis are set up which allow redirects,
* set this regexp to restrict URLs which will be displayed
* as 'redirected from' links.
*
+ * @par Example:
* It might look something like this:
+ * @code
* $wgRedirectSources = '!^https?://[a-z-]+\.wikipedia\.org/!';
+ * @endcode
*
* Leave at false to avoid displaying any incoming redirect markers.
* This does not affect intra-wiki redirects, which don't change
@@ -2831,7 +3115,8 @@ $wgRedirectSources = false;
/**
* Set this to false to avoid forcing the first letter of links to capitals.
- * WARNING: may break links! This makes links COMPLETELY case-sensitive. Links
+ *
+ * @warning may break links! This makes links COMPLETELY case-sensitive. Links
* appearing with a capital at the beginning of a sentence will *not* go to the
* same place as links in the middle of a sentence using a lowercase initial.
*/
@@ -2845,7 +3130,11 @@ $wgCapitalLinks = true;
* associated content namespaces, the values for those are ignored in favor of the
* subject namespace's setting. Setting for NS_MEDIA is taken automatically from
* NS_FILE.
- * EX: $wgCapitalLinkOverrides[ NS_FILE ] = false;
+ *
+ * @par Example:
+ * @code
+ * $wgCapitalLinkOverrides[ NS_FILE ] = false;
+ * @endcode
*/
$wgCapitalLinkOverrides = array();
@@ -2930,11 +3219,19 @@ $wgParserConf = array(
$wgMaxTocLevel = 999;
/**
- * A complexity limit on template expansion
+ * A complexity limit on template expansion: the maximum number of nodes visited
+ * by PPFrame::expand()
*/
$wgMaxPPNodeCount = 1000000;
/**
+ * A complexity limit on template expansion: the maximum number of nodes
+ * generated by Preprocessor::preprocessToObj()
+ */
+$wgMaxGeneratedPPNodeCount = 1000000;
+
+
+/**
* Maximum recursion depth for templates within templates.
* The current parser adds two levels to the PHP call stack for each template,
* and xdebug limits the call stack to 100 by default. So this should hopefully
@@ -2978,11 +3275,11 @@ $wgAllowExternalImages = false;
* You can use this to set up a trusted, simple repository of images.
* You may also specify an array of strings to allow multiple sites
*
- * Examples:
- * <code>
+ * @par Examples:
+ * @code
* $wgAllowExternalImagesFrom = 'http://127.0.0.1/';
* $wgAllowExternalImagesFrom = array( 'http://127.0.0.1/', 'http://example.com' );
- * </code>
+ * @endcode
*/
$wgAllowExternalImagesFrom = '';
@@ -2997,7 +3294,7 @@ $wgAllowExternalImagesFrom = '';
$wgEnableImageWhitelist = true;
/**
- * A different approach to the above: simply allow the <img> tag to be used.
+ * A different approach to the above: simply allow the "<img>" tag to be used.
* This allows you to specify alt text and other attributes, copy-paste HTML to
* your wiki more easily, etc. However, allowing external images in any manner
* will allow anyone with editing rights to snoop on your visitors' IP
@@ -3039,7 +3336,7 @@ $wgTidyInternal = extension_loaded( 'tidy' );
*/
$wgDebugTidy = false;
-/** Allow raw, unchecked HTML in <html>...</html> sections.
+/** Allow raw, unchecked HTML in "<html>...</html>" sections.
* THIS IS VERY DANGEROUS on a publicly editable site, so USE wgGroupPermissions
* TO RESTRICT EDITING to only those that you trust
*/
@@ -3245,7 +3542,6 @@ $wgDefaultUserOptions = array(
'gender' => 'unknown',
'hideminor' => 0,
'hidepatrolled' => 0,
- 'highlightbroken' => 1,
'imagesize' => 2,
'justify' => 0,
'math' => 1,
@@ -3308,7 +3604,7 @@ $wgInvalidUsernameCharacters = '@';
/**
* Character used as a delimiter when testing for interwiki userrights
* (In Special:UserRights, it is possible to modify users on different
- * databases if the delimiter is used, e.g. Someuser@enwiki).
+ * databases if the delimiter is used, e.g. "Someuser@enwiki").
*
* It is recommended that you have this delimiter in
* $wgInvalidUsernameCharacters above, or you will not be able to
@@ -3405,12 +3701,19 @@ $wgSysopEmailBans = true;
* Limits on the possible sizes of range blocks.
*
* CIDR notation is hard to understand, it's easy to mistakenly assume that a
- * /1 is a small range and a /31 is a large range. Setting this to half the
- * number of bits avoids such errors.
+ * /1 is a small range and a /31 is a large range. For IPv4, setting a limit of
+ * half the number of bits avoids such errors, and allows entire ISPs to be
+ * blocked using a small number of range blocks.
+ *
+ * For IPv6, RFC 3177 recommends that a /48 be allocated to every residential
+ * customer, so range blocks larger than /64 (half the number of bits) will
+ * plainly be required. RFC 4692 implies that a very large ISP may be
+ * allocated a /19 if a generous HD-Ratio of 0.8 is used, so we will use that
+ * as our limit. As of 2012, blocking the whole world would require a /4 range.
*/
$wgBlockCIDRLimit = array(
'IPv4' => 16, # Blocks larger than a /16 (64k addresses) will not be allowed
- 'IPv6' => 64, # 2^64 = ~1.8x10^19 addresses
+ 'IPv6' => 19,
);
/**
@@ -3423,18 +3726,19 @@ $wgBlockCIDRLimit = array(
$wgBlockDisablesLogin = false;
/**
- * Pages anonymous user may see as an array, e.g.
+ * Pages anonymous user may see, set as an array of pages titles.
*
- * <code>
+ * @par Example:
+ * @code
* $wgWhitelistRead = array ( "Main Page", "Wikipedia:Help");
- * </code>
+ * @endcode
*
* Special:Userlogin and Special:ChangePassword are always whitelisted.
*
- * NOTE: This will only work if $wgGroupPermissions['*']['read'] is false --
+ * @note This will only work if $wgGroupPermissions['*']['read'] is false --
* see below. Otherwise, ALL pages are accessible, regardless of this setting.
*
- * Also note that this will only protect _pages in the wiki_. Uploaded files
+ * @note Also that this will only protect _pages in the wiki_. Uploaded files
* will remain readable. You can use img_auth.php to protect uploaded files,
* see http://www.mediawiki.org/wiki/Manual:Image_Authorization
*/
@@ -3448,6 +3752,7 @@ $wgEmailConfirmToEdit = false;
/**
* Permission keys given to users in each group.
+ *
* This is an array where the keys are all groups and each value is an
* array of the format (right => boolean).
*
@@ -3538,7 +3843,6 @@ $wgGroupPermissions['sysop']['reupload'] = true;
$wgGroupPermissions['sysop']['reupload-shared'] = true;
$wgGroupPermissions['sysop']['unwatchedpages'] = true;
$wgGroupPermissions['sysop']['autoconfirmed'] = true;
-$wgGroupPermissions['sysop']['upload_by_url'] = true;
$wgGroupPermissions['sysop']['ipblock-exempt'] = true;
$wgGroupPermissions['sysop']['blockemail'] = true;
$wgGroupPermissions['sysop']['markbotedits'] = true;
@@ -3548,6 +3852,7 @@ $wgGroupPermissions['sysop']['noratelimit'] = true;
$wgGroupPermissions['sysop']['movefile'] = true;
$wgGroupPermissions['sysop']['unblockself'] = true;
$wgGroupPermissions['sysop']['suppressredirect'] = true;
+#$wgGroupPermissions['sysop']['upload_by_url'] = true;
#$wgGroupPermissions['sysop']['mergehistory'] = true;
// Permission to change users' group assignments
@@ -3558,6 +3863,7 @@ $wgGroupPermissions['bureaucrat']['noratelimit'] = true;
// Permission to export pages including linked pages regardless of $wgExportMaxLinkDepth
#$wgGroupPermissions['bureaucrat']['override-export-depth'] = true;
+#$wgGroupPermissions['sysop']['deletelogentry'] = true;
#$wgGroupPermissions['sysop']['deleterevision'] = true;
// To hide usernames from users and Sysops
#$wgGroupPermissions['suppress']['hideuser'] = true;
@@ -3578,6 +3884,7 @@ $wgGroupPermissions['bureaucrat']['noratelimit'] = true;
/**
* Permission keys revoked from users in each group.
+ *
* This acts the same way as wgGroupPermissions above, except that
* if the user is in a group here, the permission will be removed from them.
*
@@ -3595,16 +3902,20 @@ $wgImplicitGroups = array( '*', 'user', 'autoconfirmed' );
* A map of group names that the user is in, to group names that those users
* are allowed to add or revoke.
*
- * Setting the list of groups to add or revoke to true is equivalent to "any group".
- *
- * For example, to allow sysops to add themselves to the "bot" group:
+ * Setting the list of groups to add or revoke to true is equivalent to "any
+ * group".
*
+ * @par Example:
+ * To allow sysops to add themselves to the "bot" group:
+ * @code
* $wgGroupsAddToSelf = array( 'sysop' => array( 'bot' ) );
+ * @endcode
*
+ * @par Example:
* Implicit groups may be used for the source group, for instance:
- *
+ * @code
* $wgGroupsRemoveFromSelf = array( '*' => true );
- *
+ * @endcode
* This allows users in the '*' group (i.e. any user) to remove themselves from
* any group that they happen to be in.
*
@@ -3640,13 +3951,16 @@ $wgRestrictionLevels = array( '', 'autoconfirmed', 'sysop' );
* namespace. If you list more than one permission, a user must
* have all of them to edit pages in that namespace.
*
- * Note: NS_MEDIAWIKI is implicitly restricted to editinterface.
+ * @note NS_MEDIAWIKI is implicitly restricted to 'editinterface'.
*/
$wgNamespaceProtection = array();
/**
* Pages in namespaces in this array can not be used as templates.
- * Elements must be numeric namespace ids.
+ *
+ * Elements MUST be numeric namespace ids, you can safely use the MediaWiki
+ * namespaces constants (NS_USER, NS_MAIN...).
+ *
* Among other things, this may be useful to enforce read-restrictions
* which may otherwise be bypassed by using the template machanism.
*/
@@ -3662,11 +3976,15 @@ $wgNonincludableNamespaces = array();
*
* When left at 0, all registered accounts will pass.
*
- * Example:
- * <code>
+ * @par Example:
+ * Set automatic confirmation to 10 minutes (which is 600 seconds):
+ * @code
* $wgAutoConfirmAge = 600; // ten minutes
+ * @endcode
+ * Set age to one day:
+ * @code
* $wgAutoConfirmAge = 3600*24; // one day
- * </code>
+ * @endcode
*/
$wgAutoConfirmAge = 0;
@@ -3674,14 +3992,18 @@ $wgAutoConfirmAge = 0;
* Number of edits an account requires before it is autoconfirmed.
* Passing both this AND the time requirement is needed. Example:
*
- * <code>
+ * @par Example:
+ * @code
* $wgAutoConfirmCount = 50;
- * </code>
+ * @endcode
*/
$wgAutoConfirmCount = 0;
/**
* Automatically add a usergroup to any user who matches certain conditions.
+ *
+ * @todo Redocument $wgAutopromote
+ *
* The format is
* array( '&' or '|' or '^' or '!', cond1, cond2, ... )
* where cond1, cond2, ... are themselves conditions; *OR*
@@ -3709,14 +4031,19 @@ $wgAutopromote = array(
/**
* Automatically add a usergroup to any user who matches certain conditions.
+ *
* Does not add the user to the group again if it has been removed.
* Also, does not remove the group if the user no longer meets the criteria.
*
- * The format is
+ * The format is:
+ * @code
* array( event => criteria, ... )
- * where event is
- * 'onEdit' (when user edits) or 'onView' (when user views the wiki)
- * and criteria has the same format as $wgAutopromote
+ * @endcode
+ * Where event is either:
+ * - 'onEdit' (when user edits)
+ * - 'onView' (when user views the wiki)
+ *
+ * Criteria has the same format as $wgAutopromote
*
* @see $wgAutopromote
* @since 1.18
@@ -3734,16 +4061,23 @@ $wgAutopromoteOnceLogInRC = true;
/**
* $wgAddGroups and $wgRemoveGroups can be used to give finer control over who
- * can assign which groups at Special:Userrights. Example configuration:
+ * can assign which groups at Special:Userrights.
*
+ * @par Example:
+ * Bureaucrats can add any group:
* @code
- * // Bureaucrat can add any group
* $wgAddGroups['bureaucrat'] = true;
- * // Bureaucrats can only remove bots and sysops
+ * @endcode
+ * Bureaucrats can only remove bots and sysops:
+ * @code
* $wgRemoveGroups['bureaucrat'] = array( 'bot', 'sysop' );
- * // Sysops can make bots
+ * @endcode
+ * Sysops can make bots:
+ * @code
* $wgAddGroups['sysop'] = array( 'bot' );
- * // Sysops can disable other sysops in an emergency, and disable bots
+ * @endcode
+ * Sysops can disable other sysops in an emergency, and disable bots:
+ * @code
* $wgRemoveGroups['sysop'] = array( 'sysop', 'bot' );
* @endcode
*/
@@ -3763,8 +4097,10 @@ $wgAvailableRights = array();
*/
$wgDeleteRevisionsLimit = 0;
-/** Number of accounts each IP address may create, 0 to disable.
- * Requires memcached */
+/**
+ * Number of accounts each IP address may create, 0 to disable.
+ *
+ * @warning Requires memcached */
$wgAccountCreationThrottle = 0;
/**
@@ -3774,8 +4110,9 @@ $wgAccountCreationThrottle = 0;
* There's no administrator override on-wiki, so be careful what you set. :)
* May be an array of regexes or a single string for backwards compatibility.
*
- * See http://en.wikipedia.org/wiki/Regular_expression
- * Note that each regex needs a beginning/end delimiter, eg: # or /
+ * @see http://en.wikipedia.org/wiki/Regular_expression
+ *
+ * @note Each regex needs a beginning/end delimiter, eg: # or /
*/
$wgSpamRegex = array();
@@ -3783,54 +4120,46 @@ $wgSpamRegex = array();
$wgSummarySpamRegex = array();
/**
- * Similarly you can get a function to do the job. The function will be given
- * the following args:
- * - a Title object for the article the edit is made on
- * - the text submitted in the textarea (wpTextbox1)
- * - the section number.
- * The return should be boolean indicating whether the edit matched some evilness:
- * - true : block it
- * - false : let it through
- *
- * @deprecated since 1.17 Use hooks. See SpamBlacklist extension.
- * @var $wgFilterCallback bool|string|Closure
- */
-$wgFilterCallback = false;
-
-/**
- * Whether to use DNS blacklists in $wgDnsBlacklistUrls to check for open proxies
+ * Whether to use DNS blacklists in $wgDnsBlacklistUrls to check for open
+ * proxies
* @since 1.16
*/
$wgEnableDnsBlacklist = false;
/**
- * @deprecated since 1.17 Use $wgEnableDnsBlacklist instead, only kept for backward
- * compatibility
+ * @deprecated since 1.17 Use $wgEnableDnsBlacklist instead, only kept for
+ * backward compatibility.
*/
$wgEnableSorbs = false;
/**
- * List of DNS blacklists to use, if $wgEnableDnsBlacklist is true. This is an
- * array of either a URL or an array with the URL and a key (should the blacklist
- * require a key). For example:
+ * List of DNS blacklists to use, if $wgEnableDnsBlacklist is true.
+ *
+ * This is an array of either a URL or an array with the URL and a key (should
+ * the blacklist require a key).
+ *
+ * @par Example:
* @code
* $wgDnsBlacklistUrls = array(
* // String containing URL
- * 'http.dnsbl.sorbs.net',
+ * 'http.dnsbl.sorbs.net.',
* // Array with URL and key, for services that require a key
- * array( 'dnsbl.httpbl.net', 'mykey' ),
+ * array( 'dnsbl.httpbl.net.', 'mykey' ),
* // Array with just the URL. While this works, it is recommended that you
* // just use a string as shown above
- * array( 'opm.tornevall.org' )
+ * array( 'opm.tornevall.org.' )
* );
* @endcode
+ *
+ * @note You should end the domain name with a . to avoid searching your
+ * eventual domain search suffixes.
* @since 1.16
*/
$wgDnsBlacklistUrls = array( 'http.dnsbl.sorbs.net.' );
/**
- * @deprecated since 1.17 Use $wgDnsBlacklistUrls instead, only kept for backward
- * compatibility
+ * @deprecated since 1.17 Use $wgDnsBlacklistUrls instead, only kept for
+ * backward compatibility.
*/
$wgSorbsUrl = array();
@@ -3841,13 +4170,24 @@ $wgSorbsUrl = array();
$wgProxyWhitelist = array();
/**
- * Simple rate limiter options to brake edit floods. Maximum number actions
- * allowed in the given number of seconds; after that the violating client re-
- * ceives HTTP 500 error pages until the period elapses.
+ * Simple rate limiter options to brake edit floods.
+ *
+ * Maximum number actions allowed in the given number of seconds; after that
+ * the violating client receives HTTP 500 error pages until the period
+ * elapses.
+ *
+ * @par Example:
+ * To set a generic maximum of 4 hits in 60 seconds:
+ * @code
+ * $wgRateLimits = array( 4, 60 );
+ * @endcode
*
- * array( 4, 60 ) for a maximum of 4 hits in 60 seconds.
+ * You could also limit per action and then type of users. See the inline
+ * code for a template to use.
*
- * This option set is experimental and likely to change. Requires memcached.
+ * This option set is experimental and likely to change.
+ *
+ * @warning Requires memcached.
*/
$wgRateLimits = array(
'edit' => array(
@@ -3896,7 +4236,8 @@ $wgQueryPageDefaultLimit = 50;
/**
* Limit password attempts to X attempts per Y seconds per IP per account.
- * Requires memcached.
+ *
+ * @warning Requires memcached.
*/
$wgPasswordAttemptThrottle = array( 'count' => 5, 'seconds' => 300 );
@@ -3911,10 +4252,10 @@ $wgPasswordAttemptThrottle = array( 'count' => 5, 'seconds' => 300 );
* If you enable this, every editor's IP address will be scanned for open HTTP
* proxies.
*
- * Don't enable this. Many sysops will report "hostile TCP port scans" to your
- * ISP and ask for your server to be shut down.
- *
+ * @warning Don't enable this. Many sysops will report "hostile TCP port scans"
+ * to your ISP and ask for your server to be shut down.
* You have been warned.
+ *
*/
$wgBlockOpenProxies = false;
/** Port we want to scan for a proxy */
@@ -4048,22 +4389,29 @@ $wgDebugRedirects = false;
/**
* If true, log debugging data from action=raw and load.php.
- * This is normally false to avoid overlapping debug entries due to gen=css and
- * gen=js requests.
+ * This is normally false to avoid overlapping debug entries due to gen=css
+ * and gen=js requests.
*/
$wgDebugRawPage = false;
/**
* Send debug data to an HTML comment in the output.
*
- * This may occasionally be useful when supporting a non-technical end-user. It's
- * more secure than exposing the debug log file to the web, since the output only
- * contains private data for the current user. But it's not ideal for development
- * use since data is lost on fatal errors and redirects.
+ * This may occasionally be useful when supporting a non-technical end-user.
+ * It's more secure than exposing the debug log file to the web, since the
+ * output only contains private data for the current user. But it's not ideal
+ * for development use since data is lost on fatal errors and redirects.
*/
$wgDebugComments = false;
/**
+ * Extensive database transaction state debugging
+ *
+ * @since 1.20
+ */
+$wgDebugDBTransactions = false;
+
+/**
* Write SQL queries to the debug log
*/
$wgDebugDumpSql = false;
@@ -4120,11 +4468,23 @@ $wgShowExceptionDetails = false;
$wgShowDBErrorBacktrace = false;
/**
+ * If true, send the exception backtrace to the error log
+ */
+$wgLogExceptionBacktrace = true;
+
+/**
* Expose backend server host names through the API and various HTML comments
*/
$wgShowHostnames = false;
/**
+ * Override server hostname detection with a hardcoded value.
+ * Should be a string, default false.
+ * @since 1.20
+ */
+$wgOverrideHostname = false;
+
+/**
* If set to true MediaWiki will throw notices for some possible error
* conditions and for deprecated functions.
*/
@@ -4135,7 +4495,7 @@ $wgDevelopmentWarnings = false;
* development warnings will not be generated for deprecations added in releases
* after the limit.
*/
-$wgDeprecationReleaseLimit = '1.17';
+$wgDeprecationReleaseLimit = false;
/** Only record profiling info for pages that took longer than this */
$wgProfileLimit = 0.0;
@@ -4201,6 +4561,14 @@ $wgAggregateStatsID = false;
$wgDisableCounters = false;
/**
+ * Set this to an integer to only do synchronous site_stats updates
+ * one every *this many* updates. The other requests go into pending
+ * delta values in $wgMemc. Make sure that $wgMemc is a global cache.
+ * If set to -1, updates *only* go to $wgMemc (useful for daemons).
+ */
+$wgSiteStatsAsyncFactor = false;
+
+/**
* Parser test suite files to be run by parserTests.php when no specific
* filename is passed to it.
*
@@ -4228,7 +4596,7 @@ $wgParserTestFiles = array(
* );
*/
$wgParserTestRemote = false;
-
+
/**
* Allow running of javascript test suites via [[Special:JavaScriptTest]] (such as QUnit).
*/
@@ -4239,7 +4607,17 @@ $wgEnableJavaScriptTest = false;
*/
$wgJavaScriptTestConfig = array(
'qunit' => array(
+ // Page where documentation can be found relevant to the QUnit test suite being ran.
+ // Used in the intro paragraph on [[Special:JavaScriptTest/qunit]] for the
+ // documentation link in the "javascripttest-qunit-intro" message.
'documentation' => '//www.mediawiki.org/wiki/Manual:JavaScript_unit_testing',
+ // If you are submitting the QUnit test suite to a TestSwarm instance,
+ // point this to the "inject.js" script of that instance. This is was registers
+ // the QUnit hooks to extract the test results and push them back up into the
+ // TestSwarm database.
+ // @example 'http://localhost/testswarm/js/inject.js'
+ // @example '//integration.mediawiki.org/testswarm/js/inject.js'
+ 'testswarm-injectjs' => false,
),
);
@@ -4307,16 +4685,10 @@ $wgCountTotalSearchHits = false;
$wgOpenSearchTemplate = false;
/**
- * Enable suggestions while typing in search boxes
- * (results are passed around in OpenSearch format)
- * Requires $wgEnableOpenSearchSuggest = true;
- */
-$wgEnableMWSuggest = false;
-
-/**
* Enable OpenSearch suggestions requested by MediaWiki. Set this to
- * false if you've disabled MWSuggest or another suggestion script and
- * want reduce load caused by cached scripts pulling suggestions.
+ * false if you've disabled scripts that use api?action=opensearch and
+ * want reduce load caused by cached scripts still pulling suggestions.
+ * It will let the API fallback by responding with an empty array.
*/
$wgEnableOpenSearchSuggest = true;
@@ -4326,26 +4698,19 @@ $wgEnableOpenSearchSuggest = true;
$wgSearchSuggestCacheExpiry = 1200;
/**
- * Template for internal MediaWiki suggestion engine, defaults to API action=opensearch
- *
- * Placeholders: {searchTerms}, {namespaces}, {dbname}
- *
- */
-$wgMWSuggestTemplate = false;
-
-/**
* If you've disabled search semi-permanently, this also disables updates to the
* table. If you ever re-enable, be sure to rebuild the search table.
*/
$wgDisableSearchUpdate = false;
/**
- * List of namespaces which are searched by default. Example:
+ * List of namespaces which are searched by default.
*
- * <code>
+ * @par Example:
+ * @code
* $wgNamespacesToBeSearchedDefault[NS_MAIN] = true;
* $wgNamespacesToBeSearchedDefault[NS_PROJECT] = true;
- * </code>
+ * @endcode
*/
$wgNamespacesToBeSearchedDefault = array(
NS_MAIN => true,
@@ -4353,9 +4718,9 @@ $wgNamespacesToBeSearchedDefault = array(
/**
* Namespaces to be searched when user clicks the "Help" tab
- * on Special:Search
+ * on Special:Search.
*
- * Same format as $wgNamespacesToBeSearchedDefault
+ * Same format as $wgNamespacesToBeSearchedDefault.
*/
$wgNamespacesToBeSearchedHelp = array(
NS_PROJECT => true,
@@ -4363,8 +4728,10 @@ $wgNamespacesToBeSearchedHelp = array(
);
/**
- * If set to true the 'searcheverything' preference will be effective only for logged-in users.
- * Useful for big wikis to maintain different search profiles for anonymous and logged-in users.
+ * If set to true the 'searcheverything' preference will be effective only for
+ * logged-in users.
+ * Useful for big wikis to maintain different search profiles for anonymous and
+ * logged-in users.
*
*/
$wgSearchEverythingOnlyLoggedIn = false;
@@ -4380,18 +4747,22 @@ $wgDisableInternalSearch = false;
* If the URL includes '$1', this will be replaced with the URL-encoded
* search term.
*
- * For example, to forward to Google you'd have something like:
- * $wgSearchForwardUrl = 'http://www.google.com/search?q=$1' .
- * '&domains=http://example.com' .
- * '&sitesearch=http://example.com' .
- * '&ie=utf-8&oe=utf-8';
+ * @par Example:
+ * To forward to Google you'd have something like:
+ * @code
+ * $wgSearchForwardUrl =
+ * 'http://www.google.com/search?q=$1' .
+ * '&domains=http://example.com' .
+ * '&sitesearch=http://example.com' .
+ * '&ie=utf-8&oe=utf-8';
+ * @endcode
*/
$wgSearchForwardUrl = null;
/**
- * Search form behavior
- * true = use Go & Search buttons
- * false = use Go button & Advanced search link
+ * Search form behavior.
+ * - true = use Go & Search buttons
+ * - false = use Go button & Advanced search link
*/
$wgUseTwoButtonsSearchForm = true;
@@ -4408,11 +4779,13 @@ $wgSitemapNamespaces = false;
* maintenance/generateSitemap.php script.
*
* This should be a map of namespace IDs to priority
- * Example:
+ * @par Example:
+ * @code
* $wgSitemapNamespacesPriorities = array(
* NS_USER => '0.9',
* NS_HELP => '0.0',
* );
+ * @endcode
*/
$wgSitemapNamespacesPriorities = false;
@@ -4530,6 +4903,22 @@ $wgReadOnlyFile = false;
*/
$wgUpgradeKey = false;
+/**
+ * Map GIT repository URLs to viewer URLs to provide links in Special:Version
+ *
+ * Key is a pattern passed to preg_match() and preg_replace(),
+ * without the delimiters (which are #) and must match the whole URL.
+ * The value is the replacement for the key (it can contain $1, etc.)
+ * %h will be replaced by the short SHA-1 (7 first chars) and %H by the
+ * full SHA-1 of the HEAD revision.
+ *
+ * @since 1.20
+ */
+$wgGitRepositoryViewers = array(
+ 'https://gerrit.wikimedia.org/r/p/(.*)' => 'https://gerrit.wikimedia.org/r/gitweb?p=$1;h=%H',
+ 'ssh://(?:[a-z0-9_]+@)?gerrit.wikimedia.org:29418/(.*)' => 'https://gerrit.wikimedia.org/r/gitweb?p=$1;h=%H',
+);
+
/** @} */ # End of maintenance }
/************************************************************************//**
@@ -4627,18 +5016,23 @@ $wgFeedDiffCutoff = 32768;
/** Override the site's default RSS/ATOM feed for recentchanges that appears on
* every page. Some sites might have a different feed they'd like to promote
* instead of the RC feed (maybe like a "Recent New Articles" or "Breaking news" one).
- * Ex: $wgSiteFeed['format'] = "http://example.com/somefeed.xml"; Format can be one
- * of either 'rss' or 'atom'.
+ * Should be a format as key (either 'rss' or 'atom') and an URL to the feed
+ * as value.
+ * @par Example:
+ * Configure the 'atom' feed to http://example.com/somefeed.xml
+ * @code
+ * $wgSiteFeed['atom'] = "http://example.com/somefeed.xml";
+ * @endcode
*/
$wgOverrideSiteFeed = array();
/**
- * Available feeds objects
+ * Available feeds objects.
* Should probably only be defined when a page is syndicated ie when
- * $wgOut->isSyndicated() is true
+ * $wgOut->isSyndicated() is true.
*/
$wgFeedClasses = array(
- 'rss' => 'RSSFeed',
+ 'rss' => 'RSSFeed',
'atom' => 'AtomFeed',
);
@@ -4797,9 +5191,9 @@ $wgExportAllowListContributors = false;
* can become *insanely large* and could easily break your wiki,
* it's disabled by default for now.
*
- * There's a HARD CODED limit of 5 levels of recursion to prevent a
- * crazy-big export from being done by someone setting the depth
- * number too high. In other words, last resort safety net.
+ * @warning There's a HARD CODED limit of 5 levels of recursion to prevent a
+ * crazy-big export from being done by someone setting the depth number too
+ * high. In other words, last resort safety net.
*/
$wgExportMaxLinkDepth = 0;
@@ -4821,7 +5215,8 @@ $wgExportAllowAll = false;
*/
/**
- * A list of callback functions which are called once MediaWiki is fully initialised
+ * A list of callback functions which are called once MediaWiki is fully
+ * initialised
*/
$wgExtensionFunctions = array();
@@ -4836,9 +5231,10 @@ $wgExtensionFunctions = array();
* Variables defined in extensions will override conflicting variables defined
* in the core.
*
- * Example:
- * $wgExtensionMessagesFiles['ConfirmEdit'] = dirname(__FILE__).'/ConfirmEdit.i18n.php';
- *
+ * @par Example:
+ * @code
+ * $wgExtensionMessagesFiles['ConfirmEdit'] = __DIR__.'/ConfirmEdit.i18n.php';
+ * @endcode
*/
$wgExtensionMessagesFiles = array();
@@ -4852,7 +5248,9 @@ $wgExtensionMessagesFiles = array();
* Registration is done with $pout->addOutputHook( $tag, $data ).
*
* The callback has the form:
+ * @code
* function outputHook( $outputPage, $parserOutput, $data ) { ... }
+ * @endcode
*/
$wgParserOutputHooks = array();
@@ -4883,7 +5281,7 @@ $wgAutoloadClasses = array();
* urls, descriptions and pointers to localized description msgs. Note that
* the version, url, description and descriptionmsg key can be omitted.
*
- * <code>
+ * @code
* $wgExtensionCredits[$type][] = array(
* 'name' => 'Example extension',
* 'version' => 1.9,
@@ -4893,7 +5291,7 @@ $wgAutoloadClasses = array();
* 'description' => 'An example extension',
* 'descriptionmsg' => 'exampleextension-desc',
* );
- * </code>
+ * @endcode
*
* Where $type is 'specialpage', 'parserhook', 'variable', 'media' or 'other'.
* Where 'descriptionmsg' can be an array with message key and parameters:
@@ -4909,12 +5307,30 @@ $wgAuth = null;
/**
* Global list of hooks.
- * Add a hook by doing:
+ *
+ * The key is one of the events made available by MediaWiki, you can find
+ * a description for most of them in docs/hooks.txt. The array is used
+ * internally by Hook:run().
+ *
+ * The value can be one of:
+ *
+ * - A function name:
+ * @code
* $wgHooks['event_name'][] = $function;
- * or:
+ * @endcode
+ * - A function with some data:
+ * @code
* $wgHooks['event_name'][] = array($function, $data);
- * or:
+ * @endcode
+ * - A an object method:
+ * @code
* $wgHooks['event_name'][] = array($object, 'method');
+ * @endcode
+ *
+ * @warning You should always append to an event array or you will end up
+ * deleting a previous registered hook.
+ *
+ * @todo Does it support PHP closures?
*/
$wgHooks = array();
@@ -5068,17 +5484,19 @@ $wgLogRestrictions = array(
*
* See $wgLogTypes for a list of available log types.
*
- * For example:
+ * @par Example:
+ * @code
* $wgFilterLogTypes => array(
* 'move' => true,
* 'import' => false,
* );
+ * @endcode
*
* Will display show/hide links for the move and import logs. Move logs will be
* hidden by default unless the link is clicked. Import logs will be shown by
* default, and hidden when the link is clicked.
*
- * A message of the form log-show-hide-<type> should be added, and will be used
+ * A message of the form log-show-hide-[type] should be added, and will be used
* for the link text.
*/
$wgFilterLogTypes = array(
@@ -5091,7 +5509,7 @@ $wgFilterLogTypes = array(
*
* Extensions with custom log types may add to this array.
*
- * Since 1.19, if you follow the naming convention log-name-TYPE,
+ * @since 1.19, if you follow the naming convention log-name-TYPE,
* where TYPE is your log type, yoy don't need to use this array.
*/
$wgLogNames = array(
@@ -5114,7 +5532,7 @@ $wgLogNames = array(
*
* Extensions with custom log types may add to this array.
*
- * Since 1.19, if you follow the naming convention log-description-TYPE,
+ * @since 1.19, if you follow the naming convention log-description-TYPE,
* where TYPE is your log type, yoy don't need to use this array.
*/
$wgLogHeaders = array(
@@ -5164,10 +5582,12 @@ $wgLogActions = array(
* @see LogFormatter
*/
$wgLogActionsHandlers = array(
- // move, move_redir
- 'move/*' => 'MoveLogFormatter',
- // delete, restore, revision, event
- 'delete/*' => 'DeleteLogFormatter',
+ 'move/move' => 'MoveLogFormatter',
+ 'move/move_redir' => 'MoveLogFormatter',
+ 'delete/delete' => 'DeleteLogFormatter',
+ 'delete/restore' => 'DeleteLogFormatter',
+ 'delete/revision' => 'DeleteLogFormatter',
+ 'delete/event' => 'DeleteLogFormatter',
'suppress/revision' => 'DeleteLogFormatter',
'suppress/event' => 'DeleteLogFormatter',
'suppress/delete' => 'DeleteLogFormatter',
@@ -5266,6 +5686,7 @@ $wgSpecialPageGroups = array(
'Mostlinkedtemplates' => 'highuse',
'Mostcategories' => 'highuse',
'Mostimages' => 'highuse',
+ 'Mostinterwikis' => 'highuse',
'Mostrevisions' => 'highuse',
'Allpages' => 'pages',
@@ -5328,7 +5749,7 @@ $wgMaxRedirectLinksRetrieved = 500;
*/
/**
- * Array of allowed values for the title=foo&action=<action> parameter. Syntax is:
+ * Array of allowed values for the "title=foo&action=<action>" parameter. Syntax is:
* 'foo' => 'ClassName' Load the specified class which subclasses Action
* 'foo' => true Load the class FooAction which subclasses Action
* If something is specified in the getActionOverrides()
@@ -5364,11 +5785,6 @@ $wgActions = array(
*/
$wgDisabledActions = array();
-/**
- * Allow the "info" action, very inefficient at the moment
- */
-$wgAllowPageInfo = false;
-
/** @} */ # end actions }
/*************************************************************************//**
@@ -5393,8 +5809,10 @@ $wgDefaultRobotPolicy = 'index,follow';
* URLs, so search engine spiders risk getting lost in a maze of twisty special
* pages, all alike, and never reaching your actual content.
*
- * Example:
+ * @par Example:
+ * @code
* $wgNamespaceRobotPolicies = array( NS_TALK => 'noindex' );
+ * @endcode
*/
$wgNamespaceRobotPolicies = array();
@@ -5402,10 +5820,18 @@ $wgNamespaceRobotPolicies = array();
* Robot policies per article. These override the per-namespace robot policies.
* Must be in the form of an array where the key part is a properly canonical-
* ised text form title and the value is a robot policy.
- * Example:
- * $wgArticleRobotPolicies = array( 'Main Page' => 'noindex,follow',
- * 'User:Bob' => 'index,follow' );
- * Example that DOES NOT WORK because the names are not canonical text forms:
+ *
+ * @par Example:
+ * @code
+ * $wgArticleRobotPolicies = array(
+ * 'Main Page' => 'noindex,follow',
+ * 'User:Bob' => 'index,follow',
+ * );
+ * @endcode
+ *
+ * @par Example that DOES NOT WORK because the names are not canonical text
+ * forms:
+ * @code
* $wgArticleRobotPolicies = array(
* # Underscore, not space!
* 'Main_Page' => 'noindex,follow',
@@ -5414,6 +5840,7 @@ $wgNamespaceRobotPolicies = array();
* # Needs to be "Abc", not "abc" (unless $wgCapitalLinks is false for that namespace)!
* 'abc' => 'noindex,nofollow'
* );
+ * @endcode
*/
$wgArticleRobotPolicies = array();
@@ -5421,8 +5848,11 @@ $wgArticleRobotPolicies = array();
* An array of namespace keys in which the __INDEX__/__NOINDEX__ magic words
* will not function, so users can't decide whether pages in that namespace are
* indexed by search engines. If set to null, default to $wgContentNamespaces.
- * Example:
+ *
+ * @par Example:
+ * @code
* $wgExemptFromUserRobotsControl = array( NS_MAIN, NS_TALK, NS_PROJECT );
+ * @endcode
*/
$wgExemptFromUserRobotsControl = null;
@@ -5452,9 +5882,10 @@ $wgEnableAPI = true;
$wgEnableWriteAPI = true;
/**
- * API module extensions
+ * API module extensions.
* Associative array mapping module name to class name.
* Extension modules may override the core modules.
+ * @todo Describe each of the variables, group them and add examples
*/
$wgAPIModules = array();
$wgAPIMetaModules = array();
@@ -5469,7 +5900,7 @@ $wgAPIMaxDBRows = 5000;
/**
* The maximum size (in bytes) of an API result.
- * Don't set this lower than $wgMaxArticleSize*1024
+ * @warning Do not set this lower than $wgMaxArticleSize*1024
*/
$wgAPIMaxResultSize = 8388608;
@@ -5524,17 +5955,18 @@ $wgAjaxLicensePreview = true;
* This is currently only used by the API (requests to api.php)
* $wgCrossSiteAJAXdomains can be set using a wildcard syntax:
*
- * '*' matches any number of characters
- * '?' matches any 1 character
- *
- * Example:
- $wgCrossSiteAJAXdomains = array(
- 'www.mediawiki.org',
- '*.wikipedia.org',
- '*.wikimedia.org',
- '*.wiktionary.org',
- );
+ * - '*' matches any number of characters
+ * - '?' matches any 1 character
*
+ * @par Example:
+ * @code
+ * $wgCrossSiteAJAXdomains = array(
+ * 'www.mediawiki.org',
+ * '*.wikipedia.org',
+ * '*.wikimedia.org',
+ * '*.wiktionary.org',
+ * );
+ * @endcode
*/
$wgCrossSiteAJAXdomains = array();
@@ -5638,7 +6070,7 @@ $wgUpdateRowsPerQuery = 100;
/**
* The build directory for HipHop compilation.
- * Defaults to $IP/maintenance/hiphop/build.
+ * Defaults to '$IP/maintenance/hiphop/build'.
*/
$wgHipHopBuildDirectory = false;
@@ -5658,8 +6090,9 @@ $wgHipHopCompilerProcs = 'detect';
*
* To compile extensions with HipHop, set $wgExtensionsDirectory correctly,
* and use code like:
- *
+ * @code
* require( MWInit::extensionSetupPath( 'Extension/Extension.php' ) );
+ * @endcode
*
* to include the extension setup file from LocalSettings.php. It is not
* necessary to set this variable unless you use MWInit::extensionSetupPath().
@@ -5682,6 +6115,19 @@ $wgCompiledFiles = array();
/************************************************************************//**
+ * @name Mobile support
+ * @{
+ */
+
+/**
+ * Name of the class used for mobile device detection, must be inherited from
+ * IDeviceDetector.
+ */
+$wgDeviceDetectionClass = 'DeviceDetection';
+
+/** @} */ # End of Mobile support }
+
+/************************************************************************//**
* @name Miscellaneous
* @{
*/
@@ -5691,9 +6137,11 @@ $wgExternalDiffEngine = false;
/**
* Disable redirects to special pages and interwiki redirects, which use a 302
- * and have no "redirected from" link. Note this is only for articles with #Redirect
- * in them. URL's containing a local interwiki prefix (or a non-canonical special
- * page name) are still hard redirected regardless of this setting.
+ * and have no "redirected from" link.
+ *
+ * @note This is only for articles with #REDIRECT in them. URL's containing a
+ * local interwiki prefix (or a non-canonical special page name) are still hard
+ * redirected regardless of this setting.
*/
$wgDisableHardRedirects = false;
@@ -5704,8 +6152,8 @@ $wgDisableHardRedirects = false;
$wgLinkHolderBatchSize = 1000;
/**
- * By default MediaWiki does not register links pointing to same server in externallinks dataset,
- * use this value to override:
+ * By default MediaWiki does not register links pointing to same server in
+ * externallinks dataset, use this value to override:
*/
$wgRegisterInternalExternals = false;
@@ -5733,8 +6181,10 @@ $wgRedirectOnLogin = null;
* This configuration array maps pool types to an associative array. The only
* defined key in the associative array is "class", which gives the class name.
* The remaining elements are passed through to the class as constructor
- * parameters. Example:
+ * parameters.
*
+ * @par Example:
+ * @code
* $wgPoolCounterConf = array( 'ArticleView' => array(
* 'class' => 'PoolCounter_Client',
* 'timeout' => 15, // wait timeout in seconds
@@ -5742,6 +6192,7 @@ $wgRedirectOnLogin = null;
* 'maxqueue' => 50, // maximum number of total threads in each pool
* ... any extension-specific options...
* );
+ * @endcode
*/
$wgPoolCounterConf = null;
@@ -5760,6 +6211,13 @@ $wgDBtestuser = ''; //db user that has permission to create and drop the test da
$wgDBtestpassword = '';
/**
+ * Whether the user must enter their password to change their e-mail address
+ *
+ * @since 1.20
+ */
+$wgRequirePasswordforEmailChange = true;
+
+/**
* For really cool vim folding this needs to be at the end:
* vim: foldmarker=@{,@} foldmethod=marker
* @}
diff --git a/includes/DeferredUpdates.php b/includes/DeferredUpdates.php
index 262994e3..b4989a69 100644
--- a/includes/DeferredUpdates.php
+++ b/includes/DeferredUpdates.php
@@ -1,5 +1,26 @@
<?php
/**
+ * Interface and manager for deferred updates.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ * @file
+ */
+
+/**
* Interface that deferrable updates should implement. Basically required so we
* can validate input on DeferredUpdates::addUpdate()
*
@@ -67,10 +88,19 @@ class DeferredUpdates {
}
foreach ( $updates as $update ) {
- $update->doUpdate();
+ try {
+ $update->doUpdate();
- if ( $doCommit && $dbw->trxLevel() ) {
- $dbw->commit( __METHOD__ );
+ if ( $doCommit && $dbw->trxLevel() ) {
+ $dbw->commit( __METHOD__ );
+ }
+ } catch ( MWException $e ) {
+ // We don't want exceptions thrown during deferred updates to
+ // be reported to the user since the output is already sent.
+ // Instead we just log them.
+ if ( !$e instanceof ErrorPageError ) {
+ wfDebugLog( 'exception', $e->getLogMessage() );
+ }
}
}
diff --git a/includes/Defines.php b/includes/Defines.php
index 26deb2ba..be9f9816 100644
--- a/includes/Defines.php
+++ b/includes/Defines.php
@@ -6,10 +6,29 @@
* since this file will not be executed during request startup for a compiled
* MediaWiki.
*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
* @file
*/
/**
+ * @defgroup Constants MediaWiki constants
+ */
+
+/**
* Version constants for the benefit of extensions
*/
define( 'MW_SPECIALPAGE_VERSION', 2 );
@@ -25,6 +44,8 @@ define( 'DBO_DEFAULT', 16 );
define( 'DBO_PERSISTENT', 32 );
define( 'DBO_SYSDBA', 64 ); //for oracle maintenance
define( 'DBO_DDLMODE', 128 ); // when using schema files: mostly for Oracle
+define( 'DBO_SSL', 256 );
+define( 'DBO_COMPRESS', 512 );
/**@}*/
/**@{
@@ -125,8 +146,8 @@ define( 'AV_SCAN_FAILED', false ); #scan failed (scanner not found or error in
* Anti-lock flags
* See DefaultSettings.php for a description
*/
-define( 'ALF_PRELOAD_LINKS', 1 );
-define( 'ALF_PRELOAD_EXISTENCE', 2 );
+define( 'ALF_PRELOAD_LINKS', 1 ); // unused
+define( 'ALF_PRELOAD_EXISTENCE', 2 ); // unused
define( 'ALF_NO_LINK_LOCK', 4 );
define( 'ALF_NO_BLOCK_LOCK', 8 );
/**@}*/
@@ -184,7 +205,7 @@ define( 'LIST_SET_PREPARED', 8); // List of (?, ?, ?) for DatabaseIbm_db2
/**
* Unicode and normalisation related
*/
-require_once dirname(__FILE__).'/normal/UtfNormalDefines.php';
+require_once __DIR__.'/normal/UtfNormalDefines.php';
/**@{
* Hook support constants
diff --git a/includes/DeprecatedGlobal.php b/includes/DeprecatedGlobal.php
new file mode 100644
index 00000000..4d7b9689
--- /dev/null
+++ b/includes/DeprecatedGlobal.php
@@ -0,0 +1,55 @@
+<?php
+/**
+ * Delayed loading of deprecated global objects.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ * @file
+ */
+
+/**
+ * Class to allow throwing wfDeprecated warnings
+ * when people use globals that we do not want them to.
+ * (For example like $wgArticle)
+ */
+
+class DeprecatedGlobal extends StubObject {
+ // The m's are to stay consistent with parent class.
+ protected $mRealValue, $mVersion;
+
+ function __construct( $name, $realValue, $version = false ) {
+ parent::__construct( $name );
+ $this->mRealValue = $realValue;
+ $this->mVersion = $version;
+ }
+
+ function _newObject() {
+ /* Put the caller offset for wfDeprecated as 6, as
+ * that gives the function that uses this object, since:
+ * 1 = this function ( _newObject )
+ * 2 = StubObject::_unstub
+ * 3 = StubObject::_call
+ * 4 = StubObject::__call
+ * 5 = DeprecatedGlobal::<method of global called>
+ * 6 = Actual function using the global.
+ * Of course its theoretically possible to have other call
+ * sequences for this method, but that seems to be
+ * rather unlikely.
+ */
+ wfDeprecated( '$' . $this->mGlobal, $this->mVersion, false, 6 );
+ return $this->mRealValue;
+ }
+}
diff --git a/includes/EditPage.php b/includes/EditPage.php
index d00d9114..b762cad1 100644
--- a/includes/EditPage.php
+++ b/includes/EditPage.php
@@ -1,6 +1,22 @@
<?php
/**
- * Contains the EditPage class
+ * Page edition user interface.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
* @file
*/
@@ -37,11 +53,6 @@ class EditPage {
const AS_HOOK_ERROR = 210;
/**
- * Status: The filter function set in $wgFilterCallback returned true (= block it)
- */
- const AS_FILTERING = 211;
-
- /**
* Status: A hook function returned an error
*/
const AS_HOOK_ERROR_EXPECTED = 212;
@@ -145,6 +156,11 @@ class EditPage {
const AS_IMAGE_REDIRECT_LOGGED = 234;
/**
+ * HTML id and name for the beginning of the edit form.
+ */
+ const EDITFORM_ID = 'editform';
+
+ /**
* @var Article
*/
var $mArticle;
@@ -183,6 +199,12 @@ class EditPage {
*/
var $mParserOutput;
+ /**
+ * Has a summary been preset using GET parameter &summary= ?
+ * @var Bool
+ */
+ var $hasPresetSummary = false;
+
var $mBaseRevision = false;
var $mShowSummaryField = true;
@@ -282,7 +304,7 @@ class EditPage {
}
wfProfileIn( __METHOD__ );
- wfDebug( __METHOD__.": enter\n" );
+ wfDebug( __METHOD__ . ": enter\n" );
// If they used redlink=1 and the page exists, redirect to the main article
if ( $wgRequest->getBool( 'redlink' ) && $this->mTitle->exists() ) {
@@ -333,7 +355,7 @@ class EditPage {
return;
}
- wfProfileIn( __METHOD__."-business-end" );
+ wfProfileIn( __METHOD__ . "-business-end" );
$this->isConflict = false;
// css / js subpages of user pages get a special treatment
@@ -355,7 +377,7 @@ class EditPage {
if ( 'save' == $this->formtype ) {
if ( !$this->attemptSave() ) {
- wfProfileOut( __METHOD__."-business-end" );
+ wfProfileOut( __METHOD__ . "-business-end" );
wfProfileOut( __METHOD__ );
return;
}
@@ -366,18 +388,18 @@ class EditPage {
if ( 'initial' == $this->formtype || $this->firsttime ) {
if ( $this->initialiseForm() === false ) {
$this->noSuchSectionPage();
- wfProfileOut( __METHOD__."-business-end" );
+ wfProfileOut( __METHOD__ . "-business-end" );
wfProfileOut( __METHOD__ );
return;
}
- if ( !$this->mTitle->getArticleId() )
+ if ( !$this->mTitle->getArticleID() )
wfRunHooks( 'EditFormPreloadText', array( &$this->textbox1, &$this->mTitle ) );
else
wfRunHooks( 'EditFormInitialText', array( $this ) );
}
$this->showEditForm();
- wfProfileOut( __METHOD__."-business-end" );
+ wfProfileOut( __METHOD__ . "-business-end" );
wfProfileOut( __METHOD__ );
}
@@ -394,7 +416,7 @@ class EditPage {
}
# Ignore some permissions errors when a user is just previewing/viewing diffs
$remove = array();
- foreach( $permErrors as $error ) {
+ foreach ( $permErrors as $error ) {
if ( ( $this->preview || $this->diff ) &&
( $error[0] == 'blockedtext' || $error[0] == 'autoblockedtext' ) )
{
@@ -469,7 +491,7 @@ class EditPage {
*/
function readOnlyPage( $source = null, $protected = false, $reasons = array(), $action = null ) {
wfDeprecated( __METHOD__, '1.19' );
-
+
global $wgRequest, $wgOut;
if ( $wgRequest->getBool( 'redlink' ) ) {
// The edit page was reached via a red link.
@@ -501,7 +523,7 @@ class EditPage {
// Standard preference behaviour
return true;
} elseif ( !$this->mTitle->exists() &&
- isset($wgPreviewOnOpenNamespaces[$this->mTitle->getNamespace()]) &&
+ isset( $wgPreviewOnOpenNamespaces[$this->mTitle->getNamespace()] ) &&
$wgPreviewOnOpenNamespaces[$this->mTitle->getNamespace()] )
{
// Categories are special
@@ -518,7 +540,7 @@ class EditPage {
* @return bool
*/
protected function isWrongCaseCssJsPage() {
- if( $this->mTitle->isCssJsSubpage() ) {
+ if ( $this->mTitle->isCssJsSubpage() ) {
$name = $this->mTitle->getSkinFromCssJsSubpage();
$skins = array_merge(
array_keys( Skin::getSkinNames() ),
@@ -558,31 +580,31 @@ class EditPage {
# Also remove trailing whitespace, but don't remove _initial_
# whitespace from the text boxes. This may be significant formatting.
$this->textbox1 = $this->safeUnicodeInput( $request, 'wpTextbox1' );
- if ( !$request->getCheck('wpTextbox2') ) {
+ if ( !$request->getCheck( 'wpTextbox2' ) ) {
// Skip this if wpTextbox2 has input, it indicates that we came
// from a conflict page with raw page text, not a custom form
// modified by subclasses
- wfProfileIn( get_class($this)."::importContentFormData" );
+ wfProfileIn( get_class( $this ) . "::importContentFormData" );
$textbox1 = $this->importContentFormData( $request );
- if ( isset($textbox1) )
+ if ( isset( $textbox1 ) )
$this->textbox1 = $textbox1;
- wfProfileOut( get_class($this)."::importContentFormData" );
+ wfProfileOut( get_class( $this ) . "::importContentFormData" );
}
- # Truncate for whole multibyte characters. +5 bytes for ellipsis
- $this->summary = $wgLang->truncate( $request->getText( 'wpSummary' ), 250 );
+ # Truncate for whole multibyte characters
+ $this->summary = $wgLang->truncate( $request->getText( 'wpSummary' ), 255 );
# If the summary consists of a heading, e.g. '==Foobar==', extract the title from the
# header syntax, e.g. 'Foobar'. This is mainly an issue when we are using wpSummary for
# section titles.
$this->summary = preg_replace( '/^\s*=+\s*(.*?)\s*=+\s*$/', '$1', $this->summary );
-
+
# Treat sectiontitle the same way as summary.
# Note that wpSectionTitle is not yet a part of the actual edit form, as wpSummary is
# currently doing double duty as both edit summary and section title. Right now this
# is just to allow API edits to work around this limitation, but this should be
# incorporated into the actual edit form when EditPage is rewritten (Bugs 18654, 26312).
- $this->sectiontitle = $wgLang->truncate( $request->getText( 'wpSectionTitle' ), 250 );
+ $this->sectiontitle = $wgLang->truncate( $request->getText( 'wpSectionTitle' ), 255 );
$this->sectiontitle = preg_replace( '/^\s*=+\s*(.*?)\s*=+\s*$/', '$1', $this->sectiontitle );
$this->edittime = $request->getVal( 'wpEdittime' );
@@ -650,7 +672,7 @@ class EditPage {
{
$this->allowBlankSummary = true;
} else {
- $this->allowBlankSummary = $request->getBool( 'wpIgnoreBlankSummary' ) || !$wgUser->getOption( 'forceeditsummary');
+ $this->allowBlankSummary = $request->getBool( 'wpIgnoreBlankSummary' ) || !$wgUser->getOption( 'forceeditsummary' );
}
$this->autoSumm = $request->getText( 'wpAutoSummary' );
@@ -669,7 +691,7 @@ class EditPage {
$this->minoredit = false;
$this->watchthis = $request->getBool( 'watchthis', false ); // Watch may be overriden by request parameters
$this->recreate = false;
-
+
// When creating a new section, we can preload a section title by passing it as the
// preloadtitle parameter in the URL (Bug 13100)
if ( $this->section == 'new' && $request->getVal( 'preloadtitle' ) ) {
@@ -679,6 +701,9 @@ class EditPage {
}
elseif ( $this->section != 'new' && $request->getVal( 'summary' ) ) {
$this->summary = $request->getText( 'summary' );
+ if ( $this->summary !== '' ) {
+ $this->hasPresetSummary = true;
+ }
}
if ( $request->getVal( 'minor' ) ) {
@@ -731,7 +756,7 @@ class EditPage {
} elseif ( $wgUser->getOption( 'watchcreations' ) && !$this->mTitle->exists() ) {
# Watch creations
$this->watchthis = true;
- } elseif ( $this->mTitle->userIsWatching() ) {
+ } elseif ( $wgUser->isWatched( $this->mTitle ) ) {
# Already watched
$this->watchthis = true;
}
@@ -796,7 +821,7 @@ class EditPage {
# Otherwise, $text will be left as-is.
if ( !is_null( $undorev ) && !is_null( $oldrev ) &&
$undorev->getPage() == $oldrev->getPage() &&
- $undorev->getPage() == $this->mTitle->getArticleId() &&
+ $undorev->getPage() == $this->mTitle->getArticleID() &&
!$undorev->isDeleted( Revision::DELETED_TEXT ) &&
!$oldrev->isDeleted( Revision::DELETED_TEXT ) ) {
@@ -810,12 +835,13 @@ class EditPage {
# If we just undid one rev, use an autosummary
$firstrev = $oldrev->getNext();
- if ( $firstrev->getId() == $undo ) {
- $undoSummary = wfMsgForContent( 'undo-summary', $undo, $undorev->getUserText() );
+ if ( $firstrev && $firstrev->getId() == $undo ) {
+ $undoSummary = wfMessage( 'undo-summary', $undo, $undorev->getUserText() )->inContentLanguage()->text();
if ( $this->summary === '' ) {
$this->summary = $undoSummary;
} else {
- $this->summary = $undoSummary . wfMsgForContent( 'colon-separator' ) . $this->summary;
+ $this->summary = $undoSummary . wfMessage( 'colon-separator' )
+ ->inContentLanguage()->text() . $this->summary;
}
$this->undidRev = $undo;
}
@@ -830,7 +856,7 @@ class EditPage {
$class = ( $undoMsg == 'success' ? '' : 'error ' ) . "mw-undo-{$undoMsg}";
$this->editFormPageTop .= $wgOut->parse( "<div class=\"{$class}\">" .
- wfMsgNoTrans( 'undo-' . $undoMsg ) . '</div>', true, /* interface */true );
+ wfMessage( 'undo-' . $undoMsg )->plain() . '</div>', true, /* interface */true );
}
if ( $text === false ) {
@@ -852,7 +878,7 @@ class EditPage {
*
* This difers from Article::getContent() that when a missing revision is
* encountered the result will be an empty string and not the
- * 'missing-article' message.
+ * 'missing-revision' message.
*
* @since 1.19
* @return string
@@ -907,7 +933,7 @@ class EditPage {
if ( !empty( $this->mPreloadText ) ) {
return $this->mPreloadText;
}
-
+
if ( $preload === '' ) {
return '';
}
@@ -959,7 +985,6 @@ class EditPage {
$bot = $wgUser->isAllowed( 'bot' ) && $this->bot;
$status = $this->internalAttemptSave( $resultDetails, $bot );
// FIXME: once the interface for internalAttemptSave() is made nicer, this should use the message in $status
-
if ( $status->value == self::AS_SUCCESS_UPDATE || $status->value == self::AS_SUCCESS_NEW_ARTICLE ) {
$this->didSave = true;
}
@@ -976,7 +1001,6 @@ class EditPage {
return true;
case self::AS_HOOK_ERROR:
- case self::AS_FILTERING:
return false;
case self::AS_SUCCESS_NEW_ARTICLE:
@@ -1011,7 +1035,7 @@ class EditPage {
return false;
case self::AS_BLOCKED_PAGE_FOR_USER:
- throw new UserBlockedError( $wgUser->mBlock );
+ throw new UserBlockedError( $wgUser->getBlock() );
case self::AS_IMAGE_REDIRECT_ANON:
case self::AS_IMAGE_REDIRECT_LOGGED:
@@ -1031,8 +1055,15 @@ class EditPage {
$permission = $this->mTitle->isTalkPage() ? 'createtalk' : 'createpage';
throw new PermissionsError( $permission );
+ default:
+ // We don't recognize $status->value. The only way that can happen
+ // is if an extension hook aborted from inside ArticleSave.
+ // Render the status object into $this->hookError
+ // FIXME this sucks, we should just use the Status object throughout
+ $this->hookError = '<div class="error">' . $status->getWikitext() .
+ '</div>';
+ return true;
}
- return false;
}
/**
@@ -1048,8 +1079,7 @@ class EditPage {
* AS_CONTENT_TOO_BIG and AS_BLOCKED_PAGE_FOR_USER. All that stuff needs to be cleaned up some time.
*/
function internalAttemptSave( &$result, $bot = false ) {
- global $wgFilterCallback, $wgUser, $wgRequest, $wgParser;
- global $wgMaxArticleSize;
+ global $wgUser, $wgRequest, $wgParser, $wgMaxArticleSize;
$status = Status::newGood();
@@ -1095,13 +1125,6 @@ class EditPage {
wfProfileOut( __METHOD__ );
return $status;
}
- if ( $wgFilterCallback && is_callable( $wgFilterCallback ) && $wgFilterCallback( $this->mTitle, $this->textbox1, $this->section, $this->hookError, $this->summary ) ) {
- # Error messages or other handling should be performed by the filter function
- $status->setResult( false, self::AS_FILTERING );
- wfProfileOut( __METHOD__ . '-checks' );
- wfProfileOut( __METHOD__ );
- return $status;
- }
if ( !wfRunHooks( 'EditFilter', array( $this, $this->textbox1, $this->section, &$this->hookError, $this->summary ) ) ) {
# Error messages etc. could be handled within the hook...
$status->fatal( 'hookaborted' );
@@ -1179,9 +1202,10 @@ class EditPage {
wfProfileOut( __METHOD__ . '-checks' );
- # If article is new, insert it.
- $aid = $this->mTitle->getArticleID( Title::GAID_FOR_UPDATE );
- $new = ( $aid == 0 );
+ # Load the page data from the master. If anything changes in the meantime,
+ # we detect it by using page_latest like a token in a 1 try compare-and-swap.
+ $this->mArticle->loadPageData( 'fromdbmaster' );
+ $new = !$this->mArticle->exists();
if ( $new ) {
// Late check for create permission, just in case *PARANOIA*
@@ -1215,44 +1239,37 @@ class EditPage {
return $status;
}
- # Handle the user preference to force summaries here. Check if it's not a redirect.
- if ( !$this->allowBlankSummary && !Title::newFromRedirect( $this->textbox1 ) ) {
- if ( md5( $this->summary ) == $this->autoSumm ) {
- $this->missingSummary = true;
- $status->fatal( 'missingsummary' ); // or 'missingcommentheader' if $section == 'new'. Blegh
- $status->value = self::AS_SUMMARY_NEEDED;
- wfProfileOut( __METHOD__ );
- return $status;
- }
- }
-
$text = $this->textbox1;
$result['sectionanchor'] = '';
if ( $this->section == 'new' ) {
if ( $this->sectiontitle !== '' ) {
// Insert the section title above the content.
- $text = wfMsgForContent( 'newsectionheaderdefaultlevel', $this->sectiontitle ) . "\n\n" . $text;
-
+ $text = wfMessage( 'newsectionheaderdefaultlevel', $this->sectiontitle )
+ ->inContentLanguage()->text() . "\n\n" . $text;
+
// Jump to the new section
$result['sectionanchor'] = $wgParser->guessLegacySectionNameFromWikiText( $this->sectiontitle );
-
+
// If no edit summary was specified, create one automatically from the section
// title and have it link to the new section. Otherwise, respect the summary as
// passed.
if ( $this->summary === '' ) {
$cleanSectionTitle = $wgParser->stripSectionName( $this->sectiontitle );
- $this->summary = wfMsgForContent( 'newsectionsummary', $cleanSectionTitle );
+ $this->summary = wfMessage( 'newsectionsummary' )
+ ->rawParams( $cleanSectionTitle )->inContentLanguage()->text();
}
} elseif ( $this->summary !== '' ) {
// Insert the section title above the content.
- $text = wfMsgForContent( 'newsectionheaderdefaultlevel', $this->summary ) . "\n\n" . $text;
-
+ $text = wfMessage( 'newsectionheaderdefaultlevel', $this->summary )
+ ->inContentLanguage()->text() . "\n\n" . $text;
+
// Jump to the new section
$result['sectionanchor'] = $wgParser->guessLegacySectionNameFromWikiText( $this->summary );
// Create a link to the new section from the edit summary.
$cleanSummary = $wgParser->stripSectionName( $this->summary );
- $this->summary = wfMsgForContent( 'newsectionsummary', $cleanSummary );
+ $this->summary = wfMessage( 'newsectionsummary' )
+ ->rawParams( $cleanSummary )->inContentLanguage()->text();
}
}
@@ -1261,10 +1278,7 @@ class EditPage {
} else {
# Article exists. Check for edit conflict.
-
- $this->mArticle->clear(); # Force reload of dates, etc.
$timestamp = $this->mArticle->getTimestamp();
-
wfDebug( "timestamp: {$timestamp}, edittime: {$this->edittime}\n" );
if ( $timestamp != $this->edittime ) {
@@ -1279,15 +1293,15 @@ class EditPage {
} else {
// New comment; suppress conflict.
$this->isConflict = false;
- wfDebug( __METHOD__ .": conflict suppressed; new section\n" );
+ wfDebug( __METHOD__ . ": conflict suppressed; new section\n" );
}
- } elseif ( $this->section == '' && $this->userWasLastToEdit( $wgUser->getId(), $this->edittime ) ) {
+ } elseif ( $this->section == '' && Revision::userWasLastToEdit( DB_MASTER, $this->mTitle->getArticleID(), $wgUser->getId(), $this->edittime ) ) {
# Suppress edit conflict with self, except for section edits where merging is required.
wfDebug( __METHOD__ . ": Suppressing edit conflict, same user.\n" );
$this->isConflict = false;
}
}
-
+
// If sectiontitle is set, use it, otherwise use the summary as the section title (for
// backwards compatibility with old forms/bots).
if ( $this->sectiontitle !== '' ) {
@@ -1295,7 +1309,7 @@ class EditPage {
} else {
$sectionTitle = $this->summary;
}
-
+
if ( $this->isConflict ) {
wfDebug( __METHOD__ . ": conflict! getting section '$this->section' for time '$this->edittime' (article time '{$timestamp}')\n" );
$text = $this->mArticle->replaceSection( $this->section, $this->textbox1, $sectionTitle, $this->edittime );
@@ -1385,14 +1399,16 @@ class EditPage {
// passed.
if ( $this->summary === '' ) {
$cleanSectionTitle = $wgParser->stripSectionName( $this->sectiontitle );
- $this->summary = wfMsgForContent( 'newsectionsummary', $cleanSectionTitle );
+ $this->summary = wfMessage( 'newsectionsummary' )
+ ->rawParams( $cleanSectionTitle )->inContentLanguage()->text();
}
} elseif ( $this->summary !== '' ) {
$sectionanchor = $wgParser->guessLegacySectionNameFromWikiText( $this->summary );
# This is a new section, so create a link to the new section
# in the revision summary.
$cleanSummary = $wgParser->stripSectionName( $this->summary );
- $this->summary = wfMsgForContent( 'newsectionsummary', $cleanSummary );
+ $this->summary = wfMessage( 'newsectionsummary' )
+ ->rawParams( $cleanSummary )->inContentLanguage()->text();
}
} elseif ( $this->section != '' ) {
# Try to get a section anchor from the section source, redirect to edited section if header found
@@ -1440,8 +1456,17 @@ class EditPage {
wfProfileOut( __METHOD__ );
return $status;
} else {
- $this->isConflict = true;
- $doEditStatus->value = self::AS_END; // Destroys data doEdit() put in $status->value but who cares
+ // Failure from doEdit()
+ // Show the edit conflict page for certain recognized errors from doEdit(),
+ // but don't show it for errors from extension hooks
+ $errors = $doEditStatus->getErrorsArray();
+ if ( in_array( $errors[0][0], array( 'edit-gone-missing', 'edit-conflict',
+ 'edit-already-exists' ) ) )
+ {
+ $this->isConflict = true;
+ // Destroys data doEdit() put in $status->value but who cares
+ $doEditStatus->value = self::AS_END;
+ }
wfProfileOut( __METHOD__ );
return $doEditStatus;
}
@@ -1452,56 +1477,27 @@ class EditPage {
*/
protected function commitWatch() {
global $wgUser;
- if ( $this->watchthis xor $this->mTitle->userIsWatching() ) {
+ if ( $wgUser->isLoggedIn() && $this->watchthis != $wgUser->isWatched( $this->mTitle ) ) {
$dbw = wfGetDB( DB_MASTER );
- $dbw->begin();
+ $dbw->begin( __METHOD__ );
if ( $this->watchthis ) {
WatchAction::doWatch( $this->mTitle, $wgUser );
} else {
WatchAction::doUnwatch( $this->mTitle, $wgUser );
}
- $dbw->commit();
+ $dbw->commit( __METHOD__ );
}
}
/**
- * Check if no edits were made by other users since
- * the time a user started editing the page. Limit to
- * 50 revisions for the sake of performance.
- *
- * @param $id int
- * @param $edittime string
- *
- * @return bool
- */
- protected function userWasLastToEdit( $id, $edittime ) {
- if( !$id ) return false;
- $dbw = wfGetDB( DB_MASTER );
- $res = $dbw->select( 'revision',
- 'rev_user',
- array(
- 'rev_page' => $this->mTitle->getArticleId(),
- 'rev_timestamp > '.$dbw->addQuotes( $dbw->timestamp($edittime) )
- ),
- __METHOD__,
- array( 'ORDER BY' => 'rev_timestamp ASC', 'LIMIT' => 50 ) );
- foreach ( $res as $row ) {
- if( $row->rev_user != $id ) {
- return false;
- }
- }
- return true;
- }
-
- /**
* @private
* @todo document
*
- * @parma $editText string
+ * @param $editText string
*
* @return bool
*/
- function mergeChangesInto( &$editText ){
+ function mergeChangesInto( &$editText ) {
wfProfileIn( __METHOD__ );
$db = wfGetDB( DB_MASTER );
@@ -1552,7 +1548,7 @@ class EditPage {
*
* @param $text string
*
- * @return string|false matching string or false
+ * @return string|bool matching string or false
*/
public static function matchSpamRegex( $text ) {
global $wgSpamRegex;
@@ -1564,9 +1560,9 @@ class EditPage {
/**
* Check given input text against $wgSpamRegex, and return the text of the first match.
*
- * @parma $text string
+ * @param $text string
*
- * @return string|false matching string or false
+ * @return string|bool matching string or false
*/
public static function matchSummarySpamRegex( $text ) {
global $wgSummarySpamRegex;
@@ -1580,9 +1576,9 @@ class EditPage {
* @return bool|string
*/
protected static function matchSpamRegexInternal( $text, $regexes ) {
- foreach( $regexes as $regex ) {
+ foreach ( $regexes as $regex ) {
$matches = array();
- if( preg_match( $regex, $text, $matches ) ) {
+ if ( preg_match( $regex, $text, $matches ) ) {
return $matches[0];
}
}
@@ -1595,7 +1591,7 @@ class EditPage {
$wgOut->addModules( 'mediawiki.action.edit' );
if ( $wgUser->getOption( 'uselivepreview', false ) ) {
- $wgOut->addModules( 'mediawiki.legacy.preview' );
+ $wgOut->addModules( 'mediawiki.action.edit.preview' );
}
// Bug #19334: textarea jumps when editing articles in IE8
$wgOut->addStyle( 'common/IE80Fixes.css', 'screen', 'IE 8' );
@@ -1605,21 +1601,21 @@ class EditPage {
# Enabled article-related sidebar, toplinks, etc.
$wgOut->setArticleRelated( true );
+ $contextTitle = $this->getContextTitle();
if ( $this->isConflict ) {
- $wgOut->setPageTitle( wfMessage( 'editconflict', $this->getContextTitle()->getPrefixedText() ) );
- } elseif ( $this->section != '' ) {
+ $msg = 'editconflict';
+ } elseif ( $contextTitle->exists() && $this->section != '' ) {
$msg = $this->section == 'new' ? 'editingcomment' : 'editingsection';
- $wgOut->setPageTitle( wfMessage( $msg, $this->getContextTitle()->getPrefixedText() ) );
} else {
- # Use the title defined by DISPLAYTITLE magic word when present
- if ( isset( $this->mParserOutput )
- && ( $dt = $this->mParserOutput->getDisplayTitle() ) !== false ) {
- $title = $dt;
- } else {
- $title = $this->getContextTitle()->getPrefixedText();
- }
- $wgOut->setPageTitle( wfMessage( 'editing', $title ) );
+ $msg = $contextTitle->exists() || ( $contextTitle->getNamespace() == NS_MEDIAWIKI && $contextTitle->getDefaultMessageText() !== false ) ?
+ 'editing' : 'creating';
+ }
+ # Use the title defined by DISPLAYTITLE magic word when present
+ $displayTitle = isset( $this->mParserOutput ) ? $this->mParserOutput->getDisplayTitle() : false;
+ if ( $displayTitle === false ) {
+ $displayTitle = $contextTitle->getPrefixedText();
}
+ $wgOut->setPageTitle( wfMessage( $msg, $displayTitle ) );
}
/**
@@ -1636,6 +1632,24 @@ class EditPage {
if ( $namespace == NS_MEDIAWIKI ) {
# Show a warning if editing an interface message
$wgOut->wrapWikiMsg( "<div class='mw-editinginterface'>\n$1\n</div>", 'editinginterface' );
+ } else if( $namespace == NS_FILE ) {
+ # Show a hint to shared repo
+ $file = wfFindFile( $this->mTitle );
+ if( $file && !$file->isLocal() ) {
+ $descUrl = $file->getDescriptionUrl();
+ # there must be a description url to show a hint to shared repo
+ if( $descUrl ) {
+ if( !$this->mTitle->exists() ) {
+ $wgOut->wrapWikiMsg( "<div class=\"mw-sharedupload-desc-create\">\n$1\n</div>", array (
+ 'sharedupload-desc-create', $file->getRepo()->getDisplayName(), $descUrl
+ ) );
+ } else {
+ $wgOut->wrapWikiMsg( "<div class=\"mw-sharedupload-desc-edit\">\n$1\n</div>", array(
+ 'sharedupload-desc-edit', $file->getRepo()->getDisplayName(), $descUrl
+ ) );
+ }
+ }
+ }
}
# Show a warning message when someone creates/edits a user (talk) page but the user does not exist
@@ -1645,7 +1659,7 @@ class EditPage {
$username = $parts[0];
$user = User::newFromName( $username, false /* allow IP users*/ );
$ip = User::isIP( $username );
- if ( !($user && $user->isLoggedIn()) && !$ip ) { # User does not exist
+ if ( !( $user && $user->isLoggedIn() ) && !$ip ) { # User does not exist
$wgOut->wrapWikiMsg( "<div class=\"mw-userpage-userdoesnotexist error\">\n$1\n</div>",
array( 'userpage-userdoesnotexist', wfEscapeWikiText( $username ) ) );
} elseif ( $user->isBlocked() ) { # Show log extract if the user is currently blocked
@@ -1679,7 +1693,7 @@ class EditPage {
'', array( 'lim' => 10,
'conds' => array( "log_action != 'revision'" ),
'showIfEmpty' => false,
- 'msgKey' => array( 'recreate-moveddeleted-warn') )
+ 'msgKey' => array( 'recreate-moveddeleted-warn' ) )
);
}
}
@@ -1715,16 +1729,16 @@ class EditPage {
wfProfileIn( __METHOD__ );
- #need to parse the preview early so that we know which templates are used,
- #otherwise users with "show preview after edit box" will get a blank list
- #we parse this near the beginning so that setHeaders can do the title
- #setting work instead of leaving it in getPreviewText
+ # need to parse the preview early so that we know which templates are used,
+ # otherwise users with "show preview after edit box" will get a blank list
+ # we parse this near the beginning so that setHeaders can do the title
+ # setting work instead of leaving it in getPreviewText
$previewOutput = '';
if ( $this->formtype == 'preview' ) {
$previewOutput = $this->getPreviewText();
}
- wfRunHooks( 'EditPage::showEditForm:initial', array( &$this ) );
+ wfRunHooks( 'EditPage::showEditForm:initial', array( &$this, &$wgOut ) );
$this->setHeaders();
@@ -1753,7 +1767,7 @@ class EditPage {
}
}
- $wgOut->addHTML( Html::openElement( 'form', array( 'id' => 'editform', 'name' => 'editform',
+ $wgOut->addHTML( Html::openElement( 'form', array( 'id' => self::EDITFORM_ID, 'name' => self::EDITFORM_ID,
'method' => 'post', 'action' => $this->getActionURL( $this->getContextTitle() ),
'enctype' => 'multipart/form-data' ) ) );
@@ -1777,14 +1791,19 @@ class EditPage {
: 'confirmrecreate';
$wgOut->addHTML(
'<div class="mw-confirm-recreate">' .
- wfMsgExt( $key, 'parseinline', $username, "<nowiki>$comment</nowiki>" ) .
- Xml::checkLabel( wfMsg( 'recreate' ), 'wpRecreate', 'wpRecreate', false,
+ wfMessage( $key, $username, "<nowiki>$comment</nowiki>" )->parse() .
+ Xml::checkLabel( wfMessage( 'recreate' )->text(), 'wpRecreate', 'wpRecreate', false,
array( 'title' => Linker::titleAttrib( 'recreate' ), 'tabindex' => 1, 'id' => 'wpRecreate' )
) .
'</div>'
);
}
+ # When the summary is hidden, also hide them on preview/show changes
+ if( $this->nosummary ) {
+ $wgOut->addHTML( Html::hidden( 'nosummary', true ) );
+ }
+
# If a blank edit summary was previously provided, and the appropriate
# user preference is active, pass a hidden tag as wpIgnoreBlankSummary. This will stop the
# user being bounced back more than once in the event that a summary
@@ -1796,6 +1815,17 @@ class EditPage {
$wgOut->addHTML( Html::hidden( 'wpIgnoreBlankSummary', true ) );
}
+ if ( $this->undidRev ) {
+ $wgOut->addHTML( Html::hidden( 'wpUndidRevision', $this->undidRev ) );
+ }
+
+ if ( $this->hasPresetSummary ) {
+ // If a summary has been preset using &summary= we dont want to prompt for
+ // a different summary. Only prompt for a summary if the summary is blanked.
+ // (Bug 17416)
+ $this->autoSumm = md5( '' );
+ }
+
$autosumm = $this->autoSumm ? $this->autoSumm : md5( $this->summary );
$wgOut->addHTML( Html::hidden( 'wpAutoSummary', $autosumm ) );
@@ -1827,10 +1857,6 @@ class EditPage {
$wgOut->addHTML( $this->editFormTextAfterContent );
- $wgOut->addWikiText( $this->getCopywarn() );
-
- $wgOut->addHTML( $this->editFormTextAfterWarn );
-
$this->showStandardInputs();
$this->showFormAfterText();
@@ -1870,7 +1896,7 @@ class EditPage {
preg_match( "/^(=+)(.+)\\1\\s*(\n|$)/i", $text, $matches );
if ( !empty( $matches[2] ) ) {
global $wgParser;
- return $wgParser->stripSectionName(trim($matches[2]));
+ return $wgParser->stripSectionName( trim( $matches[2] ) );
} else {
return false;
}
@@ -1884,8 +1910,8 @@ class EditPage {
}
# Optional notices on a per-namespace and per-page basis
- $editnotice_ns = 'editnotice-'.$this->mTitle->getNamespace();
- $editnotice_ns_message = wfMessage( $editnotice_ns )->inContentLanguage();
+ $editnotice_ns = 'editnotice-' . $this->mTitle->getNamespace();
+ $editnotice_ns_message = wfMessage( $editnotice_ns );
if ( $editnotice_ns_message->exists() ) {
$wgOut->addWikiText( $editnotice_ns_message->plain() );
}
@@ -1893,16 +1919,16 @@ class EditPage {
$parts = explode( '/', $this->mTitle->getDBkey() );
$editnotice_base = $editnotice_ns;
while ( count( $parts ) > 0 ) {
- $editnotice_base .= '-'.array_shift( $parts );
- $editnotice_base_msg = wfMessage( $editnotice_base )->inContentLanguage();
+ $editnotice_base .= '-' . array_shift( $parts );
+ $editnotice_base_msg = wfMessage( $editnotice_base );
if ( $editnotice_base_msg->exists() ) {
- $wgOut->addWikiText( $editnotice_base_msg->plain() );
+ $wgOut->addWikiText( $editnotice_base_msg->plain() );
}
}
} else {
# Even if there are no subpages in namespace, we still don't want / in MW ns.
$editnoticeText = $editnotice_ns . '-' . str_replace( '/', '-', $this->mTitle->getDBkey() );
- $editnoticeMsg = wfMessage( $editnoticeText )->inContentLanguage();
+ $editnoticeMsg = wfMessage( $editnoticeText );
if ( $editnoticeMsg->exists() ) {
$wgOut->addWikiText( $editnoticeMsg->plain() );
}
@@ -1968,8 +1994,7 @@ class EditPage {
// Something went wrong
$wgOut->wrapWikiMsg( "<div class='errorbox'>\n$1\n</div>\n",
- array( 'missing-article', $this->mTitle->getPrefixedText(),
- wfMsgNoTrans( 'missingarticle-rev', $this->oldid ) ) );
+ array( 'missing-revision', $this->oldid ) );
}
}
}
@@ -2010,12 +2035,12 @@ class EditPage {
}
if ( $this->mTitle->isCascadeProtected() ) {
# Is this page under cascading protection from some source pages?
- list($cascadeSources, /* $restrictions */) = $this->mTitle->getCascadeProtectionSources();
+ list( $cascadeSources, /* $restrictions */ ) = $this->mTitle->getCascadeProtectionSources();
$notice = "<div class='mw-cascadeprotectedwarning'>\n$1\n";
$cascadeSourcesCount = count( $cascadeSources );
if ( $cascadeSourcesCount > 0 ) {
# Explain, and list the titles responsible
- foreach( $cascadeSources as $page ) {
+ foreach ( $cascadeSources as $page ) {
$notice .= '* [[:' . $page->getPrefixedText() . "]]\n";
}
}
@@ -2024,7 +2049,7 @@ class EditPage {
}
if ( !$this->mTitle->exists() && $this->mTitle->getRestrictions( 'create' ) ) {
LogEventsList::showLogExtract( $wgOut, 'protect', $this->mTitle, '',
- array( 'lim' => 1,
+ array( 'lim' => 1,
'showIfEmpty' => false,
'msgKey' => array( 'titleprotectedwarning' ),
'wrap' => "<div class=\"mw-titleprotectedwarning\">\n$1</div>" ) );
@@ -2038,14 +2063,17 @@ class EditPage {
$wgOut->wrapWikiMsg( "<div class='error' id='mw-edit-longpageerror'>\n$1\n</div>",
array( 'longpageerror', $wgLang->formatNum( $this->kblength ), $wgLang->formatNum( $wgMaxArticleSize ) ) );
} else {
- if( !wfMessage('longpage-hint')->isDisabled() ) {
+ if ( !wfMessage( 'longpage-hint' )->isDisabled() ) {
$wgOut->wrapWikiMsg( "<div id='mw-edit-longpage-hint'>\n$1\n</div>",
array( 'longpage-hint', $wgLang->formatSize( strlen( $this->textbox1 ) ), strlen( $this->textbox1 ) )
);
}
}
+ # Add header copyright warning
+ $this->showHeaderCopyrightWarning();
}
+
/**
* Standard summary input and label (wgSummary), abstracted so EditPage
* subclasses may reorganize the form.
@@ -2060,9 +2088,9 @@ class EditPage {
*
* @return array An array in the format array( $label, $input )
*/
- function getSummaryInput($summary = "", $labelText = null, $inputAttrs = null, $spanLabelAttrs = null) {
- //Note: the maxlength is overriden in JS to 250 and to make it use UTF-8 bytes, not characters.
- $inputAttrs = ( is_array($inputAttrs) ? $inputAttrs : array() ) + array(
+ function getSummaryInput( $summary = "", $labelText = null, $inputAttrs = null, $spanLabelAttrs = null ) {
+ // Note: the maxlength is overriden in JS to 255 and to make it use UTF-8 bytes, not characters.
+ $inputAttrs = ( is_array( $inputAttrs ) ? $inputAttrs : array() ) + array(
'id' => 'wpSummary',
'maxlength' => '200',
'tabindex' => '1',
@@ -2070,7 +2098,7 @@ class EditPage {
'spellcheck' => 'true',
) + Linker::tooltipAndAccesskeyAttribs( 'summary' );
- $spanLabelAttrs = ( is_array($spanLabelAttrs) ? $spanLabelAttrs : array() ) + array(
+ $spanLabelAttrs = ( is_array( $spanLabelAttrs ) ? $spanLabelAttrs : array() ) + array(
'class' => $this->missingSummary ? 'mw-summarymissed' : 'mw-summary',
'id' => "wpSummaryLabel"
);
@@ -2107,9 +2135,9 @@ class EditPage {
}
}
$summary = $wgContLang->recodeForEdit( $summary );
- $labelText = wfMsgExt( $isSubjectPreview ? 'subject' : 'summary', 'parseinline' );
- list($label, $input) = $this->getSummaryInput($summary, $labelText, array( 'class' => $summaryClass ), array());
- $wgOut->addHTML("{$label} {$input}");
+ $labelText = wfMessage( $isSubjectPreview ? 'subject' : 'summary' )->parse();
+ list( $label, $input ) = $this->getSummaryInput( $summary, $labelText, array( 'class' => $summaryClass ), array() );
+ $wgOut->addHTML( "{$label} {$input}" );
}
/**
@@ -2126,11 +2154,12 @@ class EditPage {
global $wgParser;
if ( $isSubjectPreview )
- $summary = wfMsgForContent( 'newsectionsummary', $wgParser->stripSectionName( $summary ) );
+ $summary = wfMessage( 'newsectionsummary', $wgParser->stripSectionName( $summary ) )
+ ->inContentLanguage()->text();
$message = $isSubjectPreview ? 'subject-preview' : 'summary-preview';
- $summary = wfMsgExt( $message, 'parseinline' ) . Linker::commentBlock( $summary, $this->mTitle, $isSubjectPreview );
+ $summary = wfMessage( $message )->parse() . Linker::commentBlock( $summary, $this->mTitle, $isSubjectPreview );
return Xml::tags( 'div', array( 'class' => 'mw-summary-preview' ), $summary );
}
@@ -2146,7 +2175,7 @@ class EditPage {
HTML
);
if ( !$this->checkUnicodeCompliantBrowser() )
- $wgOut->addHTML(Html::hidden( 'safemode', '1' ));
+ $wgOut->addHTML( Html::hidden( 'safemode', '1' ) );
}
protected function showFormAfterText() {
@@ -2183,7 +2212,7 @@ HTML
* The $textoverride method can be used by subclasses overriding showContentForm
* to pass back to this method.
*
- * @param $customAttribs An array of html attributes to use in the textarea
+ * @param $customAttribs array of html attributes to use in the textarea
* @param $textoverride String: optional text to override $this->textarea1 with
*/
protected function showTextbox1( $customAttribs = null, $textoverride = null ) {
@@ -2230,7 +2259,7 @@ HTML
global $wgOut, $wgUser;
$wikitext = $this->safeUnicodeOutput( $content );
- if ( strval($wikitext) !== '' ) {
+ if ( strval( $wikitext ) !== '' ) {
// Ensure there's a newline at the end, otherwise adding lines
// is awkward.
// But don't add a newline if the ext is empty, or Firefox in XHTML
@@ -2272,7 +2301,7 @@ HTML
$wgOut->addHTML( '</div>' );
- if ( $this->formtype == 'diff') {
+ if ( $this->formtype == 'diff' ) {
$this->showDiff();
}
}
@@ -2285,12 +2314,12 @@ HTML
*/
protected function showPreview( $text ) {
global $wgOut;
- if ( $this->mTitle->getNamespace() == NS_CATEGORY) {
+ if ( $this->mTitle->getNamespace() == NS_CATEGORY ) {
$this->mArticle->openShowCategory();
}
# This hook seems slightly odd here, but makes things more
# consistent for extensions.
- wfRunHooks( 'OutputPageBeforeHTML',array( &$wgOut, &$text ) );
+ wfRunHooks( 'OutputPageBeforeHTML', array( &$wgOut, &$text ) );
$wgOut->addHTML( $text );
if ( $this->mTitle->getNamespace() == NS_CATEGORY ) {
$this->mArticle->closeShowCategory();
@@ -2307,7 +2336,16 @@ HTML
function showDiff() {
global $wgUser, $wgContLang, $wgParser, $wgOut;
- $oldtext = $this->mArticle->getRawText();
+ $oldtitlemsg = 'currentrev';
+ # if message does not exist, show diff against the preloaded default
+ if( $this->mTitle->getNamespace() == NS_MEDIAWIKI && !$this->mTitle->exists() ) {
+ $oldtext = $this->mTitle->getDefaultMessageText();
+ if( $oldtext !== false ) {
+ $oldtitlemsg = 'defaultmessagetext';
+ }
+ } else {
+ $oldtext = $this->mArticle->getRawText();
+ }
$newtext = $this->mArticle->replaceSection(
$this->section, $this->textbox1, $this->summary, $this->edittime );
@@ -2317,8 +2355,8 @@ HTML
$newtext = $wgParser->preSaveTransform( $newtext, $this->mTitle, $wgUser, $popts );
if ( $oldtext !== false || $newtext != '' ) {
- $oldtitle = wfMsgExt( 'currentrev', array( 'parseinline' ) );
- $newtitle = wfMsgExt( 'yourtext', array( 'parseinline' ) );
+ $oldtitle = wfMessage( $oldtitlemsg )->parse();
+ $newtitle = wfMessage( 'yourtext' )->parse();
$de = new DifferenceEngine( $this->mArticle->getContext() );
$de->setText( $oldtext, $newtext );
@@ -2332,6 +2370,18 @@ HTML
}
/**
+ * Show the header copyright warning.
+ */
+ protected function showHeaderCopyrightWarning() {
+ $msg = 'editpage-head-copy-warn';
+ if ( !wfMessage( $msg )->isDisabled() ) {
+ global $wgOut;
+ $wgOut->wrapWikiMsg( "<div class='editpage-head-copywarn'>\n$1\n</div>",
+ 'editpage-head-copy-warn' );
+ }
+ }
+
+ /**
* Give a chance for site and per-namespace customizations of
* terms of service summary link that might exist separately
* from the copyright notice.
@@ -2342,7 +2392,7 @@ HTML
protected function showTosSummary() {
$msg = 'editpage-tos-summary';
wfRunHooks( 'EditPageTosSummary', array( $this->mTitle, &$msg ) );
- if( !wfMessage( $msg )->isDisabled() ) {
+ if ( !wfMessage( $msg )->isDisabled() ) {
global $wgOut;
$wgOut->addHTML( '<div class="mw-tos-summary">' );
$wgOut->addWikiMsg( $msg );
@@ -2357,21 +2407,30 @@ HTML
'</div>' );
}
+ /**
+ * Get the copyright warning
+ *
+ * Renamed to getCopyrightWarning(), old name kept around for backwards compatibility
+ */
protected function getCopywarn() {
+ return self::getCopyrightWarning( $this->mTitle );
+ }
+
+ public static function getCopyrightWarning( $title ) {
global $wgRightsText;
if ( $wgRightsText ) {
$copywarnMsg = array( 'copyrightwarning',
- '[[' . wfMsgForContent( 'copyrightpage' ) . ']]',
+ '[[' . wfMessage( 'copyrightpage' )->inContentLanguage()->text() . ']]',
$wgRightsText );
} else {
$copywarnMsg = array( 'copyrightwarning2',
- '[[' . wfMsgForContent( 'copyrightpage' ) . ']]' );
+ '[[' . wfMessage( 'copyrightpage' )->inContentLanguage()->text() . ']]' );
}
// Allow for site and per-namespace customization of contribution/copyright notice.
- wfRunHooks( 'EditPageCopyrightWarning', array( $this->mTitle, &$copywarnMsg ) );
+ wfRunHooks( 'EditPageCopyrightWarning', array( $title, &$copywarnMsg ) );
return "<div id=\"editpage-copywarn\">\n" .
- call_user_func_array("wfMsgNoTrans", $copywarnMsg) . "\n</div>";
+ call_user_func_array( 'wfMessage', $copywarnMsg )->plain() . "\n</div>";
}
protected function showStandardInputs( &$tabindex = 2 ) {
@@ -2386,18 +2445,24 @@ HTML
$checkboxes = $this->getCheckboxes( $tabindex,
array( 'minor' => $this->minoredit, 'watch' => $this->watchthis ) );
$wgOut->addHTML( "<div class='editCheckboxes'>" . implode( $checkboxes, "\n" ) . "</div>\n" );
+
+ // Show copyright warning.
+ $wgOut->addWikiText( $this->getCopywarn() );
+ $wgOut->addHTML( $this->editFormTextAfterWarn );
+
$wgOut->addHTML( "<div class='editButtons'>\n" );
$wgOut->addHTML( implode( $this->getEditButtons( $tabindex ), "\n" ) . "\n" );
$cancel = $this->getCancelLink();
if ( $cancel !== '' ) {
- $cancel .= wfMsgExt( 'pipe-separator' , 'escapenoentities' );
- }
- $edithelpurl = Skin::makeInternalOrExternalUrl( wfMsgForContent( 'edithelppage' ) );
- $edithelp = '<a target="helpwindow" href="'.$edithelpurl.'">'.
- htmlspecialchars( wfMsg( 'edithelp' ) ).'</a> '.
- htmlspecialchars( wfMsg( 'newwindow' ) );
- $wgOut->addHTML( " <span class='editHelp'>{$cancel}{$edithelp}</span>\n" );
+ $cancel .= wfMessage( 'pipe-separator' )->text();
+ }
+ $edithelpurl = Skin::makeInternalOrExternalUrl( wfMessage( 'edithelppage' )->inContentLanguage()->text() );
+ $edithelp = '<a target="helpwindow" href="' . $edithelpurl . '">' .
+ wfMessage( 'edithelp' )->escaped() . '</a> ' .
+ wfMessage( 'newwindow' )->parse();
+ $wgOut->addHTML( " <span class='cancelLink'>{$cancel}</span>\n" );
+ $wgOut->addHTML( " <span class='editHelp'>{$edithelp}</span>\n" );
$wgOut->addHTML( "</div><!-- editButtons -->\n</div><!-- editOptions -->\n" );
}
@@ -2413,7 +2478,10 @@ HTML
$de = new DifferenceEngine( $this->mArticle->getContext() );
$de->setText( $this->textbox2, $this->textbox1 );
- $de->showDiff( wfMsgExt( 'yourtext', 'parseinline' ), wfMsg( 'storedversion' ) );
+ $de->showDiff(
+ wfMessage( 'yourtext' )->parse(),
+ wfMessage( 'storedversion' )->text()
+ );
$wgOut->wrapWikiMsg( '<h2>$1</h2>', "yourtext" );
$this->showTextbox2();
@@ -2431,7 +2499,7 @@ HTML
return Linker::linkKnown(
$this->getContextTitle(),
- wfMsgExt( 'cancel', array( 'parseinline' ) ),
+ wfMessage( 'cancel' )->parse(),
array( 'id' => 'mw-editform-cancel' ),
$cancelParams
);
@@ -2499,11 +2567,11 @@ HTML
array( 'LIMIT' => 1, 'ORDER BY' => 'log_timestamp DESC' )
);
// Quick paranoid permission checks...
- if( is_object( $data ) ) {
- if( $data->log_deleted & LogPage::DELETED_USER )
- $data->user_name = wfMsgHtml( 'rev-deleted-user' );
- if( $data->log_deleted & LogPage::DELETED_COMMENT )
- $data->log_comment = wfMsgHtml( 'rev-deleted-comment' );
+ if ( is_object( $data ) ) {
+ if ( $data->log_deleted & LogPage::DELETED_USER )
+ $data->user_name = wfMessage( 'rev-deleted-user' )->escaped();
+ if ( $data->log_deleted & LogPage::DELETED_COMMENT )
+ $data->log_comment = wfMessage( 'rev-deleted-comment' )->escaped();
}
return $data;
}
@@ -2513,7 +2581,7 @@ HTML
* @return string
*/
function getPreviewText() {
- global $wgOut, $wgUser, $wgParser, $wgRawHtml;
+ global $wgOut, $wgUser, $wgParser, $wgRawHtml, $wgLang;
wfProfileIn( __METHOD__ );
@@ -2526,7 +2594,7 @@ HTML
// string, which happens when you initially edit
// a category page, due to automatic preview-on-open.
$parsedNote = $wgOut->parse( "<div class='previewnote'>" .
- wfMsg( 'session_fail_preview_html' ) . "</div>", true, /* interface */true );
+ wfMessage( 'session_fail_preview_html' )->text() . "</div>", true, /* interface */true );
}
wfProfileOut( __METHOD__ );
return $parsedNote;
@@ -2534,29 +2602,28 @@ HTML
if ( $this->mTriedSave && !$this->mTokenOk ) {
if ( $this->mTokenOkExceptSuffix ) {
- $note = wfMsg( 'token_suffix_mismatch' );
+ $note = wfMessage( 'token_suffix_mismatch' )->plain();
} else {
- $note = wfMsg( 'session_fail_preview' );
+ $note = wfMessage( 'session_fail_preview' )->plain();
}
} elseif ( $this->incompleteForm ) {
- $note = wfMsg( 'edit_form_incomplete' );
+ $note = wfMessage( 'edit_form_incomplete' )->plain();
} else {
- $note = wfMsg( 'previewnote' );
+ $note = wfMessage( 'previewnote' )->plain() .
+ ' [[#' . self::EDITFORM_ID . '|' . $wgLang->getArrow() . ' ' . wfMessage( 'continue-editing' )->text() . ']]';
}
- $parserOptions = ParserOptions::newFromUser( $wgUser );
+ $parserOptions = $this->mArticle->makeParserOptions( $this->mArticle->getContext() );
+
$parserOptions->setEditSection( false );
- $parserOptions->setTidy( true );
$parserOptions->setIsPreview( true );
- $parserOptions->setIsSectionPreview( !is_null($this->section) && $this->section !== '' );
+ $parserOptions->setIsSectionPreview( !is_null( $this->section ) && $this->section !== '' );
# don't parse non-wikitext pages, show message about preview
- # XXX: stupid php bug won't let us use $this->getContextTitle()->isCssJsSubpage() here -- This note has been there since r3530. Sure the bug was fixed time ago?
-
- if ( $this->isCssJsSubpage || !$this->mTitle->isWikitextPage() ) {
- if( $this->mTitle->isCssJsSubpage() ) {
+ if ( $this->mTitle->isCssJsSubpage() || !$this->mTitle->isWikitextPage() ) {
+ if ( $this->mTitle->isCssJsSubpage() ) {
$level = 'user';
- } elseif( $this->mTitle->isCssOrJsPage() ) {
+ } elseif ( $this->mTitle->isCssOrJsPage() ) {
$level = 'site';
} else {
$level = false;
@@ -2564,64 +2631,66 @@ HTML
# Used messages to make sure grep find them:
# Messages: usercsspreview, userjspreview, sitecsspreview, sitejspreview
- if( $level ) {
- if (preg_match( "/\\.css$/", $this->mTitle->getText() ) ) {
- $previewtext = "<div id='mw-{$level}csspreview'>\n" . wfMsg( "{$level}csspreview" ) . "\n</div>";
- $class = "mw-code mw-css";
- } elseif (preg_match( "/\\.js$/", $this->mTitle->getText() ) ) {
- $previewtext = "<div id='mw-{$level}jspreview'>\n" . wfMsg( "{$level}jspreview" ) . "\n</div>";
- $class = "mw-code mw-js";
+ $class = 'mw-code';
+ if ( $level ) {
+ if ( preg_match( "/\\.css$/", $this->mTitle->getText() ) ) {
+ $previewtext = "<div id='mw-{$level}csspreview'>\n" . wfMessage( "{$level}csspreview" )->text() . "\n</div>";
+ $class .= " mw-css";
+ } elseif ( preg_match( "/\\.js$/", $this->mTitle->getText() ) ) {
+ $previewtext = "<div id='mw-{$level}jspreview'>\n" . wfMessage( "{$level}jspreview" )->text() . "\n</div>";
+ $class .= " mw-js";
} else {
throw new MWException( 'A CSS/JS (sub)page but which is not css nor js!' );
}
+ $parserOutput = $wgParser->parse( $previewtext, $this->mTitle, $parserOptions );
+ $previewHTML = $parserOutput->getText();
+ } else {
+ $previewHTML = '';
}
- $parserOutput = $wgParser->parse( $previewtext, $this->mTitle, $parserOptions );
- $previewHTML = $parserOutput->mText;
$previewHTML .= "<pre class=\"$class\" dir=\"ltr\">\n" . htmlspecialchars( $this->textbox1 ) . "\n</pre>\n";
} else {
- $rt = Title::newFromRedirectArray( $this->textbox1 );
- if ( $rt ) {
- $previewHTML = $this->mArticle->viewRedirect( $rt, false );
- } else {
- $toparse = $this->textbox1;
-
- # If we're adding a comment, we need to show the
- # summary as the headline
- if ( $this->section == "new" && $this->summary != "" ) {
- $toparse = wfMsgForContent( 'newsectionheaderdefaultlevel', $this->summary ) . "\n\n" . $toparse;
- }
+ $toparse = $this->textbox1;
- wfRunHooks( 'EditPageGetPreviewText', array( $this, &$toparse ) );
+ # If we're adding a comment, we need to show the
+ # summary as the headline
+ if ( $this->section == "new" && $this->summary != "" ) {
+ $toparse = wfMessage( 'newsectionheaderdefaultlevel', $this->summary )->inContentLanguage()->text() . "\n\n" . $toparse;
+ }
- $parserOptions->enableLimitReport();
+ wfRunHooks( 'EditPageGetPreviewText', array( $this, &$toparse ) );
- $toparse = $wgParser->preSaveTransform( $toparse, $this->mTitle, $wgUser, $parserOptions );
- $parserOutput = $wgParser->parse( $toparse, $this->mTitle, $parserOptions );
+ $toparse = $wgParser->preSaveTransform( $toparse, $this->mTitle, $wgUser, $parserOptions );
+ $parserOutput = $wgParser->parse( $toparse, $this->mTitle, $parserOptions );
+ $rt = Title::newFromRedirectArray( $this->textbox1 );
+ if ( $rt ) {
+ $previewHTML = $this->mArticle->viewRedirect( $rt, false );
+ } else {
$previewHTML = $parserOutput->getText();
- $this->mParserOutput = $parserOutput;
- $wgOut->addParserOutputNoText( $parserOutput );
+ }
- if ( count( $parserOutput->getWarnings() ) ) {
- $note .= "\n\n" . implode( "\n\n", $parserOutput->getWarnings() );
- }
+ $this->mParserOutput = $parserOutput;
+ $wgOut->addParserOutputNoText( $parserOutput );
+
+ if ( count( $parserOutput->getWarnings() ) ) {
+ $note .= "\n\n" . implode( "\n\n", $parserOutput->getWarnings() );
}
}
- if( $this->isConflict ) {
- $conflict = '<h2 id="mw-previewconflict">' . htmlspecialchars( wfMsg( 'previewconflict' ) ) . "</h2>\n";
+ if ( $this->isConflict ) {
+ $conflict = '<h2 id="mw-previewconflict">' . wfMessage( 'previewconflict' )->escaped() . "</h2>\n";
} else {
$conflict = '<hr />';
}
$previewhead = "<div class='previewnote'>\n" .
- '<h2 id="mw-previewheader">' . htmlspecialchars( wfMsg( 'preview' ) ) . "</h2>" .
+ '<h2 id="mw-previewheader">' . wfMessage( 'preview' )->escaped() . "</h2>" .
$wgOut->parse( $note, true, /* interface */true ) . $conflict . "</div>\n";
$pageLang = $this->mTitle->getPageLanguage();
$attribs = array( 'lang' => $pageLang->getCode(), 'dir' => $pageLang->getDir(),
- 'class' => 'mw-content-'.$pageLang->getDir() );
+ 'class' => 'mw-content-' . $pageLang->getDir() );
$previewHTML = Html::rawElement( 'div', $attribs, $previewHTML );
wfProfileOut( __METHOD__ );
@@ -2637,9 +2706,9 @@ HTML
if ( !isset( $this->mParserOutput ) ) {
return $templates;
}
- foreach( $this->mParserOutput->getTemplates() as $ns => $template) {
- foreach( array_keys( $template ) as $dbk ) {
- $templates[] = Title::makeTitle($ns, $dbk);
+ foreach ( $this->mParserOutput->getTemplates() as $ns => $template ) {
+ foreach ( array_keys( $template ) as $dbk ) {
+ $templates[] = Title::makeTitle( $ns, $dbk );
}
}
return $templates;
@@ -2680,8 +2749,8 @@ HTML
'id' => 'mw-editbutton-bold',
'open' => '\'\'\'',
'close' => '\'\'\'',
- 'sample' => wfMsg( 'bold_sample' ),
- 'tip' => wfMsg( 'bold_tip' ),
+ 'sample' => wfMessage( 'bold_sample' )->text(),
+ 'tip' => wfMessage( 'bold_tip' )->text(),
'key' => 'B'
),
array(
@@ -2689,8 +2758,8 @@ HTML
'id' => 'mw-editbutton-italic',
'open' => '\'\'',
'close' => '\'\'',
- 'sample' => wfMsg( 'italic_sample' ),
- 'tip' => wfMsg( 'italic_tip' ),
+ 'sample' => wfMessage( 'italic_sample' )->text(),
+ 'tip' => wfMessage( 'italic_tip' )->text(),
'key' => 'I'
),
array(
@@ -2698,8 +2767,8 @@ HTML
'id' => 'mw-editbutton-link',
'open' => '[[',
'close' => ']]',
- 'sample' => wfMsg( 'link_sample' ),
- 'tip' => wfMsg( 'link_tip' ),
+ 'sample' => wfMessage( 'link_sample' )->text(),
+ 'tip' => wfMessage( 'link_tip' )->text(),
'key' => 'L'
),
array(
@@ -2707,8 +2776,8 @@ HTML
'id' => 'mw-editbutton-extlink',
'open' => '[',
'close' => ']',
- 'sample' => wfMsg( 'extlink_sample' ),
- 'tip' => wfMsg( 'extlink_tip' ),
+ 'sample' => wfMessage( 'extlink_sample' )->text(),
+ 'tip' => wfMessage( 'extlink_tip' )->text(),
'key' => 'X'
),
array(
@@ -2716,8 +2785,8 @@ HTML
'id' => 'mw-editbutton-headline',
'open' => "\n== ",
'close' => " ==\n",
- 'sample' => wfMsg( 'headline_sample' ),
- 'tip' => wfMsg( 'headline_tip' ),
+ 'sample' => wfMessage( 'headline_sample' )->text(),
+ 'tip' => wfMessage( 'headline_tip' )->text(),
'key' => 'H'
),
$imagesAvailable ? array(
@@ -2725,8 +2794,8 @@ HTML
'id' => 'mw-editbutton-image',
'open' => '[[' . $wgContLang->getNsText( NS_FILE ) . ':',
'close' => ']]',
- 'sample' => wfMsg( 'image_sample' ),
- 'tip' => wfMsg( 'image_tip' ),
+ 'sample' => wfMessage( 'image_sample' )->text(),
+ 'tip' => wfMessage( 'image_tip' )->text(),
'key' => 'D',
) : false,
$imagesAvailable ? array(
@@ -2734,17 +2803,17 @@ HTML
'id' => 'mw-editbutton-media',
'open' => '[[' . $wgContLang->getNsText( NS_MEDIA ) . ':',
'close' => ']]',
- 'sample' => wfMsg( 'media_sample' ),
- 'tip' => wfMsg( 'media_tip' ),
+ 'sample' => wfMessage( 'media_sample' )->text(),
+ 'tip' => wfMessage( 'media_tip' )->text(),
'key' => 'M'
) : false,
- $wgUseTeX ? array(
+ $wgUseTeX ? array(
'image' => $wgLang->getImageFile( 'button-math' ),
'id' => 'mw-editbutton-math',
'open' => "<math>",
'close' => "</math>",
- 'sample' => wfMsg( 'math_sample' ),
- 'tip' => wfMsg( 'math_tip' ),
+ 'sample' => wfMessage( 'math_sample' )->text(),
+ 'tip' => wfMessage( 'math_tip' )->text(),
'key' => 'C'
) : false,
array(
@@ -2752,8 +2821,8 @@ HTML
'id' => 'mw-editbutton-nowiki',
'open' => "<nowiki>",
'close' => "</nowiki>",
- 'sample' => wfMsg( 'nowiki_sample' ),
- 'tip' => wfMsg( 'nowiki_tip' ),
+ 'sample' => wfMessage( 'nowiki_sample' )->text(),
+ 'tip' => wfMessage( 'nowiki_tip' )->text(),
'key' => 'N'
),
array(
@@ -2762,7 +2831,7 @@ HTML
'open' => '--~~~~',
'close' => '',
'sample' => '',
- 'tip' => wfMsg( 'sig_tip' ),
+ 'tip' => wfMessage( 'sig_tip' )->text(),
'key' => 'Y'
),
array(
@@ -2771,7 +2840,7 @@ HTML
'open' => "\n----\n",
'close' => '',
'sample' => '',
- 'tip' => wfMsg( 'hr_tip' ),
+ 'tip' => wfMessage( 'hr_tip' )->text(),
'key' => 'R'
)
);
@@ -2797,7 +2866,7 @@ HTML
$script .= Xml::encodeJsCall( 'mw.toolbar.addButton', $params );
}
-
+
// This used to be called on DOMReady from mediawiki.action.edit, which
// ended up causing race conditions with the setup code above.
$script .= "\n" .
@@ -2818,7 +2887,7 @@ HTML
* Returns an array of html code of the following checkboxes:
* minor and watch
*
- * @param $tabindex Current tabindex
+ * @param $tabindex int Current tabindex
* @param $checked Array of checkbox => bool, where bool indicates the checked
* status of the checkbox
*
@@ -2832,11 +2901,11 @@ HTML
// don't show the minor edit checkbox if it's a new page or section
if ( !$this->isNew ) {
$checkboxes['minor'] = '';
- $minorLabel = wfMsgExt( 'minoredit', array( 'parseinline' ) );
+ $minorLabel = wfMessage( 'minoredit' )->parse();
if ( $wgUser->isAllowed( 'minoredit' ) ) {
$attribs = array(
'tabindex' => ++$tabindex,
- 'accesskey' => wfMsg( 'accesskey-minoredit' ),
+ 'accesskey' => wfMessage( 'accesskey-minoredit' )->text(),
'id' => 'wpMinoredit',
);
$checkboxes['minor'] =
@@ -2847,12 +2916,12 @@ HTML
}
}
- $watchLabel = wfMsgExt( 'watchthis', array( 'parseinline' ) );
+ $watchLabel = wfMessage( 'watchthis' )->parse();
$checkboxes['watch'] = '';
if ( $wgUser->isLoggedIn() ) {
$attribs = array(
'tabindex' => ++$tabindex,
- 'accesskey' => wfMsg( 'accesskey-watch' ),
+ 'accesskey' => wfMessage( 'accesskey-watch' )->text(),
'id' => 'wpWatchthis',
);
$checkboxes['watch'] =
@@ -2869,7 +2938,7 @@ HTML
* Returns an array of html code of the following buttons:
* save, diff, preview and live
*
- * @param $tabindex Current tabindex
+ * @param $tabindex int Current tabindex
*
* @return array
*/
@@ -2881,11 +2950,11 @@ HTML
'name' => 'wpSave',
'type' => 'submit',
'tabindex' => ++$tabindex,
- 'value' => wfMsg( 'savearticle' ),
- 'accesskey' => wfMsg( 'accesskey-save' ),
- 'title' => wfMsg( 'tooltip-save' ).' ['.wfMsg( 'accesskey-save' ).']',
+ 'value' => wfMessage( 'savearticle' )->text(),
+ 'accesskey' => wfMessage( 'accesskey-save' )->text(),
+ 'title' => wfMessage( 'tooltip-save' )->text() . ' [' . wfMessage( 'accesskey-save' )->text() . ']',
);
- $buttons['save'] = Xml::element('input', $temp, '');
+ $buttons['save'] = Xml::element( 'input', $temp, '' );
++$tabindex; // use the same for preview and live preview
$temp = array(
@@ -2893,9 +2962,9 @@ HTML
'name' => 'wpPreview',
'type' => 'submit',
'tabindex' => $tabindex,
- 'value' => wfMsg( 'showpreview' ),
- 'accesskey' => wfMsg( 'accesskey-preview' ),
- 'title' => wfMsg( 'tooltip-preview' ) . ' [' . wfMsg( 'accesskey-preview' ) . ']',
+ 'value' => wfMessage( 'showpreview' )->text(),
+ 'accesskey' => wfMessage( 'accesskey-preview' )->text(),
+ 'title' => wfMessage( 'tooltip-preview' )->text() . ' [' . wfMessage( 'accesskey-preview' )->text() . ']',
);
$buttons['preview'] = Xml::element( 'input', $temp, '' );
$buttons['live'] = '';
@@ -2905,9 +2974,9 @@ HTML
'name' => 'wpDiff',
'type' => 'submit',
'tabindex' => ++$tabindex,
- 'value' => wfMsg( 'showdiff' ),
- 'accesskey' => wfMsg( 'accesskey-diff' ),
- 'title' => wfMsg( 'tooltip-diff' ) . ' [' . wfMsg( 'accesskey-diff' ) . ']',
+ 'value' => wfMessage( 'showdiff' )->text(),
+ 'accesskey' => wfMessage( 'accesskey-diff' )->text(),
+ 'title' => wfMessage( 'tooltip-diff' )->text() . ' [' . wfMessage( 'accesskey-diff' )->text() . ']',
);
$buttons['diff'] = Xml::element( 'input', $temp, '' );
@@ -2923,8 +2992,8 @@ HTML
* failure, etc).
*
* @todo This doesn't include category or interlanguage links.
- * Would need to enhance it a bit, <s>maybe wrap them in XML
- * or something...</s> that might also require more skin
+ * Would need to enhance it a bit, "<s>maybe wrap them in XML
+ * or something...</s>" that might also require more skin
* initialization, so check whether that's a problem.
*/
function livePreview() {
@@ -2954,7 +3023,7 @@ HTML
wfDeprecated( __METHOD__, '1.19' );
global $wgUser;
- throw new UserBlockedError( $wgUser->mBlock );
+ throw new UserBlockedError( $wgUser->getBlock() );
}
/**
@@ -2988,7 +3057,7 @@ HTML
$wgOut->prepareErrorPage( wfMessage( 'nosuchsectiontitle' ) );
- $res = wfMsgExt( 'nosuchsectiontext', 'parse', $this->section );
+ $res = wfMessage( 'nosuchsectiontext', $this->section )->parseAsBlock();
wfRunHooks( 'EditPageNoSuchSection', array( &$this, &$res ) );
$wgOut->addHTML( $res );
@@ -2998,12 +3067,12 @@ HTML
/**
* Produce the stock "your edit contains spam" page
*
- * @param $match Text which triggered one or more filters
+ * @param $match string Text which triggered one or more filters
* @deprecated since 1.17 Use method spamPageWithContent() instead
*/
static function spamPage( $match = false ) {
wfDeprecated( __METHOD__, '1.17' );
-
+
global $wgOut, $wgTitle;
$wgOut->prepareErrorPage( wfMessage( 'spamprotectiontitle' ) );
@@ -3021,12 +3090,15 @@ HTML
/**
* Show "your edit contains spam" page with your diff and text
*
- * @param $match Text which triggered one or more filters
+ * @param $match string|Array|bool Text (or array of texts) which triggered one or more filters
*/
public function spamPageWithContent( $match = false ) {
- global $wgOut;
+ global $wgOut, $wgLang;
$this->textbox2 = $this->textbox1;
+ if( is_array( $match ) ){
+ $match = $wgLang->listToText( $match );
+ }
$wgOut->prepareErrorPage( wfMessage( 'spamprotectiontitle' ) );
$wgOut->addHTML( '<div id="spamprotected">' );
@@ -3037,9 +3109,7 @@ HTML
$wgOut->addHTML( '</div>' );
$wgOut->wrapWikiMsg( '<h2>$1</h2>', "yourdiff" );
- $de = new DifferenceEngine( $this->mArticle->getContext() );
- $de->setText( $this->getCurrentText(), $this->textbox2 );
- $de->showDiff( wfMsg( "storedversion" ), wfMsgExt( 'yourtext', 'parseinline' ) );
+ $this->showDiff();
$wgOut->wrapWikiMsg( '<h2>$1</h2>', "yourtext" );
$this->showTextbox2();
@@ -3066,14 +3136,16 @@ HTML
* @private
*/
function checkUnicodeCompliantBrowser() {
- global $wgBrowserBlackList;
- if ( empty( $_SERVER["HTTP_USER_AGENT"] ) ) {
+ global $wgBrowserBlackList, $wgRequest;
+
+ $currentbrowser = $wgRequest->getHeader( 'User-Agent' );
+ if ( $currentbrowser === false ) {
// No User-Agent header sent? Trust it by default...
return true;
}
- $currentbrowser = $_SERVER["HTTP_USER_AGENT"];
+
foreach ( $wgBrowserBlackList as $browser ) {
- if ( preg_match($browser, $currentbrowser) ) {
+ if ( preg_match( $browser, $currentbrowser ) ) {
return false;
}
}
@@ -3144,25 +3216,25 @@ HTML
$bytesleft = 0;
$result = "";
$working = 0;
- for( $i = 0; $i < strlen( $invalue ); $i++ ) {
+ for ( $i = 0; $i < strlen( $invalue ); $i++ ) {
$bytevalue = ord( $invalue[$i] );
- if ( $bytevalue <= 0x7F ) { //0xxx xxxx
+ if ( $bytevalue <= 0x7F ) { // 0xxx xxxx
$result .= chr( $bytevalue );
$bytesleft = 0;
- } elseif ( $bytevalue <= 0xBF ) { //10xx xxxx
+ } elseif ( $bytevalue <= 0xBF ) { // 10xx xxxx
$working = $working << 6;
- $working += ($bytevalue & 0x3F);
+ $working += ( $bytevalue & 0x3F );
$bytesleft--;
if ( $bytesleft <= 0 ) {
$result .= "&#x" . strtoupper( dechex( $working ) ) . ";";
}
- } elseif ( $bytevalue <= 0xDF ) { //110x xxxx
+ } elseif ( $bytevalue <= 0xDF ) { // 110x xxxx
$working = $bytevalue & 0x1F;
$bytesleft = 1;
- } elseif ( $bytevalue <= 0xEF ) { //1110 xxxx
+ } elseif ( $bytevalue <= 0xEF ) { // 1110 xxxx
$working = $bytevalue & 0x0F;
$bytesleft = 2;
- } else { //1111 0xxx
+ } else { // 1111 0xxx
$working = $bytevalue & 0x07;
$bytesleft = 3;
}
@@ -3181,20 +3253,20 @@ HTML
*/
function unmakesafe( $invalue ) {
$result = "";
- for( $i = 0; $i < strlen( $invalue ); $i++ ) {
- if ( ( substr( $invalue, $i, 3 ) == "&#x" ) && ( $invalue[$i+3] != '0' ) ) {
+ for ( $i = 0; $i < strlen( $invalue ); $i++ ) {
+ if ( ( substr( $invalue, $i, 3 ) == "&#x" ) && ( $invalue[$i + 3] != '0' ) ) {
$i += 3;
$hexstring = "";
do {
$hexstring .= $invalue[$i];
$i++;
- } while( ctype_xdigit( $invalue[$i] ) && ( $i < strlen( $invalue ) ) );
+ } while ( ctype_xdigit( $invalue[$i] ) && ( $i < strlen( $invalue ) ) );
// Do some sanity checks. These aren't needed for reversability,
// but should help keep the breakage down if the editor
// breaks one of the entities whilst editing.
- if ( (substr($invalue,$i,1)==";") and (strlen($hexstring) <= 6) ) {
- $codepoint = hexdec($hexstring);
+ if ( ( substr( $invalue, $i, 1 ) == ";" ) and ( strlen( $hexstring ) <= 6 ) ) {
+ $codepoint = hexdec( $hexstring );
$result .= codepointToUtf8( $codepoint );
} else {
$result .= "&#x" . $hexstring . substr( $invalue, $i, 1 );
diff --git a/includes/Exception.php b/includes/Exception.php
index 3bd89b6e..714f73e8 100644
--- a/includes/Exception.php
+++ b/includes/Exception.php
@@ -1,6 +1,21 @@
<?php
/**
- * Exception class and handler
+ * Exception class and handler.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * http://www.gnu.org/copyleft/gpl.html
*
* @file
*/
@@ -15,8 +30,11 @@
* @ingroup Exception
*/
class MWException extends Exception {
+ var $logId;
+
/**
- * Should the exception use $wgOut to output the error ?
+ * Should the exception use $wgOut to output the error?
+ *
* @return bool
*/
function useOutputPage() {
@@ -27,7 +45,8 @@ class MWException extends Exception {
}
/**
- * Can the extension use wfMsg() to get i18n messages ?
+ * Can the extension use the Message class/wfMessage to get i18n-ed messages?
+ *
* @return bool
*/
function useMessageCache() {
@@ -45,19 +64,19 @@ class MWException extends Exception {
/**
* Run hook to allow extensions to modify the text of the exception
*
- * @param $name String: class name of the exception
- * @param $args Array: arguments to pass to the callback functions
- * @return Mixed: string to output or null if any hook has been called
+ * @param $name string: class name of the exception
+ * @param $args array: arguments to pass to the callback functions
+ * @return string|null string to output or null if any hook has been called
*/
function runHooks( $name, $args = array() ) {
global $wgExceptionHooks;
if ( !isset( $wgExceptionHooks ) || !is_array( $wgExceptionHooks ) ) {
- return; // Just silently ignore
+ return null; // Just silently ignore
}
if ( !array_key_exists( $name, $wgExceptionHooks ) || !is_array( $wgExceptionHooks[ $name ] ) ) {
- return;
+ return null;
}
$hooks = $wgExceptionHooks[ $name ];
@@ -74,22 +93,23 @@ class MWException extends Exception {
return $result;
}
}
+ return null;
}
/**
* Get a message from i18n
*
- * @param $key String: message name
- * @param $fallback String: default message if the message cache can't be
+ * @param $key string: message name
+ * @param $fallback string: default message if the message cache can't be
* called by the exception
* The function also has other parameters that are arguments for the message
- * @return String message with arguments replaced
+ * @return string message with arguments replaced
*/
function msg( $key, $fallback /*[, params...] */ ) {
$args = array_slice( func_get_args(), 2 );
if ( $this->useMessageCache() ) {
- return wfMsgNoTrans( $key, $args );
+ return wfMessage( $key, $args )->plain();
} else {
return wfMsgReplaceArgs( $fallback, $args );
}
@@ -100,7 +120,7 @@ class MWException extends Exception {
* backtrace to the error, otherwise show a message to ask to set it to true
* to show that information.
*
- * @return String html to output
+ * @return string html to output
*/
function getHTML() {
global $wgShowExceptionDetails;
@@ -110,15 +130,22 @@ class MWException extends Exception {
'</p><p>Backtrace:</p><p>' . nl2br( htmlspecialchars( $this->getTraceAsString() ) ) .
"</p>\n";
} else {
- return "<p>Set <b><tt>\$wgShowExceptionDetails = true;</tt></b> " .
+ return
+ "<div class=\"errorbox\">" .
+ '[' . $this->getLogId() . '] ' .
+ gmdate( 'Y-m-d H:i:s' ) .
+ ": Fatal exception of type " . get_class( $this ) . "</div>\n" .
+ "<!-- Set \$wgShowExceptionDetails = true; " .
"at the bottom of LocalSettings.php to show detailed " .
- "debugging information.</p>";
+ "debugging information. -->";
}
}
/**
+ * Get the text to display when reporting the error on the command line.
* If $wgShowExceptionDetails is true, return a text message with a
* backtrace to the error.
+ *
* @return string
*/
function getText() {
@@ -134,22 +161,38 @@ class MWException extends Exception {
}
/**
- * Return titles of this error page
- * @return String
+ * Return the title of the page when reporting this error in a HTTP response.
+ *
+ * @return string
*/
function getPageTitle() {
return $this->msg( 'internalerror', "Internal error" );
}
/**
+ * Get a random ID for this error.
+ * This allows to link the exception to its correspoding log entry when
+ * $wgShowExceptionDetails is set to false.
+ *
+ * @return string
+ */
+ function getLogId() {
+ if ( $this->logId === null ) {
+ $this->logId = wfRandomString( 8 );
+ }
+ return $this->logId;
+ }
+
+ /**
* Return the requested URL and point to file and line number from which the
- * exception occured
+ * exception occurred
*
- * @return String
+ * @return string
*/
function getLogMessage() {
global $wgRequest;
+ $id = $this->getLogId();
$file = $this->getFile();
$line = $this->getLine();
$message = $this->getMessage();
@@ -163,10 +206,12 @@ class MWException extends Exception {
$url = '[no req]';
}
- return "$url Exception from line $line of $file: $message";
+ return "[$id] $url Exception from line $line of $file: $message";
}
- /** Output the exception report using HTML */
+ /**
+ * Output the exception report using HTML.
+ */
function reportHTML() {
global $wgOut;
if ( $this->useOutputPage() ) {
@@ -182,13 +227,19 @@ class MWException extends Exception {
$wgOut->output();
} else {
header( "Content-Type: text/html; charset=utf-8" );
+ echo "<!doctype html>\n" .
+ '<html><head>' .
+ '<title>' . htmlspecialchars( $this->getPageTitle() ) . '</title>' .
+ "</head><body>\n";
+
$hookResult = $this->runHooks( get_class( $this ) . "Raw" );
if ( $hookResult ) {
- die( $hookResult );
+ echo $hookResult;
+ } else {
+ echo $this->getHTML();
}
- echo $this->getHTML();
- die(1);
+ echo "</body></html>\n";
}
}
@@ -197,21 +248,35 @@ class MWException extends Exception {
* It will be either HTML or plain text based on isCommandLine().
*/
function report() {
+ global $wgLogExceptionBacktrace;
$log = $this->getLogMessage();
if ( $log ) {
- wfDebugLog( 'exception', $log );
+ if ( $wgLogExceptionBacktrace ) {
+ wfDebugLog( 'exception', $log . "\n" . $this->getTraceAsString() . "\n" );
+ } else {
+ wfDebugLog( 'exception', $log );
+ }
}
- if ( self::isCommandLine() ) {
+ if ( defined( 'MW_API' ) ) {
+ // Unhandled API exception, we can't be sure that format printer is alive
+ header( 'MediaWiki-API-Error: internal_api_error_' . get_class( $this ) );
+ wfHttpError(500, 'Internal Server Error', $this->getText() );
+ } elseif ( self::isCommandLine() ) {
MWExceptionHandler::printError( $this->getText() );
} else {
+ header( "HTTP/1.1 500 MediaWiki exception" );
+ header( "Status: 500 MediaWiki exception", true );
+
$this->reportHTML();
}
}
/**
- * @static
+ * Check whether we are in command line mode or not to report the exception
+ * in the correct format.
+ *
* @return bool
*/
static function isCommandLine() {
@@ -222,6 +287,8 @@ class MWException extends Exception {
/**
* Exception class which takes an HTML error message, and does not
* produce a backtrace. Replacement for OutputPage::fatalError().
+ *
+ * @since 1.7
* @ingroup Exception
*/
class FatalError extends MWException {
@@ -242,14 +309,20 @@ class FatalError extends MWException {
}
/**
- * An error page which can definitely be safely rendered using the OutputPage
+ * An error page which can definitely be safely rendered using the OutputPage.
+ *
+ * @since 1.7
* @ingroup Exception
*/
class ErrorPageError extends MWException {
public $title, $msg, $params;
/**
- * Note: these arguments are keys into wfMsg(), not text!
+ * Note: these arguments are keys into wfMessage(), not text!
+ *
+ * @param $title string|Message Message key (string) for page title, or a Message object
+ * @param $msg string|Message Message key (string) for error text, or a Message object
+ * @param $params array with parameters to wfMessage()
*/
function __construct( $title, $msg, $params = null ) {
$this->title = $title;
@@ -259,14 +332,13 @@ class ErrorPageError extends MWException {
if( $msg instanceof Message ){
parent::__construct( $msg );
} else {
- parent::__construct( wfMsg( $msg ) );
+ parent::__construct( wfMessage( $msg )->text() );
}
}
function report() {
global $wgOut;
-
$wgOut->showErrorPage( $this->title, $this->msg, $this->params );
$wgOut->output();
}
@@ -276,12 +348,14 @@ class ErrorPageError extends MWException {
* Show an error page on a badtitle.
* Similar to ErrorPage, but emit a 400 HTTP error code to let mobile
* browser it is not really a valid content.
+ *
+ * @since 1.19
+ * @ingroup Exception
*/
class BadTitleError extends ErrorPageError {
-
/**
- * @param $msg string A message key (default: 'badtitletext')
- * @param $params Array parameter to wfMsg()
+ * @param $msg string|Message A message key (default: 'badtitletext')
+ * @param $params Array parameter to wfMessage()
*/
function __construct( $msg = 'badtitletext', $params = null ) {
parent::__construct( 'badtitle', $msg, $params );
@@ -305,6 +379,8 @@ class BadTitleError extends ErrorPageError {
/**
* Show an error when a user tries to do something they do not have the necessary
* permissions for.
+ *
+ * @since 1.18
* @ingroup Exception
*/
class PermissionsError extends ErrorPageError {
@@ -341,7 +417,9 @@ class PermissionsError extends ErrorPageError {
/**
* Show an error when the wiki is locked/read-only and the user tries to do
- * something that requires write access
+ * something that requires write access.
+ *
+ * @since 1.18
* @ingroup Exception
*/
class ReadOnlyError extends ErrorPageError {
@@ -355,7 +433,9 @@ class ReadOnlyError extends ErrorPageError {
}
/**
- * Show an error when the user hits a rate limit
+ * Show an error when the user hits a rate limit.
+ *
+ * @since 1.18
* @ingroup Exception
*/
class ThrottledError extends ErrorPageError {
@@ -369,12 +449,14 @@ class ThrottledError extends ErrorPageError {
public function report(){
global $wgOut;
$wgOut->setStatusCode( 503 );
- return parent::report();
+ parent::report();
}
}
/**
- * Show an error when the user tries to do something whilst blocked
+ * Show an error when the user tries to do something whilst blocked.
+ *
+ * @since 1.18
* @ingroup Exception
*/
class UserBlockedError extends ErrorPageError {
@@ -391,7 +473,7 @@ class UserBlockedError extends ErrorPageError {
$reason = $block->mReason;
if( $reason == '' ) {
- $reason = wfMsg( 'blockednoreason' );
+ $reason = wfMessage( 'blockednoreason' )->text();
}
/* $ip returns who *is* being blocked, $intended contains who was meant to be blocked.
@@ -416,9 +498,57 @@ class UserBlockedError extends ErrorPageError {
}
/**
+ * Shows a generic "user is not logged in" error page.
+ *
+ * This is essentially an ErrorPageError exception which by default use the
+ * 'exception-nologin' as a title and 'exception-nologin-text' for the message.
+ * @see bug 37627
+ * @since 1.20
+ *
+ * @par Example:
+ * @code
+ * if( $user->isAnon ) {
+ * throw new UserNotLoggedIn();
+ * }
+ * @endcode
+ *
+ * Please note the parameters are mixed up compared to ErrorPageError, this
+ * is done to be able to simply specify a reason whitout overriding the default
+ * title.
+ *
+ * @par Example:
+ * @code
+ * if( $user->isAnon ) {
+ * throw new UserNotLoggedIn( 'action-require-loggedin' );
+ * }
+ * @endcode
+ *
+ * @ingroup Exception
+ */
+class UserNotLoggedIn extends ErrorPageError {
+
+ /**
+ * @param $reasonMsg A message key containing the reason for the error.
+ * Optional, default: 'exception-nologin-text'
+ * @param $titleMsg A message key to set the page title.
+ * Optional, default: 'exception-nologin'
+ * @param $params Parameters to wfMessage().
+ * Optiona, default: null
+ */
+ public function __construct(
+ $reasonMsg = 'exception-nologin-text',
+ $titleMsg = 'exception-nologin',
+ $params = null
+ ) {
+ parent::__construct( $titleMsg, $reasonMsg, $params );
+ }
+}
+
+/**
* Show an error that looks like an HTTP server error.
* Replacement for wfHttpError().
*
+ * @since 1.19
* @ingroup Exception
*/
class HttpError extends MWException {
@@ -438,7 +568,7 @@ class HttpError extends MWException {
$this->content = $content;
}
- public function reportHTML() {
+ public function report() {
$httpMessage = HttpStatus::getMessage( $this->httpCode );
header( "Status: {$this->httpCode} {$httpMessage}" );
@@ -458,7 +588,7 @@ class HttpError extends MWException {
$content = htmlspecialchars( $this->content );
}
- print "<!DOCTYPE HTML PUBLIC \"-//IETF//DTD HTML 2.0//EN\">\n".
+ print "<!DOCTYPE html>\n".
"<html><head><title>$header</title></head>\n" .
"<body><h1>$header</h1><p>$content</p></body></html>\n";
}
@@ -508,7 +638,7 @@ class MWExceptionHandler {
if ( $cmdLine ) {
self::printError( $message );
} else {
- self::escapeEchoAndDie( $message );
+ echo nl2br( htmlspecialchars( $message ) ) . "\n";
}
}
} else {
@@ -522,7 +652,7 @@ class MWExceptionHandler {
if ( $cmdLine ) {
self::printError( $message );
} else {
- self::escapeEchoAndDie( $message );
+ echo nl2br( htmlspecialchars( $message ) ) . "\n";
}
}
}
@@ -530,7 +660,8 @@ class MWExceptionHandler {
/**
* Print a message, if possible to STDERR.
* Use this in command line mode only (see isCommandLine)
- * @param $message String Failure text
+ *
+ * @param $message string Failure text
*/
public static function printError( $message ) {
# NOTE: STDERR may not be available, especially if php-cgi is used from the command line (bug #15602).
@@ -543,16 +674,6 @@ class MWExceptionHandler {
}
/**
- * Print a message after escaping it and converting newlines to <br>
- * Use this for non-command line failures
- * @param $message String Failure text
- */
- private static function escapeEchoAndDie( $message ) {
- echo nl2br( htmlspecialchars( $message ) ) . "\n";
- die(1);
- }
-
- /**
* Exception handler which simulates the appropriate catch() handling:
*
* try {
diff --git a/includes/Export.php b/includes/Export.php
index 7773d03c..f01fb237 100644
--- a/includes/Export.php
+++ b/includes/Export.php
@@ -49,6 +49,23 @@ class WikiExporter {
const TEXT = 0;
const STUB = 1;
+ var $buffer;
+
+ var $text;
+
+ /**
+ * @var DumpOutput
+ */
+ var $sink;
+
+ /**
+ * Returns the export schema version.
+ * @return string
+ */
+ public static function schemaVersion() {
+ return "0.7";
+ }
+
/**
* If using WikiExporter::STREAM to stream a large amount of data,
* provide a database connection which is not managed by
@@ -103,7 +120,7 @@ class WikiExporter {
* the most recent version.
*/
public function allPages() {
- return $this->dumpFrom( '' );
+ $this->dumpFrom( '' );
}
/**
@@ -118,7 +135,7 @@ class WikiExporter {
if ( $end ) {
$condition .= ' AND page_id < ' . intval( $end );
}
- return $this->dumpFrom( $condition );
+ $this->dumpFrom( $condition );
}
/**
@@ -133,27 +150,34 @@ class WikiExporter {
if ( $end ) {
$condition .= ' AND rev_id < ' . intval( $end );
}
- return $this->dumpFrom( $condition );
+ $this->dumpFrom( $condition );
}
/**
* @param $title Title
*/
public function pageByTitle( $title ) {
- return $this->dumpFrom(
+ $this->dumpFrom(
'page_namespace=' . $title->getNamespace() .
' AND page_title=' . $this->db->addQuotes( $title->getDBkey() ) );
}
+ /**
+ * @param $name string
+ * @throws MWException
+ */
public function pageByName( $name ) {
$title = Title::newFromText( $name );
if ( is_null( $title ) ) {
throw new MWException( "Can't export invalid title" );
} else {
- return $this->pageByTitle( $title );
+ $this->pageByTitle( $title );
}
}
+ /**
+ * @param $names array
+ */
public function pagesByName( $names ) {
foreach ( $names as $name ) {
$this->pageByName( $name );
@@ -161,20 +185,28 @@ class WikiExporter {
}
public function allLogs() {
- return $this->dumpFrom( '' );
+ $this->dumpFrom( '' );
}
+ /**
+ * @param $start int
+ * @param $end int
+ */
public function logsByRange( $start, $end ) {
$condition = 'log_id >= ' . intval( $start );
if ( $end ) {
$condition .= ' AND log_id < ' . intval( $end );
}
- return $this->dumpFrom( $condition );
+ $this->dumpFrom( $condition );
}
- # Generates the distinct list of authors of an article
- # Not called by default (depends on $this->list_authors)
- # Can be set by Special:Export when not exporting whole history
+ /**
+ * Generates the distinct list of authors of an article
+ * Not called by default (depends on $this->list_authors)
+ * Can be set by Special:Export when not exporting whole history
+ *
+ * @param $cond
+ */
protected function do_list_authors( $cond ) {
wfProfileIn( __METHOD__ );
$this->author_list = "<contributors>";
@@ -205,13 +237,15 @@ class WikiExporter {
wfProfileOut( __METHOD__ );
}
+ /**
+ * @param $cond string
+ * @throws MWException
+ * @throws Exception
+ */
protected function dumpFrom( $cond = '' ) {
wfProfileIn( __METHOD__ );
# For logging dumps...
if ( $this->history & self::LOGS ) {
- if ( $this->buffer == WikiExporter::STREAM ) {
- $prev = $this->db->bufferResults( false );
- }
$where = array( 'user_id = log_user' );
# Hide private logs
$hideLogs = LogEventsList::getExcludeClause( $this->db );
@@ -220,16 +254,49 @@ class WikiExporter {
if ( $cond ) $where[] = $cond;
# Get logging table name for logging.* clause
$logging = $this->db->tableName( 'logging' );
- $result = $this->db->select( array( 'logging', 'user' ),
- array( "{$logging}.*", 'user_name' ), // grab the user name
- $where,
- __METHOD__,
- array( 'ORDER BY' => 'log_id', 'USE INDEX' => array( 'logging' => 'PRIMARY' ) )
- );
- $wrapper = $this->db->resultObject( $result );
- $this->outputLogStream( $wrapper );
+
if ( $this->buffer == WikiExporter::STREAM ) {
- $this->db->bufferResults( $prev );
+ $prev = $this->db->bufferResults( false );
+ }
+ $wrapper = null; // Assuring $wrapper is not undefined, if exception occurs early
+ try {
+ $result = $this->db->select( array( 'logging', 'user' ),
+ array( "{$logging}.*", 'user_name' ), // grab the user name
+ $where,
+ __METHOD__,
+ array( 'ORDER BY' => 'log_id', 'USE INDEX' => array( 'logging' => 'PRIMARY' ) )
+ );
+ $wrapper = $this->db->resultObject( $result );
+ $this->outputLogStream( $wrapper );
+ if ( $this->buffer == WikiExporter::STREAM ) {
+ $this->db->bufferResults( $prev );
+ }
+ } catch ( Exception $e ) {
+ // Throwing the exception does not reliably free the resultset, and
+ // would also leave the connection in unbuffered mode.
+
+ // Freeing result
+ try {
+ if ( $wrapper ) {
+ $wrapper->free();
+ }
+ } catch ( Exception $e2 ) {
+ // Already in panic mode -> ignoring $e2 as $e has
+ // higher priority
+ }
+
+ // Putting database back in previous buffer mode
+ try {
+ if ( $this->buffer == WikiExporter::STREAM ) {
+ $this->db->bufferResults( $prev );
+ }
+ } catch ( Exception $e2 ) {
+ // Already in panic mode -> ignoring $e2 as $e has
+ // higher priority
+ }
+
+ // Inform caller about problem
+ throw $e;
}
# For page dumps...
} else {
@@ -279,7 +346,7 @@ class WikiExporter {
} elseif ( $this->history & WikiExporter::RANGE ) {
# Dump of revisions within a specified range
$join['revision'] = array( 'INNER JOIN', 'page_id=rev_page' );
- $opts['ORDER BY'] = 'rev_page ASC, rev_id ASC';
+ $opts['ORDER BY'] = array( 'rev_page ASC', 'rev_id ASC' );
} else {
# Uknown history specification parameter?
wfProfileOut( __METHOD__ );
@@ -300,20 +367,46 @@ class WikiExporter {
$prev = $this->db->bufferResults( false );
}
- wfRunHooks( 'ModifyExportQuery',
+ $wrapper = null; // Assuring $wrapper is not undefined, if exception occurs early
+ try {
+ wfRunHooks( 'ModifyExportQuery',
array( $this->db, &$tables, &$cond, &$opts, &$join ) );
- # Do the query!
- $result = $this->db->select( $tables, '*', $cond, __METHOD__, $opts, $join );
- $wrapper = $this->db->resultObject( $result );
- # Output dump results
- $this->outputPageStream( $wrapper );
- if ( $this->list_authors ) {
+ # Do the query!
+ $result = $this->db->select( $tables, '*', $cond, __METHOD__, $opts, $join );
+ $wrapper = $this->db->resultObject( $result );
+ # Output dump results
$this->outputPageStream( $wrapper );
- }
- if ( $this->buffer == WikiExporter::STREAM ) {
- $this->db->bufferResults( $prev );
+ if ( $this->buffer == WikiExporter::STREAM ) {
+ $this->db->bufferResults( $prev );
+ }
+ } catch ( Exception $e ) {
+ // Throwing the exception does not reliably free the resultset, and
+ // would also leave the connection in unbuffered mode.
+
+ // Freeing result
+ try {
+ if ( $wrapper ) {
+ $wrapper->free();
+ }
+ } catch ( Exception $e2 ) {
+ // Already in panic mode -> ignoring $e2 as $e has
+ // higher priority
+ }
+
+ // Putting database back in previous buffer mode
+ try {
+ if ( $this->buffer == WikiExporter::STREAM ) {
+ $this->db->bufferResults( $prev );
+ }
+ } catch ( Exception $e2 ) {
+ // Already in panic mode -> ignoring $e2 as $e has
+ // higher priority
+ }
+
+ // Inform caller about problem
+ throw $e;
}
}
wfProfileOut( __METHOD__ );
@@ -324,7 +417,7 @@ class WikiExporter {
* The result set should be sorted/grouped by page to avoid duplicate
* page records in the output.
*
- * The result set will be freed once complete. Should be safe for
+ * Should be safe for
* streaming (non-buffered) queries, as long as it was made on a
* separate database connection not managed by LoadBalancer; some
* blob storage types will make queries to pull source data.
@@ -363,6 +456,9 @@ class WikiExporter {
}
}
+ /**
+ * @param $resultset array
+ */
protected function outputLogStream( $resultset ) {
foreach ( $resultset as $row ) {
$output = $this->writer->writeLogItem( $row );
@@ -377,14 +473,16 @@ class WikiExporter {
class XmlDumpWriter {
/**
* Returns the export schema version.
+ * @deprecated in 1.20; use WikiExporter::schemaVersion() instead
* @return string
*/
function schemaVersion() {
- return "0.6";
+ wfDeprecated( __METHOD__, '1.20' );
+ return WikiExporter::schemaVersion();
}
/**
- * Opens the XML output stream's root <mediawiki> element.
+ * Opens the XML output stream's root "<mediawiki>" element.
* This does not include an xml directive, so is safe to include
* as a subelement in a larger XML stream. Namespace and XML Schema
* references are included.
@@ -395,7 +493,7 @@ class XmlDumpWriter {
*/
function openStream() {
global $wgLanguageCode;
- $ver = $this->schemaVersion();
+ $ver = WikiExporter::schemaVersion();
return Xml::element( 'mediawiki', array(
'xmlns' => "http://www.mediawiki.org/xml/export-$ver/",
'xmlns:xsi' => "http://www.w3.org/2001/XMLSchema-instance",
@@ -408,6 +506,9 @@ class XmlDumpWriter {
$this->siteInfo();
}
+ /**
+ * @return string
+ */
function siteInfo() {
$info = array(
$this->sitename(),
@@ -420,20 +521,32 @@ class XmlDumpWriter {
"\n </siteinfo>\n";
}
+ /**
+ * @return string
+ */
function sitename() {
global $wgSitename;
return Xml::element( 'sitename', array(), $wgSitename );
}
+ /**
+ * @return string
+ */
function generator() {
global $wgVersion;
return Xml::element( 'generator', array(), "MediaWiki $wgVersion" );
}
+ /**
+ * @return string
+ */
function homelink() {
return Xml::element( 'base', array(), Title::newMainPage()->getCanonicalUrl() );
}
+ /**
+ * @return string
+ */
function caseSetting() {
global $wgCapitalLinks;
// "case-insensitive" option is reserved for future
@@ -441,6 +554,9 @@ class XmlDumpWriter {
return Xml::element( 'case', array(), $sensitivity );
}
+ /**
+ * @return string
+ */
function namespaces() {
global $wgContLang;
$spaces = "<namespaces>\n";
@@ -466,7 +582,7 @@ class XmlDumpWriter {
}
/**
- * Opens a <page> section on the output stream, with data
+ * Opens a "<page>" section on the output stream, with data
* from the given database row.
*
* @param $row object
@@ -486,13 +602,7 @@ class XmlDumpWriter {
$out .= ' ' . Xml::element( 'redirect', array( 'title' => self::canonicalTitle( $redirect ) ) ) . "\n";
}
}
-
- if ( $row->rev_sha1 ) {
- $out .= " " . Xml::element('sha1', null, strval($row->rev_sha1) ) . "\n";
- } else {
- $out .= " <sha1/>\n";
- }
-
+
if ( $row->page_restrictions != '' ) {
$out .= ' ' . Xml::element( 'restrictions', array(),
strval( $row->page_restrictions ) ) . "\n";
@@ -504,16 +614,17 @@ class XmlDumpWriter {
}
/**
- * Closes a <page> section on the output stream.
+ * Closes a "<page>" section on the output stream.
*
* @access private
+ * @return string
*/
function closePage() {
return " </page>\n";
}
/**
- * Dumps a <revision> section on the output stream, with
+ * Dumps a "<revision>" section on the output stream, with
* data filled in from the given database row.
*
* @param $row object
@@ -525,6 +636,9 @@ class XmlDumpWriter {
$out = " <revision>\n";
$out .= " " . Xml::element( 'id', null, strval( $row->rev_id ) ) . "\n";
+ if( $row->rev_parent_id ) {
+ $out .= " " . Xml::element( 'parentid', null, strval( $row->rev_parent_id ) ) . "\n";
+ }
$out .= $this->writeTimestamp( $row->rev_timestamp );
@@ -540,7 +654,13 @@ class XmlDumpWriter {
if ( $row->rev_deleted & Revision::DELETED_COMMENT ) {
$out .= " " . Xml::element( 'comment', array( 'deleted' => 'deleted' ) ) . "\n";
} elseif ( $row->rev_comment != '' ) {
- $out .= " " . Xml::elementClean( 'comment', null, strval( $row->rev_comment ) ) . "\n";
+ $out .= " " . Xml::elementClean( 'comment', array(), strval( $row->rev_comment ) ) . "\n";
+ }
+
+ if ( $row->rev_sha1 && !( $row->rev_deleted & Revision::DELETED_TEXT ) ) {
+ $out .= " " . Xml::element('sha1', null, strval( $row->rev_sha1 ) ) . "\n";
+ } else {
+ $out .= " <sha1/>\n";
}
$text = '';
@@ -568,7 +688,7 @@ class XmlDumpWriter {
}
/**
- * Dumps a <logitem> section on the output stream, with
+ * Dumps a "<logitem>" section on the output stream, with
* data filled in from the given database row.
*
* @param $row object
@@ -578,64 +698,78 @@ class XmlDumpWriter {
function writeLogItem( $row ) {
wfProfileIn( __METHOD__ );
- $out = " <logitem>\n";
- $out .= " " . Xml::element( 'id', null, strval( $row->log_id ) ) . "\n";
+ $out = " <logitem>\n";
+ $out .= " " . Xml::element( 'id', null, strval( $row->log_id ) ) . "\n";
- $out .= $this->writeTimestamp( $row->log_timestamp );
+ $out .= $this->writeTimestamp( $row->log_timestamp, " " );
if ( $row->log_deleted & LogPage::DELETED_USER ) {
- $out .= " " . Xml::element( 'contributor', array( 'deleted' => 'deleted' ) ) . "\n";
+ $out .= " " . Xml::element( 'contributor', array( 'deleted' => 'deleted' ) ) . "\n";
} else {
- $out .= $this->writeContributor( $row->log_user, $row->user_name );
+ $out .= $this->writeContributor( $row->log_user, $row->user_name, " " );
}
if ( $row->log_deleted & LogPage::DELETED_COMMENT ) {
- $out .= " " . Xml::element( 'comment', array( 'deleted' => 'deleted' ) ) . "\n";
+ $out .= " " . Xml::element( 'comment', array( 'deleted' => 'deleted' ) ) . "\n";
} elseif ( $row->log_comment != '' ) {
- $out .= " " . Xml::elementClean( 'comment', null, strval( $row->log_comment ) ) . "\n";
+ $out .= " " . Xml::elementClean( 'comment', null, strval( $row->log_comment ) ) . "\n";
}
- $out .= " " . Xml::element( 'type', null, strval( $row->log_type ) ) . "\n";
- $out .= " " . Xml::element( 'action', null, strval( $row->log_action ) ) . "\n";
+ $out .= " " . Xml::element( 'type', null, strval( $row->log_type ) ) . "\n";
+ $out .= " " . Xml::element( 'action', null, strval( $row->log_action ) ) . "\n";
if ( $row->log_deleted & LogPage::DELETED_ACTION ) {
- $out .= " " . Xml::element( 'text', array( 'deleted' => 'deleted' ) ) . "\n";
+ $out .= " " . Xml::element( 'text', array( 'deleted' => 'deleted' ) ) . "\n";
} else {
$title = Title::makeTitle( $row->log_namespace, $row->log_title );
- $out .= " " . Xml::elementClean( 'logtitle', null, self::canonicalTitle( $title ) ) . "\n";
- $out .= " " . Xml::elementClean( 'params',
+ $out .= " " . Xml::elementClean( 'logtitle', null, self::canonicalTitle( $title ) ) . "\n";
+ $out .= " " . Xml::elementClean( 'params',
array( 'xml:space' => 'preserve' ),
strval( $row->log_params ) ) . "\n";
}
- $out .= " </logitem>\n";
+ $out .= " </logitem>\n";
wfProfileOut( __METHOD__ );
return $out;
}
- function writeTimestamp( $timestamp ) {
+ /**
+ * @param $timestamp string
+ * @param $indent string Default to six spaces
+ * @return string
+ */
+ function writeTimestamp( $timestamp, $indent = " " ) {
$ts = wfTimestamp( TS_ISO_8601, $timestamp );
- return " " . Xml::element( 'timestamp', null, $ts ) . "\n";
+ return $indent . Xml::element( 'timestamp', null, $ts ) . "\n";
}
- function writeContributor( $id, $text ) {
- $out = " <contributor>\n";
+ /**
+ * @param $id
+ * @param $text string
+ * @param $indent string Default to six spaces
+ * @return string
+ */
+ function writeContributor( $id, $text, $indent = " " ) {
+ $out = $indent . "<contributor>\n";
if ( $id || !IP::isValid( $text ) ) {
- $out .= " " . Xml::elementClean( 'username', null, strval( $text ) ) . "\n";
- $out .= " " . Xml::element( 'id', null, strval( $id ) ) . "\n";
+ $out .= $indent . " " . Xml::elementClean( 'username', null, strval( $text ) ) . "\n";
+ $out .= $indent . " " . Xml::element( 'id', null, strval( $id ) ) . "\n";
} else {
- $out .= " " . Xml::elementClean( 'ip', null, strval( $text ) ) . "\n";
+ $out .= $indent . " " . Xml::elementClean( 'ip', null, strval( $text ) ) . "\n";
}
- $out .= " </contributor>\n";
+ $out .= $indent . "</contributor>\n";
return $out;
}
/**
* Warning! This data is potentially inconsistent. :(
+ * @param $row
+ * @param $dumpContents bool
+ * @return string
*/
function writeUploads( $row, $dumpContents = false ) {
- if ( $row->page_namespace == NS_IMAGE ) {
+ if ( $row->page_namespace == NS_FILE ) {
$img = wfLocalFile( $row->page_title );
if ( $img && $img->exists() ) {
$out = '';
@@ -670,10 +804,15 @@ class XmlDumpWriter {
} else {
$contents = '';
}
+ if ( $file->isDeleted( File::DELETED_COMMENT ) ) {
+ $comment = Xml::element( 'comment', array( 'deleted' => 'deleted' ) );
+ } else {
+ $comment = Xml::elementClean( 'comment', null, $file->getDescription() );
+ }
return " <upload>\n" .
$this->writeTimestamp( $file->getTimestamp() ) .
$this->writeContributor( $file->getUser( 'id' ), $file->getUser( 'text' ) ) .
- " " . Xml::elementClean( 'comment', null, $file->getDescription() ) . "\n" .
+ " " . $comment . "\n" .
" " . Xml::element( 'filename', null, $file->getName() ) . "\n" .
$archiveName .
" " . Xml::element( 'src', null, $file->getCanonicalUrl() ) . "\n" .
@@ -688,7 +827,7 @@ class XmlDumpWriter {
* Return prefixed text form of title, but using the content language's
* canonical namespace. This skips any special-casing such as gendered
* user namespaces -- which while useful, are not yet listed in the
- * XML <siteinfo> data so are unsafe in export.
+ * XML "<siteinfo>" data so are unsafe in export.
*
* @param Title $title
* @return string
@@ -716,32 +855,55 @@ class XmlDumpWriter {
* @ingroup Dump
*/
class DumpOutput {
+
+ /**
+ * @param $string string
+ */
function writeOpenStream( $string ) {
$this->write( $string );
}
+ /**
+ * @param $string string
+ */
function writeCloseStream( $string ) {
$this->write( $string );
}
+ /**
+ * @param $page
+ * @param $string string
+ */
function writeOpenPage( $page, $string ) {
$this->write( $string );
}
+ /**
+ * @param $string string
+ */
function writeClosePage( $string ) {
$this->write( $string );
}
+ /**
+ * @param $rev
+ * @param $string string
+ */
function writeRevision( $rev, $string ) {
$this->write( $string );
}
+ /**
+ * @param $rev
+ * @param $string string
+ */
function writeLogItem( $rev, $string ) {
$this->write( $string );
}
/**
* Override to write to a different stream type.
+ * @param $string string
* @return bool
*/
function write( $string ) {
@@ -773,6 +935,7 @@ class DumpOutput {
/**
* Returns the name of the file or files which are
* being written to, if there are any.
+ * @return null
*/
function getFilenames() {
return NULL;
@@ -784,27 +947,56 @@ class DumpOutput {
* @ingroup Dump
*/
class DumpFileOutput extends DumpOutput {
- protected $handle, $filename;
+ protected $handle = false, $filename;
+ /**
+ * @param $file
+ */
function __construct( $file ) {
$this->handle = fopen( $file, "wt" );
$this->filename = $file;
}
+ /**
+ * @param $string string
+ */
+ function writeCloseStream( $string ) {
+ parent::writeCloseStream( $string );
+ if ( $this->handle ) {
+ fclose( $this->handle );
+ $this->handle = false;
+ }
+ }
+
+ /**
+ * @param $string string
+ */
function write( $string ) {
fputs( $this->handle, $string );
}
+ /**
+ * @param $newname
+ */
function closeRenameAndReopen( $newname ) {
$this->closeAndRename( $newname, true );
}
+ /**
+ * @param $newname
+ * @throws MWException
+ */
function renameOrException( $newname ) {
if (! rename( $this->filename, $newname ) ) {
throw new MWException( __METHOD__ . ": rename of file {$this->filename} to $newname failed\n" );
}
}
+ /**
+ * @param $newname array
+ * @return mixed
+ * @throws MWException
+ */
function checkRenameArgCount( $newname ) {
if ( is_array( $newname ) ) {
if ( count( $newname ) > 1 ) {
@@ -816,10 +1008,17 @@ class DumpFileOutput extends DumpOutput {
return $newname;
}
+ /**
+ * @param $newname mixed
+ * @param $open bool
+ */
function closeAndRename( $newname, $open = false ) {
$newname = $this->checkRenameArgCount( $newname );
if ( $newname ) {
- fclose( $this->handle );
+ if ( $this->handle ) {
+ fclose( $this->handle );
+ $this->handle = false;
+ }
$this->renameOrException( $newname );
if ( $open ) {
$this->handle = fopen( $this->filename, "wt" );
@@ -827,6 +1026,9 @@ class DumpFileOutput extends DumpOutput {
}
}
+ /**
+ * @return string|null
+ */
function getFilenames() {
return $this->filename;
}
@@ -840,7 +1042,12 @@ class DumpFileOutput extends DumpOutput {
*/
class DumpPipeOutput extends DumpFileOutput {
protected $command, $filename;
+ protected $procOpenResource = false;
+ /**
+ * @param $command
+ * @param $file null
+ */
function __construct( $command, $file = null ) {
if ( !is_null( $file ) ) {
$command .= " > " . wfEscapeShellArg( $file );
@@ -851,6 +1058,20 @@ class DumpPipeOutput extends DumpFileOutput {
$this->filename = $file;
}
+ /**
+ * @param $string string
+ */
+ function writeCloseStream( $string ) {
+ parent::writeCloseStream( $string );
+ if ( $this->procOpenResource ) {
+ proc_close( $this->procOpenResource );
+ $this->procOpenResource = false;
+ }
+ }
+
+ /**
+ * @param $command
+ */
function startCommand( $command ) {
$spec = array(
0 => array( "pipe", "r" ),
@@ -860,15 +1081,28 @@ class DumpPipeOutput extends DumpFileOutput {
$this->handle = $pipes[0];
}
+ /**
+ * @param mixed $newname
+ */
function closeRenameAndReopen( $newname ) {
$this->closeAndRename( $newname, true );
}
+ /**
+ * @param $newname mixed
+ * @param $open bool
+ */
function closeAndRename( $newname, $open = false ) {
$newname = $this->checkRenameArgCount( $newname );
if ( $newname ) {
- fclose( $this->handle );
- proc_close( $this->procOpenResource );
+ if ( $this->handle ) {
+ fclose( $this->handle );
+ $this->handle = false;
+ }
+ if ( $this->procOpenResource ) {
+ proc_close( $this->procOpenResource );
+ $this->procOpenResource = false;
+ }
$this->renameOrException( $newname );
if ( $open ) {
$command = $this->command;
@@ -885,6 +1119,10 @@ class DumpPipeOutput extends DumpFileOutput {
* @ingroup Dump
*/
class DumpGZipOutput extends DumpPipeOutput {
+
+ /**
+ * @param $file string
+ */
function __construct( $file ) {
parent::__construct( "gzip", $file );
}
@@ -895,6 +1133,10 @@ class DumpGZipOutput extends DumpPipeOutput {
* @ingroup Dump
*/
class DumpBZip2Output extends DumpPipeOutput {
+
+ /**
+ * @param $file string
+ */
function __construct( $file ) {
parent::__construct( "bzip2", $file );
}
@@ -905,12 +1147,20 @@ class DumpBZip2Output extends DumpPipeOutput {
* @ingroup Dump
*/
class Dump7ZipOutput extends DumpPipeOutput {
+
+ /**
+ * @param $file string
+ */
function __construct( $file ) {
$command = $this->setup7zCommand( $file );
parent::__construct( $command );
$this->filename = $file;
}
+ /**
+ * @param $file string
+ * @return string
+ */
function setup7zCommand( $file ) {
$command = "7za a -bd -si " . wfEscapeShellArg( $file );
// Suppress annoying useless crap from p7zip
@@ -919,6 +1169,10 @@ class Dump7ZipOutput extends DumpPipeOutput {
return( $command );
}
+ /**
+ * @param $newname string
+ * @param $open bool
+ */
function closeAndRename( $newname, $open = false ) {
$newname = $this->checkRenameArgCount( $newname );
if ( $newname ) {
@@ -933,8 +1187,6 @@ class Dump7ZipOutput extends DumpPipeOutput {
}
}
-
-
/**
* Dump output filter class.
* This just does output filtering and streaming; XML formatting is done
@@ -942,18 +1194,44 @@ class Dump7ZipOutput extends DumpPipeOutput {
* @ingroup Dump
*/
class DumpFilter {
+
+ /**
+ * @var DumpOutput
+ * FIXME will need to be made protected whenever legacy code
+ * is updated.
+ */
+ public $sink;
+
+ /**
+ * @var bool
+ */
+ protected $sendingThisPage;
+
+ /**
+ * @param $sink DumpOutput
+ */
function __construct( &$sink ) {
$this->sink =& $sink;
}
+ /**
+ * @param $string string
+ */
function writeOpenStream( $string ) {
$this->sink->writeOpenStream( $string );
}
+ /**
+ * @param $string string
+ */
function writeCloseStream( $string ) {
$this->sink->writeCloseStream( $string );
}
+ /**
+ * @param $page
+ * @param $string string
+ */
function writeOpenPage( $page, $string ) {
$this->sendingThisPage = $this->pass( $page, $string );
if ( $this->sendingThisPage ) {
@@ -961,6 +1239,9 @@ class DumpFilter {
}
}
+ /**
+ * @param $string string
+ */
function writeClosePage( $string ) {
if ( $this->sendingThisPage ) {
$this->sink->writeClosePage( $string );
@@ -968,30 +1249,49 @@ class DumpFilter {
}
}
+ /**
+ * @param $rev
+ * @param $string string
+ */
function writeRevision( $rev, $string ) {
if ( $this->sendingThisPage ) {
$this->sink->writeRevision( $rev, $string );
}
}
+ /**
+ * @param $rev
+ * @param $string string
+ */
function writeLogItem( $rev, $string ) {
$this->sink->writeRevision( $rev, $string );
}
+ /**
+ * @param $newname string
+ */
function closeRenameAndReopen( $newname ) {
$this->sink->closeRenameAndReopen( $newname );
}
+ /**
+ * @param $newname string
+ * @param $open bool
+ */
function closeAndRename( $newname, $open = false ) {
$this->sink->closeAndRename( $newname, $open );
}
+ /**
+ * @return array
+ */
function getFilenames() {
return $this->sink->getFilenames();
}
/**
* Override for page-based filter types.
+ * @param $page
* @return bool
*/
function pass( $page ) {
@@ -1004,6 +1304,11 @@ class DumpFilter {
* @ingroup Dump
*/
class DumpNotalkFilter extends DumpFilter {
+
+ /**
+ * @param $page
+ * @return bool
+ */
function pass( $page ) {
return !MWNamespace::isTalk( $page->page_namespace );
}
@@ -1017,6 +1322,10 @@ class DumpNamespaceFilter extends DumpFilter {
var $invert = false;
var $namespaces = array();
+ /**
+ * @param $sink DumpOutput
+ * @param $param
+ */
function __construct( &$sink, $param ) {
parent::__construct( $sink );
@@ -1059,6 +1368,10 @@ class DumpNamespaceFilter extends DumpFilter {
}
}
+ /**
+ * @param $page
+ * @return bool
+ */
function pass( $page ) {
$match = isset( $this->namespaces[$page->page_namespace] );
return $this->invert xor $match;
@@ -1073,11 +1386,18 @@ class DumpNamespaceFilter extends DumpFilter {
class DumpLatestFilter extends DumpFilter {
var $page, $pageString, $rev, $revString;
+ /**
+ * @param $page
+ * @param $string string
+ */
function writeOpenPage( $page, $string ) {
$this->page = $page;
$this->pageString = $string;
}
+ /**
+ * @param $string string
+ */
function writeClosePage( $string ) {
if ( $this->rev ) {
$this->sink->writeOpenPage( $this->page, $this->pageString );
@@ -1090,6 +1410,10 @@ class DumpLatestFilter extends DumpFilter {
$this->pageString = null;
}
+ /**
+ * @param $rev
+ * @param $string string
+ */
function writeRevision( $rev, $string ) {
if ( $rev->rev_id == $this->page->page_latest ) {
$this->rev = $rev;
@@ -1103,51 +1427,82 @@ class DumpLatestFilter extends DumpFilter {
* @ingroup Dump
*/
class DumpMultiWriter {
+
+ /**
+ * @param $sinks
+ */
function __construct( $sinks ) {
$this->sinks = $sinks;
$this->count = count( $sinks );
}
+ /**
+ * @param $string string
+ */
function writeOpenStream( $string ) {
for ( $i = 0; $i < $this->count; $i++ ) {
$this->sinks[$i]->writeOpenStream( $string );
}
}
+ /**
+ * @param $string string
+ */
function writeCloseStream( $string ) {
for ( $i = 0; $i < $this->count; $i++ ) {
$this->sinks[$i]->writeCloseStream( $string );
}
}
+ /**
+ * @param $page
+ * @param $string string
+ */
function writeOpenPage( $page, $string ) {
for ( $i = 0; $i < $this->count; $i++ ) {
$this->sinks[$i]->writeOpenPage( $page, $string );
}
}
+ /**
+ * @param $string
+ */
function writeClosePage( $string ) {
for ( $i = 0; $i < $this->count; $i++ ) {
$this->sinks[$i]->writeClosePage( $string );
}
}
+ /**
+ * @param $rev
+ * @param $string
+ */
function writeRevision( $rev, $string ) {
for ( $i = 0; $i < $this->count; $i++ ) {
$this->sinks[$i]->writeRevision( $rev, $string );
}
}
+ /**
+ * @param $newnames
+ */
function closeRenameAndReopen( $newnames ) {
$this->closeAndRename( $newnames, true );
}
+ /**
+ * @param $newnames array
+ * @param bool $open
+ */
function closeAndRename( $newnames, $open = false ) {
for ( $i = 0; $i < $this->count; $i++ ) {
$this->sinks[$i]->closeAndRename( $newnames[$i], $open );
}
}
+ /**
+ * @return array
+ */
function getFilenames() {
$filenames = array();
for ( $i = 0; $i < $this->count; $i++ ) {
@@ -1158,6 +1513,10 @@ class DumpMultiWriter {
}
+/**
+ * @param $string string
+ * @return string
+ */
function xmlsafe( $string ) {
wfProfileIn( __FUNCTION__ );
diff --git a/includes/ExternalEdit.php b/includes/ExternalEdit.php
index b8704758..34683253 100644
--- a/includes/ExternalEdit.php
+++ b/includes/ExternalEdit.php
@@ -80,10 +80,16 @@ class ExternalEdit extends ContextSource {
} elseif ( $this->getRequest()->getVal( 'mode' ) == 'file' ) {
$type = "Edit file";
$image = wfLocalFile( $this->getTitle() );
- $urls = array( 'File' => array(
- 'Extension' => $image->getExtension(),
- 'URL' => $image->getCanonicalURL()
- ) );
+ if ( $image ) {
+ $urls = array(
+ 'File' => array(
+ 'Extension' => $image->getExtension(),
+ 'URL' => $image->getCanonicalURL()
+ )
+ );
+ } else{
+ $urls = array();
+ }
} else {
$type = "Edit text";
# *.wiki file extension is used by some editors for syntax
diff --git a/includes/ExternalStore.php b/includes/ExternalStore.php
index 3bee6ed8..61d4ef7c 100644
--- a/includes/ExternalStore.php
+++ b/includes/ExternalStore.php
@@ -1,5 +1,26 @@
<?php
/**
+ * Data storage in external repositories.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ * @file
+ */
+
+/**
* @defgroup ExternalStorage ExternalStorage
*/
@@ -24,7 +45,7 @@ class ExternalStore {
*
* @param $url String: The URL of the text to get
* @param $params Array: associative array of parameters for the ExternalStore object.
- * @return The text stored or false on error
+ * @return string|bool The text stored or false on error
*/
static function fetchFromURL( $url, $params = array() ) {
global $wgExternalStores;
@@ -81,7 +102,7 @@ class ExternalStore {
* @param $url
* @param $data
* @param $params array
- * @return string|false The URL of the stored data item, or false on error
+ * @return string|bool The URL of the stored data item, or false on error
*/
static function insert( $url, $data, $params = array() ) {
list( $proto, $params ) = explode( '://', $url, 2 );
diff --git a/includes/ExternalStoreDB.php b/includes/ExternalStoreDB.php
index 4920a91c..6f2b33e1 100644
--- a/includes/ExternalStoreDB.php
+++ b/includes/ExternalStoreDB.php
@@ -1,4 +1,24 @@
<?php
+/**
+ * External storage in SQL database.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ * @file
+ */
/**
* DB accessable external objects
@@ -73,6 +93,7 @@ class ExternalStoreDB {
/**
* Fetch data from given URL
* @param $url String: an url of the form DB://cluster/id or DB://cluster/id/itemid for concatened storage.
+ * @return mixed
*/
function fetchFromURL( $url ) {
$path = explode( '/', $url );
@@ -157,7 +178,7 @@ class ExternalStoreDB {
throw new MWException( __METHOD__.': no insert ID' );
}
if ( $dbw->getFlag( DBO_TRX ) ) {
- $dbw->commit();
+ $dbw->commit( __METHOD__ );
}
return "DB://$cluster/$id";
}
diff --git a/includes/ExternalStoreHttp.php b/includes/ExternalStoreHttp.php
index 092ff7d8..311e32b3 100644
--- a/includes/ExternalStoreHttp.php
+++ b/includes/ExternalStoreHttp.php
@@ -1,4 +1,24 @@
<?php
+/**
+ * External storage using HTTP requests.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ * @file
+ */
/**
* Example class for HTTP accessable external objects.
diff --git a/includes/ExternalUser.php b/includes/ExternalUser.php
index 37716390..9a01deb7 100644
--- a/includes/ExternalUser.php
+++ b/includes/ExternalUser.php
@@ -18,6 +18,8 @@
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
* http://www.gnu.org/copyleft/gpl.html
+ *
+ * @file
*/
/**
@@ -98,7 +100,7 @@ abstract class ExternalUser {
* This is a wrapper around newFromId().
*
* @param $user User
- * @return ExternalUser|false
+ * @return ExternalUser|bool False on failure
*/
public static function newFromUser( $user ) {
global $wgExternalAuthType;
diff --git a/includes/FakeTitle.php b/includes/FakeTitle.php
index 8415ec08..60f7600d 100644
--- a/includes/FakeTitle.php
+++ b/includes/FakeTitle.php
@@ -1,4 +1,24 @@
<?php
+/**
+ * Fake title class that triggers an error if any members are called.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ * @file
+ */
/**
* Fake title class that triggers an error if any members are called
@@ -59,7 +79,6 @@ class FakeTitle extends Title {
function getSkinFromCssJsSubpage() { $this->error(); }
function isCssSubpage() { $this->error(); }
function isJsSubpage() { $this->error(); }
- function userCanEditCssJsSubpage() { $this->error(); }
function userCanEditCssSubpage() { $this->error(); }
function userCanEditJsSubpage() { $this->error(); }
function isCascadeProtected() { $this->error(); }
@@ -88,8 +107,6 @@ class FakeTitle extends Title {
function moveNoAuth( &$nt ) { $this->error(); }
function isValidMoveOperation( &$nt, $auth = true, $reason = '' ) { $this->error(); }
function moveTo( &$nt, $auth = true, $reason = '', $createRedirect = true ) { $this->error(); }
- function moveOverExistingRedirect( &$nt, $reason = '', $createRedirect = true ) { $this->error(); }
- function moveToNewTitle( &$nt, $reason = '', $createRedirect = true ) { $this->error(); }
function moveSubpages( $nt, $auth = true, $reason = '', $createRedirect = true ) { $this->error(); }
function isSingleRevRedirect() { $this->error(); }
function isValidMoveTarget( $nt ) { $this->error(); }
diff --git a/includes/Fallback.php b/includes/Fallback.php
index b517cd16..4b138c11 100644
--- a/includes/Fallback.php
+++ b/includes/Fallback.php
@@ -1,6 +1,7 @@
<?php
-
/**
+ * Fallback functions for PHP installed without mbstring support.
+ *
* 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
@@ -16,6 +17,7 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
* http://www.gnu.org/copyleft/gpl.html
*
+ * @file
*/
/**
diff --git a/includes/Feed.php b/includes/Feed.php
index 351f3572..f9dbf5ba 100644
--- a/includes/Feed.php
+++ b/includes/Feed.php
@@ -183,34 +183,35 @@ class FeedItem {
* @todo document (needs one-sentence top-level class description).
* @ingroup Feed
*/
-class ChannelFeed extends FeedItem {
- /**#@+
- * Abstract function, override!
- * @abstract
- */
-
+abstract class ChannelFeed extends FeedItem {
/**
* Generate Header of the feed
+ * @par Example:
+ * @code
+ * print "<feed>";
+ * @endcode
+ * @param $item
*/
- function outHeader() {
- # print "<feed>";
- }
+ abstract public function outHeader();
/**
* Generate an item
+ * @par Example:
+ * @code
+ * print "<item>...</item>";
+ * @endcode
* @param $item
*/
- function outItem( $item ) {
- # print "<item>...</item>";
- }
+ abstract public function outItem( $item );
/**
* Generate Footer of the feed
+ * @par Example:
+ * @code
+ * print "</feed>";
+ * @endcode
*/
- function outFooter() {
- # print "</feed>";
- }
- /**#@-*/
+ abstract public function outFooter();
/**
* Setup and send HTTP headers. Don't send any content;
@@ -334,6 +335,7 @@ class RSSFeed extends ChannelFeed {
class AtomFeed extends ChannelFeed {
/**
* @todo document
+ * @return string
*/
function formatTime( $ts ) {
// need to use RFC 822 time format at least for rss2.0
diff --git a/includes/FeedUtils.php b/includes/FeedUtils.php
index cf42329b..11b2675d 100644
--- a/includes/FeedUtils.php
+++ b/includes/FeedUtils.php
@@ -1,4 +1,25 @@
<?php
+/**
+ * Helper functions for feeds.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ * @file
+ * @ingroup Feed
+ */
/**
* Helper functions for feeds
@@ -64,7 +85,7 @@ class FeedUtils {
$row->rc_last_oldid, $row->rc_this_oldid,
$timestamp,
($row->rc_deleted & Revision::DELETED_COMMENT)
- ? wfMsgHtml('rev-deleted-comment')
+ ? wfMessage('rev-deleted-comment')->escaped()
: $row->rc_comment,
$actiontext
);
@@ -108,21 +129,22 @@ class FeedUtils {
if( $oldid ) {
wfProfileIn( __METHOD__."-dodiff" );
- #$diffText = $de->getDiff( wfMsg( 'revisionasof',
+ #$diffText = $de->getDiff( wfMessage( 'revisionasof',
# $wgLang->timeanddate( $timestamp ),
# $wgLang->date( $timestamp ),
- # $wgLang->time( $timestamp ) ),
- # wfMsg( 'currentrev' ) );
+ # $wgLang->time( $timestamp ) )->text(),
+ # wfMessage( 'currentrev' )->text() );
+ $diffText = '';
// Don't bother generating the diff if we won't be able to show it
if ( $wgFeedDiffCutoff > 0 ) {
$de = new DifferenceEngine( $title, $oldid, $newid );
$diffText = $de->getDiff(
- wfMsg( 'previousrevision' ), // hack
- wfMsg( 'revisionasof',
+ wfMessage( 'previousrevision' )->text(), // hack
+ wfMessage( 'revisionasof',
$wgLang->timeanddate( $timestamp ),
$wgLang->date( $timestamp ),
- $wgLang->time( $timestamp ) ) );
+ $wgLang->time( $timestamp ) )->text() );
}
if ( $wgFeedDiffCutoff <= 0 || ( strlen( $diffText ) > $wgFeedDiffCutoff ) ) {
@@ -148,7 +170,7 @@ class FeedUtils {
// Omit large new page diffs, bug 29110
$diffText = self::getDiffLink( $title, $newid );
} else {
- $diffText = '<p><b>' . wfMsg( 'newpage' ) . '</b></p>' .
+ $diffText = '<p><b>' . wfMessage( 'newpage' )->text() . '</b></p>' .
'<div>' . nl2br( htmlspecialchars( $newtext ) ) . '</div>';
}
}
@@ -165,6 +187,7 @@ class FeedUtils {
* @param $title Title object: used to generate the diff URL
* @param $newid Integer newid for this diff
* @param $oldid Integer|null oldid for the diff. Null means it is a new article
+ * @return string
*/
protected static function getDiffLink( Title $title, $newid, $oldid = null ) {
$queryParameters = ($oldid == null)
@@ -173,7 +196,7 @@ class FeedUtils {
$diffUrl = $title->getFullUrl( $queryParameters );
$diffLink = Html::element( 'a', array( 'href' => $diffUrl ),
- wfMsgForContent( 'showdiff' ) );
+ wfMessage( 'showdiff' )->inContentLanguage()->text() );
return $diffLink;
}
diff --git a/includes/FileDeleteForm.php b/includes/FileDeleteForm.php
index 11f9aea5..e75ad729 100644
--- a/includes/FileDeleteForm.php
+++ b/includes/FileDeleteForm.php
@@ -1,10 +1,31 @@
<?php
+/**
+ * File deletion user interface.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ * @file
+ * @author Rob Church <robchur@gmail.com>
+ * @ingroup Media
+ */
/**
* File deletion user interface
*
* @ingroup Media
- * @author Rob Church <robchur@gmail.com>
*/
class FileDeleteForm {
@@ -80,7 +101,8 @@ class FileDeleteForm {
$reason = $deleteReason;
} elseif ( $deleteReason != '' ) {
// Entry from drop down menu + additional comment
- $reason = $deleteReasonList . wfMsgForContent( 'colon-separator' ) . $deleteReason;
+ $reason = $deleteReasonList . wfMessage( 'colon-separator' )
+ ->inContentLanguage()->text() . $deleteReason;
} else {
$reason = $deleteReasonList;
}
@@ -89,9 +111,7 @@ class FileDeleteForm {
if( !$status->isGood() ) {
$wgOut->addHTML( '<h2>' . $this->prepareMessage( 'filedeleteerror-short' ) . "</h2>\n" );
- $wgOut->addHTML( '<span class="error">' );
- $wgOut->addWikiText( $status->getWikiText( 'filedeleteerror-short', 'filedeleteerror-long' ) );
- $wgOut->addHTML( '</span>' );
+ $wgOut->addWikiText( '<div class="error">' . $status->getWikiText( 'filedeleteerror-short', 'filedeleteerror-long' ) . '</div>' );
}
if( $status->ok ) {
$wgOut->setPageTitle( wfMessage( 'actioncomplete' ) );
@@ -100,10 +120,12 @@ class FileDeleteForm {
// file, otherwise go back to the description page
$wgOut->addReturnTo( $this->oldimage ? $this->title : Title::newMainPage() );
- if ( $wgRequest->getCheck( 'wpWatch' ) && $wgUser->isLoggedIn() ) {
- WatchAction::doWatch( $this->title, $wgUser );
- } elseif ( $this->title->userIsWatching() ) {
- WatchAction::doUnwatch( $this->title, $wgUser );
+ if ( $wgUser->isLoggedIn() && $wgRequest->getCheck( 'wpWatch' ) != $wgUser->isWatched( $this->title ) ) {
+ if ( $wgRequest->getCheck( 'wpWatch' ) ) {
+ WatchAction::doWatch( $this->title, $wgUser );
+ } else {
+ WatchAction::doUnwatch( $this->title, $wgUser );
+ }
}
}
return;
@@ -122,6 +144,7 @@ class FileDeleteForm {
* @param $reason String: reason of the deletion
* @param $suppress Boolean: whether to mark all deleted versions as restricted
* @param $user User object performing the request
+ * @return bool|Status
*/
public static function doDelete( &$title, &$file, &$oldimage, $reason, $suppress, User $user = null ) {
if ( $user === null ) {
@@ -134,12 +157,20 @@ class FileDeleteForm {
$status = $file->deleteOld( $oldimage, $reason, $suppress );
if( $status->ok ) {
// Need to do a log item
- $log = new LogPage( 'delete' );
- $logComment = wfMsgForContent( 'deletedrevision', $oldimage );
+ $logComment = wfMessage( 'deletedrevision', $oldimage )->inContentLanguage()->text();
if( trim( $reason ) != '' ) {
- $logComment .= wfMsgForContent( 'colon-separator' ) . $reason;
+ $logComment .= wfMessage( 'colon-separator' )
+ ->inContentLanguage()->text() . $reason;
}
- $log->addEntry( 'delete', $title, $logComment );
+
+ $logtype = $suppress ? 'suppress' : 'delete';
+
+ $logEntry = new ManualLogEntry( $logtype, 'delete' );
+ $logEntry->setPerformer( $user );
+ $logEntry->setTarget( $title );
+ $logEntry->setComment( $logComment );
+ $logid = $logEntry->insert();
+ $logEntry->publish( $logid );
}
} else {
$status = Status::newFatal( 'cannotdelete',
@@ -150,17 +181,20 @@ class FileDeleteForm {
try {
// delete the associated article first
$error = '';
- if ( $page->doDeleteArticleReal( $reason, $suppress, 0, false, $error, $user ) >= WikiPage::DELETE_SUCCESS ) {
+ $deleteStatus = $page->doDeleteArticleReal( $reason, $suppress, 0, false, $error, $user );
+ // doDeleteArticleReal() returns a non-fatal error status if the page
+ // or revision is missing, so check for isOK() rather than isGood()
+ if ( $deleteStatus->isOK() ) {
$status = $file->delete( $reason, $suppress );
if( $status->isOK() ) {
- $dbw->commit();
+ $dbw->commit( __METHOD__ );
} else {
- $dbw->rollback();
+ $dbw->rollback( __METHOD__ );
}
}
} catch ( MWException $e ) {
// rollback before returning to prevent UI from displaying incorrect "View or restore N deleted edits?"
- $dbw->rollback();
+ $dbw->rollback( __METHOD__ );
throw $e;
}
}
@@ -182,7 +216,7 @@ class FileDeleteForm {
$suppress = "<tr id=\"wpDeleteSuppressRow\">
<td></td>
<td class='mw-input'><strong>" .
- Xml::checkLabel( wfMsg( 'revdelete-suppress' ),
+ Xml::checkLabel( wfMessage( 'revdelete-suppress' )->text(),
'wpSuppress', 'wpSuppress', false, array( 'tabindex' => '3' ) ) .
"</strong></td>
</tr>";
@@ -190,27 +224,32 @@ class FileDeleteForm {
$suppress = '';
}
- $checkWatch = $wgUser->getBoolOption( 'watchdeletion' ) || $this->title->userIsWatching();
+ $checkWatch = $wgUser->getBoolOption( 'watchdeletion' ) || $wgUser->isWatched( $this->title );
$form = Xml::openElement( 'form', array( 'method' => 'post', 'action' => $this->getAction(),
'id' => 'mw-img-deleteconfirm' ) ) .
Xml::openElement( 'fieldset' ) .
- Xml::element( 'legend', null, wfMsg( 'filedelete-legend' ) ) .
+ Xml::element( 'legend', null, wfMessage( 'filedelete-legend' )->text() ) .
Html::hidden( 'wpEditToken', $wgUser->getEditToken( $this->oldimage ) ) .
$this->prepareMessage( 'filedelete-intro' ) .
Xml::openElement( 'table', array( 'id' => 'mw-img-deleteconfirm-table' ) ) .
"<tr>
<td class='mw-label'>" .
- Xml::label( wfMsg( 'filedelete-comment' ), 'wpDeleteReasonList' ) .
+ Xml::label( wfMessage( 'filedelete-comment' )->text(), 'wpDeleteReasonList' ) .
"</td>
<td class='mw-input'>" .
- Xml::listDropDown( 'wpDeleteReasonList',
- wfMsgForContent( 'filedelete-reason-dropdown' ),
- wfMsgForContent( 'filedelete-reason-otherlist' ), '', 'wpReasonDropDown', 1 ) .
+ Xml::listDropDown(
+ 'wpDeleteReasonList',
+ wfMessage( 'filedelete-reason-dropdown' )->inContentLanguage()->text(),
+ wfMessage( 'filedelete-reason-otherlist' )->inContentLanguage()->text(),
+ '',
+ 'wpReasonDropDown',
+ 1
+ ) .
"</td>
</tr>
<tr>
<td class='mw-label'>" .
- Xml::label( wfMsg( 'filedelete-otherreason' ), 'wpReason' ) .
+ Xml::label( wfMessage( 'filedelete-otherreason' )->text(), 'wpReason' ) .
"</td>
<td class='mw-input'>" .
Xml::input( 'wpReason', 60, $wgRequest->getText( 'wpReason' ),
@@ -223,7 +262,7 @@ class FileDeleteForm {
<tr>
<td></td>
<td class='mw-input'>" .
- Xml::checkLabel( wfMsg( 'watchthis' ),
+ Xml::checkLabel( wfMessage( 'watchthis' )->text(),
'wpWatch', 'wpWatch', $checkWatch, array( 'tabindex' => '3' ) ) .
"</td>
</tr>";
@@ -232,7 +271,7 @@ class FileDeleteForm {
<tr>
<td></td>
<td class='mw-submit'>" .
- Xml::submitButton( wfMsg( 'filedelete-submit' ),
+ Xml::submitButton( wfMessage( 'filedelete-submit' )->text(),
array( 'name' => 'mw-filedelete-submit', 'id' => 'mw-filedelete-submit', 'tabindex' => '4' ) ) .
"</td>
</tr>" .
@@ -244,7 +283,7 @@ class FileDeleteForm {
$title = Title::makeTitle( NS_MEDIAWIKI, 'Filedelete-reason-dropdown' );
$link = Linker::link(
$title,
- wfMsgHtml( 'filedelete-edit-reasonlist' ),
+ wfMessage( 'filedelete-edit-reasonlist' )->escaped(),
array(),
array( 'action' => 'edit' )
);
@@ -259,7 +298,8 @@ class FileDeleteForm {
*/
private function showLogEntries() {
global $wgOut;
- $wgOut->addHTML( '<h2>' . htmlspecialchars( LogPage::logName( 'delete' ) ) . "</h2>\n" );
+ $deleteLogPage = new LogPage( 'delete' );
+ $wgOut->addHTML( '<h2>' . $deleteLogPage->getName()->escaped() . "</h2>\n" );
LogEventsList::showLogExtract( $wgOut, 'delete', $this->title );
}
@@ -274,19 +314,17 @@ class FileDeleteForm {
private function prepareMessage( $message ) {
global $wgLang;
if( $this->oldimage ) {
- return wfMsgExt(
+ return wfMessage(
"{$message}-old", # To ensure grep will find them: 'filedelete-intro-old', 'filedelete-nofile-old', 'filedelete-success-old'
- 'parse',
wfEscapeWikiText( $this->title->getText() ),
$wgLang->date( $this->getTimestamp(), true ),
$wgLang->time( $this->getTimestamp(), true ),
- wfExpandUrl( $this->file->getArchiveUrl( $this->oldimage ), PROTO_CURRENT ) );
+ wfExpandUrl( $this->file->getArchiveUrl( $this->oldimage ), PROTO_CURRENT ) )->parseAsBlock();
} else {
- return wfMsgExt(
+ return wfMessage(
$message,
- 'parse',
wfEscapeWikiText( $this->title->getText() )
- );
+ )->parseAsBlock();
}
}
diff --git a/includes/ForkController.php b/includes/ForkController.php
index 9cacef54..448bc03b 100644
--- a/includes/ForkController.php
+++ b/includes/ForkController.php
@@ -1,4 +1,24 @@
<?php
+/**
+ * Class for managing forking command line scripts.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ * @file
+ */
/**
* Class for managing forking command line scripts.
@@ -49,6 +69,7 @@ class ForkController {
* This will return 'child' in the child processes. In the parent process,
* it will run until all the child processes exit or a TERM signal is
* received. It will then return 'done'.
+ * @return string
*/
public function start() {
// Trap SIGTERM
@@ -116,8 +137,10 @@ class ForkController {
protected function prepareEnvironment() {
global $wgMemc;
- // Don't share DB or memcached connections
+ // Don't share DB, storage, or memcached connections
wfGetLBFactory()->destroyInstance();
+ FileBackendGroup::destroySingleton();
+ LockManagerGroup::destroySingleton();
ObjectCache::clear();
$wgMemc = null;
}
diff --git a/includes/FormOptions.php b/includes/FormOptions.php
index ccc87d8a..33bbd86a 100644
--- a/includes/FormOptions.php
+++ b/includes/FormOptions.php
@@ -1,16 +1,35 @@
<?php
/**
* Helper class to keep track of options when mixing links and form elements.
- * @todo This badly need some examples and tests :-)
*
* Copyright © 2008, Niklas Laxstiröm
- *
* Copyright © 2011, Antoine Musso
*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ * @file
* @author Niklas Laxström
* @author Antoine Musso
*/
+/**
+ * Helper class to keep track of options when mixing links and form elements.
+ *
+ * @todo This badly need some examples and tests :-)
+ */
class FormOptions implements ArrayAccess {
/** @name Type constants
* Used internally to map an option value to a WebRequest accessor
@@ -65,7 +84,7 @@ class FormOptions implements ArrayAccess {
*
* @param $data Mixed: value to guess type for
* @exception MWException Unsupported datatype
- * @return Type constant
+ * @return int Type constant
*/
public static function guessType( $data ) {
if ( is_bool( $data ) ) {
@@ -291,11 +310,17 @@ class FormOptions implements ArrayAccess {
* @see http://php.net/manual/en/class.arrayaccess.php
*/
/* @{ */
- /** Whether option exist*/
+ /**
+ * Whether option exist
+ * @return bool
+ */
public function offsetExists( $name ) {
return isset( $this->options[$name] );
}
- /** Retrieve an option value */
+ /**
+ * Retrieve an option value
+ * @return Mixed
+ */
public function offsetGet( $name ) {
return $this->getValue( $name );
}
diff --git a/includes/GitInfo.php b/includes/GitInfo.php
new file mode 100644
index 00000000..c3c30733
--- /dev/null
+++ b/includes/GitInfo.php
@@ -0,0 +1,214 @@
+<?php
+/**
+ * A class to help return information about a git repo MediaWiki may be inside
+ * This is used by Special:Version and is also useful for the LocalSettings.php
+ * of anyone working on large branches in git to setup config that show up only
+ * when specific branches are currently checked out.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ * @file
+ */
+
+class GitInfo {
+
+ /**
+ * Singleton for the repo at $IP
+ */
+ protected static $repo = null;
+
+ /**
+ * Location of the .git directory
+ */
+ protected $basedir;
+
+ /**
+ * Map of repo URLs to viewer URLs. Access via static method getViewers().
+ */
+ private static $viewers = false;
+
+ /**
+ * @param $dir string The root directory of the repo where the .git dir can be found
+ */
+ public function __construct( $dir ) {
+ $this->basedir = "{$dir}/.git/";
+ }
+
+ /**
+ * Return a singleton for the repo at $IP
+ * @return GitInfo
+ */
+ public static function repo() {
+ global $IP;
+ if ( is_null( self::$repo ) ) {
+ self::$repo = new self( $IP );
+ }
+ return self::$repo;
+ }
+
+ /**
+ * Check if a string looks like a hex encoded SHA1 hash
+ *
+ * @param $str string The string to check
+ * @return bool Whether or not the string looks like a SHA1
+ */
+ public static function isSHA1( $str ) {
+ return !!preg_match( '/^[0-9A-F]{40}$/i', $str );
+ }
+
+ /**
+ * Return the HEAD of the repo (without any opening "ref: ")
+ * @return string The HEAD
+ */
+ public function getHead() {
+ $HEADfile = "{$this->basedir}/HEAD";
+
+ if ( !is_readable( $HEADfile ) ) {
+ return false;
+ }
+
+ $HEAD = file_get_contents( $HEADfile );
+
+ if ( preg_match( "/ref: (.*)/", $HEAD, $m ) ) {
+ return rtrim( $m[1] );
+ } else {
+ return rtrim( $HEAD );
+ }
+ }
+
+ /**
+ * Return the SHA1 for the current HEAD of the repo
+ * @return string A SHA1 or false
+ */
+ public function getHeadSHA1() {
+ $HEAD = $this->getHead();
+
+ // If detached HEAD may be a SHA1
+ if ( self::isSHA1( $HEAD ) ) {
+ return $HEAD;
+ }
+
+ // If not a SHA1 it may be a ref:
+ $REFfile = "{$this->basedir}{$HEAD}";
+ if ( !is_readable( $REFfile ) ) {
+ return false;
+ }
+
+ $sha1 = rtrim( file_get_contents( $REFfile ) );
+
+ return $sha1;
+ }
+
+ /**
+ * Return the name of the current branch, or HEAD if not found
+ * @return string The branch name, HEAD, or false
+ */
+ public function getCurrentBranch() {
+ $HEAD = $this->getHead();
+ if ( $HEAD && preg_match( "#^refs/heads/(.*)$#", $HEAD, $m ) ) {
+ return $m[1];
+ } else {
+ return $HEAD;
+ }
+ }
+
+ /**
+ * Get an URL to a web viewer link to the HEAD revision.
+ *
+ * @return string|bool string if an URL is available or false otherwise.
+ */
+ public function getHeadViewUrl() {
+ $config = "{$this->basedir}/config";
+ if ( !is_readable( $config ) ) {
+ return false;
+ }
+
+ $configArray = parse_ini_file( $config, true );
+ $remote = false;
+
+ // Use the "origin" remote repo if available or any other repo if not.
+ if ( isset( $configArray['remote origin'] ) ) {
+ $remote = $configArray['remote origin'];
+ } else {
+ foreach( $configArray as $sectionName => $sectionConf ) {
+ if ( substr( $sectionName, 0, 6 ) == 'remote' ) {
+ $remote = $sectionConf;
+ }
+ }
+ }
+
+ if ( $remote === false || !isset( $remote['url'] ) ) {
+ return false;
+ }
+
+ $url = $remote['url'];
+ if ( substr( $url, -4 ) !== '.git' ) {
+ $url .= '.git';
+ }
+ foreach( self::getViewers() as $repo => $viewer ) {
+ $pattern = '#^' . $repo . '$#';
+ if ( preg_match( $pattern, $url ) ) {
+ $viewerUrl = preg_replace( $pattern, $viewer, $url );
+ $headSHA1 = $this->getHeadSHA1();
+ $replacements = array(
+ '%h' => substr( $headSHA1, 0, 7 ),
+ '%H' => $headSHA1
+ );
+ return strtr( $viewerUrl, $replacements );
+ }
+ }
+ return false;
+ }
+
+ /**
+ * @see self::getHeadSHA1
+ * @return string
+ */
+ public static function headSHA1() {
+ return self::repo()->getHeadSHA1();
+ }
+
+ /**
+ * @see self::getCurrentBranch
+ * @return string
+ */
+ public static function currentBranch() {
+ return self::repo()->getCurrentBranch();
+ }
+
+ /**
+ * @see self::getHeadViewUrl()
+ * @return bool|string
+ */
+ public static function headViewUrl() {
+ return self::repo()->getHeadViewUrl();
+ }
+
+ /**
+ * Gets the list of repository viewers
+ * @return array
+ */
+ protected static function getViewers() {
+ global $wgGitRepositoryViewers;
+
+ if( self::$viewers === false ) {
+ self::$viewers = $wgGitRepositoryViewers;
+ wfRunHooks( 'GitViewers', array( &self::$viewers ) );
+ }
+
+ return self::$viewers;
+ }
+}
diff --git a/includes/GlobalFunctions.php b/includes/GlobalFunctions.php
index 65fc643e..8f701c6b 100644
--- a/includes/GlobalFunctions.php
+++ b/includes/GlobalFunctions.php
@@ -1,6 +1,22 @@
<?php
/**
- * Global functions used everywhere
+ * Global functions used everywhere.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
* @file
*/
@@ -14,39 +30,54 @@ if ( !defined( 'MEDIAWIKI' ) ) {
/**
* Compatibility functions
*
- * We support PHP 5.2.3 and up.
+ * We support PHP 5.3.2 and up.
* Re-implementations of newer functions or functions in non-standard
* PHP extensions may be included here.
*/
if( !function_exists( 'iconv' ) ) {
- /** @codeCoverageIgnore */
+ /**
+ * @codeCoverageIgnore
+ * @return string
+ */
function iconv( $from, $to, $string ) {
return Fallback::iconv( $from, $to, $string );
}
}
if ( !function_exists( 'mb_substr' ) ) {
- /** @codeCoverageIgnore */
+ /**
+ * @codeCoverageIgnore
+ * @return string
+ */
function mb_substr( $str, $start, $count='end' ) {
return Fallback::mb_substr( $str, $start, $count );
}
- /** @codeCoverageIgnore */
+ /**
+ * @codeCoverageIgnore
+ * @return int
+ */
function mb_substr_split_unicode( $str, $splitPos ) {
return Fallback::mb_substr_split_unicode( $str, $splitPos );
}
}
if ( !function_exists( 'mb_strlen' ) ) {
- /** @codeCoverageIgnore */
+ /**
+ * @codeCoverageIgnore
+ * @return int
+ */
function mb_strlen( $str, $enc = '' ) {
return Fallback::mb_strlen( $str, $enc );
}
}
if( !function_exists( 'mb_strpos' ) ) {
- /** @codeCoverageIgnore */
+ /**
+ * @codeCoverageIgnore
+ * @return int
+ */
function mb_strpos( $haystack, $needle, $offset = 0, $encoding = '' ) {
return Fallback::mb_strpos( $haystack, $needle, $offset, $encoding );
}
@@ -54,7 +85,10 @@ if( !function_exists( 'mb_strpos' ) ) {
}
if( !function_exists( 'mb_strrpos' ) ) {
- /** @codeCoverageIgnore */
+ /**
+ * @codeCoverageIgnore
+ * @return int
+ */
function mb_strrpos( $haystack, $needle, $offset = 0, $encoding = '' ) {
return Fallback::mb_strrpos( $haystack, $needle, $offset, $encoding );
}
@@ -63,7 +97,10 @@ if( !function_exists( 'mb_strrpos' ) ) {
// Support for Wietse Venema's taint feature
if ( !function_exists( 'istainted' ) ) {
- /** @codeCoverageIgnore */
+ /**
+ * @codeCoverageIgnore
+ * @return int
+ */
function istainted( $var ) {
return 0;
}
@@ -200,7 +237,7 @@ function wfMergeErrorArrays( /*...*/ ) {
* @param $after Mixed: The key to insert after
* @return Array
*/
-function wfArrayInsertAfter( $array, $insert, $after ) {
+function wfArrayInsertAfter( array $array, array $insert, $after ) {
// Find the offset of the element to insert after.
$keys = array_keys( $array );
$offsetByKey = array_flip( $keys );
@@ -274,6 +311,24 @@ function wfRandom() {
}
/**
+ * Get a random string containing a number of pesudo-random hex
+ * characters.
+ * @note This is not secure, if you are trying to generate some sort
+ * of token please use MWCryptRand instead.
+ *
+ * @param $length int The length of the string to generate
+ * @return String
+ * @since 1.20
+ */
+function wfRandomString( $length = 32 ) {
+ $str = '';
+ while ( strlen( $str ) < $length ) {
+ $str .= dechex( mt_rand() );
+ }
+ return substr( $str, 0, $length );
+}
+
+/**
* We want some things to be included as literal characters in our title URLs
* for prettiness, which urlencode encodes by default. According to RFC 1738,
* all of the following should be safe:
@@ -329,7 +384,7 @@ function wfUrlencode( $s ) {
* @param $prefix String
* @return String
*/
-function wfArrayToCGI( $array1, $array2 = null, $prefix = '' ) {
+function wfArrayToCgi( $array1, $array2 = null, $prefix = '' ) {
if ( !is_null( $array2 ) ) {
$array1 = $array1 + $array2;
}
@@ -348,7 +403,7 @@ function wfArrayToCGI( $array1, $array2 = null, $prefix = '' ) {
foreach ( $value as $k => $v ) {
$cgi .= $firstTime ? '' : '&';
if ( is_array( $v ) ) {
- $cgi .= wfArrayToCGI( $v, null, $key . "[$k]" );
+ $cgi .= wfArrayToCgi( $v, null, $key . "[$k]" );
} else {
$cgi .= urlencode( $key . "[$k]" ) . '=' . urlencode( $v );
}
@@ -366,7 +421,7 @@ function wfArrayToCGI( $array1, $array2 = null, $prefix = '' ) {
}
/**
- * This is the logical opposite of wfArrayToCGI(): it accepts a query string as
+ * This is the logical opposite of wfArrayToCgi(): it accepts a query string as
* its argument and returns the same string in array form. This allows compa-
* tibility with legacy functions that accept raw query strings instead of nice
* arrays. Of course, keys and values are urldecode()d.
@@ -423,7 +478,7 @@ function wfCgiToArray( $query ) {
*/
function wfAppendQuery( $url, $query ) {
if ( is_array( $query ) ) {
- $query = wfArrayToCGI( $query );
+ $query = wfArrayToCgi( $query );
}
if( $query != '' ) {
if( false === strpos( $url, '?' ) ) {
@@ -731,6 +786,9 @@ function wfParseUrl( $url ) {
return false;
}
+ // parse_url() incorrectly handles schemes case-sensitively. Convert it to lowercase.
+ $bits['scheme'] = strtolower( $bits['scheme'] );
+
// most of the protocols are followed by ://, but mailto: and sometimes news: not, check for it
if ( in_array( $bits['scheme'] . '://', $wgUrlProtocols ) ) {
$bits['delimiter'] = '://';
@@ -765,6 +823,31 @@ function wfParseUrl( $url ) {
}
/**
+ * Take a URL, make sure it's expanded to fully qualified, and replace any
+ * encoded non-ASCII Unicode characters with their UTF-8 original forms
+ * for more compact display and legibility for local audiences.
+ *
+ * @todo handle punycode domains too
+ *
+ * @param $url string
+ * @return string
+ */
+function wfExpandIRI( $url ) {
+ return preg_replace_callback( '/((?:%[89A-F][0-9A-F])+)/i', 'wfExpandIRI_callback', wfExpandUrl( $url ) );
+}
+
+/**
+ * Private callback for wfExpandIRI
+ * @param array $matches
+ * @return string
+ */
+function wfExpandIRI_callback( $matches ) {
+ return urldecode( $matches[1] );
+}
+
+
+
+/**
* Make URL indexes, appropriate for the el_index field of externallinks.
*
* @param $url String
@@ -852,25 +935,21 @@ function wfMatchesDomainList( $url, $domains ) {
* @param $logonly Bool: set true to avoid appearing in HTML when $wgDebugComments is set
*/
function wfDebug( $text, $logonly = false ) {
- global $wgOut, $wgDebugLogFile, $wgDebugComments, $wgProfileOnly, $wgDebugRawPage;
- global $wgDebugLogPrefix, $wgShowDebug;
-
- static $cache = array(); // Cache of unoutputted messages
- $text = wfDebugTimer() . $text;
+ global $wgDebugLogFile, $wgProfileOnly, $wgDebugRawPage, $wgDebugLogPrefix;
if ( !$wgDebugRawPage && wfIsDebugRawPage() ) {
return;
}
- if ( ( $wgDebugComments || $wgShowDebug ) && !$logonly ) {
- $cache[] = $text;
+ $timer = wfDebugTimer();
+ if ( $timer !== '' ) {
+ $text = preg_replace( '/[^\n]/', $timer . '\0', $text, 1 );
+ }
- if ( isset( $wgOut ) && is_object( $wgOut ) ) {
- // add the message and any cached messages to the output
- array_map( array( $wgOut, 'debug' ), $cache );
- $cache = array();
- }
+ if ( !$logonly ) {
+ MWDebug::debugMsg( $text );
}
+
if ( wfRunHooks( 'Debug', array( $text, null /* no log group */ ) ) ) {
if ( $wgDebugLogFile != '' && !$wgProfileOnly ) {
# Strip unprintables; they can switch terminal modes when binary data
@@ -880,12 +959,11 @@ function wfDebug( $text, $logonly = false ) {
wfErrorLog( $text, $wgDebugLogFile );
}
}
-
- MWDebug::debugMsg( $text );
}
/**
* Returns true if debug logging should be suppressed if $wgDebugRawPage = false
+ * @return bool
*/
function wfIsDebugRawPage() {
static $cache;
@@ -968,11 +1046,28 @@ function wfDebugLog( $logGroup, $text, $public = true ) {
* @param $text String: database error message.
*/
function wfLogDBError( $text ) {
- global $wgDBerrorLog;
+ global $wgDBerrorLog, $wgDBerrorLogTZ;
+ static $logDBErrorTimeZoneObject = null;
+
if ( $wgDBerrorLog ) {
$host = wfHostname();
$wiki = wfWikiID();
- $text = date( 'D M j G:i:s T Y' ) . "\t$host\t$wiki\t$text";
+
+ if ( $wgDBerrorLogTZ && !$logDBErrorTimeZoneObject ) {
+ $logDBErrorTimeZoneObject = new DateTimeZone( $wgDBerrorLogTZ );
+ }
+
+ // Workaround for https://bugs.php.net/bug.php?id=52063
+ // Can be removed when min PHP > 5.3.2
+ if ( $logDBErrorTimeZoneObject === null ) {
+ $d = date_create( "now" );
+ } else {
+ $d = date_create( "now", $logDBErrorTimeZoneObject );
+ }
+
+ $date = $d->format( 'D M j G:i:s T Y' );
+
+ $text = "$date\t$host\t$wiki\t$text";
wfErrorLog( $text, $wgDBerrorLog );
}
}
@@ -981,41 +1076,16 @@ function wfLogDBError( $text ) {
* Throws a warning that $function is deprecated
*
* @param $function String
- * @param $version String|false: Added in 1.19.
- * @param $component String|false: Added in 1.19.
- *
+ * @param $version String|bool: Version of MediaWiki that the function was deprecated in (Added in 1.19).
+ * @param $component String|bool: Added in 1.19.
+ * @param $callerOffset integer: How far up the callstack is the original
+ * caller. 2 = function that called the function that called
+ * wfDeprecated (Added in 1.20)
+ *
* @return null
*/
-function wfDeprecated( $function, $version = false, $component = false ) {
- static $functionsWarned = array();
-
- MWDebug::deprecated( $function, $version, $component );
-
- if ( !isset( $functionsWarned[$function] ) ) {
- $functionsWarned[$function] = true;
-
- if ( $version ) {
- global $wgDeprecationReleaseLimit;
-
- if ( $wgDeprecationReleaseLimit && $component === false ) {
- # Strip -* off the end of $version so that branches can use the
- # format #.##-branchname to avoid issues if the branch is merged into
- # a version of MediaWiki later than what it was branched from
- $comparableVersion = preg_replace( '/-.*$/', '', $version );
-
- # If the comparableVersion is larger than our release limit then
- # skip the warning message for the deprecation
- if ( version_compare( $wgDeprecationReleaseLimit, $comparableVersion, '<' ) ) {
- return;
- }
- }
-
- $component = $component === false ? 'MediaWiki' : $component;
- wfWarn( "Use of $function was deprecated in $component $version.", 2 );
- } else {
- wfWarn( "Use of $function is deprecated.", 2 );
- }
- }
+function wfDeprecated( $function, $version = false, $component = false, $callerOffset = 2 ) {
+ MWDebug::deprecated( $function, $version, $component, $callerOffset + 1 );
}
/**
@@ -1029,34 +1099,7 @@ function wfDeprecated( $function, $version = false, $component = false ) {
* is true
*/
function wfWarn( $msg, $callerOffset = 1, $level = E_USER_NOTICE ) {
- global $wgDevelopmentWarnings;
-
- MWDebug::warning( $msg, $callerOffset + 2 );
-
- $callers = wfDebugBacktrace();
- if ( isset( $callers[$callerOffset + 1] ) ) {
- $callerfunc = $callers[$callerOffset + 1];
- $callerfile = $callers[$callerOffset];
- if ( isset( $callerfile['file'] ) && isset( $callerfile['line'] ) ) {
- $file = $callerfile['file'] . ' at line ' . $callerfile['line'];
- } else {
- $file = '(internal function)';
- }
- $func = '';
- if ( isset( $callerfunc['class'] ) ) {
- $func .= $callerfunc['class'] . '::';
- }
- if ( isset( $callerfunc['function'] ) ) {
- $func .= $callerfunc['function'];
- }
- $msg .= " [Called from $func in $file]";
- }
-
- if ( $wgDevelopmentWarnings ) {
- trigger_error( $msg, $level );
- } else {
- wfDebug( "$msg\n" );
- }
+ MWDebug::warning( $msg, $callerOffset + 1, $level );
}
/**
@@ -1177,6 +1220,57 @@ function wfLogProfilingData() {
}
/**
+ * Increment a statistics counter
+ *
+ * @param $key String
+ * @param $count Int
+ */
+function wfIncrStats( $key, $count = 1 ) {
+ global $wgStatsMethod;
+
+ $count = intval( $count );
+
+ if( $wgStatsMethod == 'udp' ) {
+ global $wgUDPProfilerHost, $wgUDPProfilerPort, $wgDBname, $wgAggregateStatsID;
+ static $socket;
+
+ $id = $wgAggregateStatsID !== false ? $wgAggregateStatsID : $wgDBname;
+
+ if ( !$socket ) {
+ $socket = socket_create( AF_INET, SOCK_DGRAM, SOL_UDP );
+ $statline = "stats/{$id} - 1 1 1 1 1 -total\n";
+ socket_sendto(
+ $socket,
+ $statline,
+ strlen( $statline ),
+ 0,
+ $wgUDPProfilerHost,
+ $wgUDPProfilerPort
+ );
+ }
+ $statline = "stats/{$id} - {$count} 1 1 1 1 {$key}\n";
+ wfSuppressWarnings();
+ socket_sendto(
+ $socket,
+ $statline,
+ strlen( $statline ),
+ 0,
+ $wgUDPProfilerHost,
+ $wgUDPProfilerPort
+ );
+ wfRestoreWarnings();
+ } elseif( $wgStatsMethod == 'cache' ) {
+ global $wgMemc;
+ $key = wfMemcKey( 'stats', $key );
+ if ( is_null( $wgMemc->incr( $key, $count ) ) ) {
+ $wgMemc->add( $key, $count );
+ }
+ } else {
+ // Disabled
+ }
+}
+
+/**
* Check if the wiki read-only lock file is present. This can be used to lock
* off editing functions, but doesn't guarantee that the database will not be
* modified.
@@ -1247,7 +1341,7 @@ function wfGetLangObj( $langcode = false ) {
return $wgLang;
}
- $validCodes = array_keys( Language::getLanguageNames() );
+ $validCodes = array_keys( Language::fetchLanguageNames() );
if( in_array( $langcode, $validCodes ) ) {
# $langcode corresponds to a valid language.
return Language::factory( $langcode );
@@ -1260,7 +1354,7 @@ function wfGetLangObj( $langcode = false ) {
/**
* Old function when $wgBetterDirectionality existed
- * Removed in core, kept in extensions for backwards compat.
+ * All usage removed, wfUILang can be removed in near future
*
* @deprecated since 1.18
* @return Language
@@ -1308,6 +1402,8 @@ function wfMessageFallback( /*...*/ ) {
* Use wfMsgForContent() instead if the message should NOT
* change depending on the user preferences.
*
+ * @deprecated since 1.18
+ *
* @param $key String: lookup key for the message, usually
* defined in languages/Language.php
*
@@ -1328,6 +1424,8 @@ function wfMsg( $key ) {
/**
* Same as above except doesn't transform the message
*
+ * @deprecated since 1.18
+ *
* @param $key String
* @return String
*/
@@ -1356,6 +1454,8 @@ function wfMsgNoTrans( $key ) {
* customize potentially hundreds of messages in
* order to, e.g., fix a link in every possible language.
*
+ * @deprecated since 1.18
+ *
* @param $key String: lookup key for the message, usually
* defined in languages/Language.php
* @return String
@@ -1376,6 +1476,8 @@ function wfMsgForContent( $key ) {
/**
* Same as above except doesn't transform the message
*
+ * @deprecated since 1.18
+ *
* @param $key String
* @return String
*/
@@ -1395,6 +1497,8 @@ function wfMsgForContentNoTrans( $key ) {
/**
* Really get a message
*
+ * @deprecated since 1.18
+ *
* @param $key String: key to get.
* @param $args
* @param $useDB Boolean
@@ -1413,6 +1517,8 @@ function wfMsgReal( $key, $args, $useDB = true, $forContent = false, $transform
/**
* Fetch a message string value, but don't replace any keys yet.
*
+ * @deprecated since 1.18
+ *
* @param $key String
* @param $useDB Bool
* @param $langCode String: Code of the language to get the message for, or
@@ -1468,6 +1574,8 @@ function wfMsgReplaceArgs( $message, $args ) {
* to pre-escape them if you really do want plaintext, or just wrap
* the whole thing in htmlspecialchars().
*
+ * @deprecated since 1.18
+ *
* @param $key String
* @param string ... parameters
* @return string
@@ -1485,6 +1593,8 @@ function wfMsgHtml( $key ) {
* to pre-escape them if you really do want plaintext, or just wrap
* the whole thing in htmlspecialchars().
*
+ * @deprecated since 1.18
+ *
* @param $key String
* @param string ... parameters
* @return string
@@ -1500,6 +1610,9 @@ function wfMsgWikiHtml( $key ) {
/**
* Returns message in the requested format
+ *
+ * @deprecated since 1.18
+ *
* @param $key String: key of the message
* @param $options Array: processing rules. Can take the following options:
* <i>parse</i>: parses wikitext to HTML
@@ -1592,6 +1705,8 @@ function wfMsgExt( $key, $options ) {
* looked up didn't exist but a XHTML string, this function checks for the
* nonexistance of messages by checking the MessageCache::get() result directly.
*
+ * @deprecated since 1.18. Use Message::isDisabled().
+ *
* @param $key String: the message key looked up
* @return Boolean True if the message *doesn't* exist.
*/
@@ -1619,6 +1734,15 @@ function wfDebugDieBacktrace( $msg = '' ) {
function wfHostname() {
static $host;
if ( is_null( $host ) ) {
+
+ # Hostname overriding
+ global $wgOverrideHostname;
+ if( $wgOverrideHostname !== false ) {
+ # Set static and skip any detection
+ $host = $wgOverrideHostname;
+ return $host;
+ }
+
if ( function_exists( 'posix_uname' ) ) {
// This function not present on Windows
$uname = posix_uname();
@@ -1692,7 +1816,7 @@ function wfDebugBacktrace( $limit = 0 ) {
}
if ( $limit && version_compare( PHP_VERSION, '5.4.0', '>=' ) ) {
- return array_slice( debug_backtrace( DEBUG_BACKTRACE_PROVIDE_OBJECT, $limit ), 1 );
+ return array_slice( debug_backtrace( DEBUG_BACKTRACE_PROVIDE_OBJECT, $limit + 1 ), 1 );
} else {
return array_slice( debug_backtrace(), 1 );
}
@@ -1751,25 +1875,27 @@ function wfBacktrace() {
/**
* Get the name of the function which called this function
+ * wfGetCaller( 1 ) is the function with the wfGetCaller() call (ie. __FUNCTION__)
+ * wfGetCaller( 2 ) [default] is the caller of the function running wfGetCaller()
+ * wfGetCaller( 3 ) is the parent of that.
*
* @param $level Int
- * @return Bool|string
+ * @return string
*/
function wfGetCaller( $level = 2 ) {
- $backtrace = wfDebugBacktrace( $level );
+ $backtrace = wfDebugBacktrace( $level + 1 );
if ( isset( $backtrace[$level] ) ) {
return wfFormatStackFrame( $backtrace[$level] );
} else {
- $caller = 'unknown';
+ return 'unknown';
}
- return $caller;
}
/**
* Return a string consisting of callers in the stack. Useful sometimes
* for profiling specific points.
*
- * @param $limit The maximum depth of the stack frame to return, or false for
+ * @param $limit int The maximum depth of the stack frame to return, or false for
* the entire stack.
* @return String
*/
@@ -1786,7 +1912,7 @@ function wfGetAllCallers( $limit = 3 ) {
* Return a string representation of frame
*
* @param $frame Array
- * @return Bool
+ * @return string
*/
function wfFormatStackFrame( $frame ) {
return isset( $frame['class'] ) ?
@@ -1806,13 +1932,7 @@ function wfFormatStackFrame( $frame ) {
* @return String
*/
function wfShowingResults( $offset, $limit ) {
- global $wgLang;
- return wfMsgExt(
- 'showingresults',
- array( 'parseinline' ),
- $wgLang->formatNum( $limit ),
- $wgLang->formatNum( $offset + 1 )
- );
+ return wfMessage( 'showingresults' )->numParams( $limit, $offset + 1 )->parse();
}
/**
@@ -1828,7 +1948,7 @@ function wfShowingResults( $offset, $limit ) {
*/
function wfViewPrevNext( $offset, $limit, $link, $query = '', $atend = false ) {
wfDeprecated( __METHOD__, '1.19' );
-
+
global $wgLang;
$query = wfCgiToArray( $query );
@@ -1856,6 +1976,8 @@ function wfViewPrevNext( $offset, $limit, $link, $query = '', $atend = false ) {
* @deprecated since 1.19; use Language::specialList() instead
*/
function wfSpecialList( $page, $details, $oppositedm = true ) {
+ wfDeprecated( __METHOD__, '1.19' );
+
global $wgLang;
return $wgLang->specialList( $page, $details, $oppositedm );
}
@@ -1910,7 +2032,7 @@ function wfCheckLimits( $deflimit = 50, $optionname = 'rclimit' ) {
* Escapes the given text so that it may be output using addWikiText()
* without any linking, formatting, etc. making its way through. This
* is achieved by substituting certain characters with HTML entities.
- * As required by the callers, <nowiki> is not used.
+ * As required by the callers, "<nowiki>" is not used.
*
* @param $text String: text to be escaped
* @return String
@@ -1978,7 +2100,7 @@ function wfSetBit( &$dest, $bit, $state = true ) {
* A wrapper around the PHP function var_export().
* Either print it or add it to the regular output ($wgOut).
*
- * @param $var A PHP variable to dump.
+ * @param $var mixed A PHP variable to dump.
*/
function wfVarDump( $var ) {
global $wgOut;
@@ -2057,13 +2179,7 @@ function wfResetOutputBuffers( $resetGzipEncoding = true ) {
if( $status['name'] == 'ob_gzhandler' ) {
// Reset the 'Content-Encoding' field set by this handler
// so we can start fresh.
- if ( function_exists( 'header_remove' ) ) {
- // Available since PHP 5.3.0
- header_remove( 'Content-Encoding' );
- } else {
- // We need to provide a valid content-coding. See bug 28069
- header( 'Content-Encoding: identity' );
- }
+ header_remove( 'Content-Encoding' );
break;
}
}
@@ -2212,11 +2328,7 @@ function wfSuppressWarnings( $end = false ) {
}
} else {
if ( !$suppressCount ) {
- // E_DEPRECATED is undefined in PHP 5.2
- if( !defined( 'E_DEPRECATED' ) ) {
- define( 'E_DEPRECATED', 8192 );
- }
- $originalLevel = error_reporting( E_ALL & ~( E_WARNING | E_NOTICE | E_USER_WARNING | E_USER_NOTICE | E_DEPRECATED ) );
+ $originalLevel = error_reporting( E_ALL & ~( E_WARNING | E_NOTICE | E_USER_WARNING | E_USER_NOTICE | E_DEPRECATED | E_USER_DEPRECATED ) );
}
++$suppressCount;
}
@@ -2297,118 +2409,13 @@ define( 'TS_ISO_8601_BASIC', 9 );
* @return Mixed: String / false The same date in the format specified in $outputtype or false
*/
function wfTimestamp( $outputtype = TS_UNIX, $ts = 0 ) {
- $uts = 0;
- $da = array();
- $strtime = '';
-
- if ( !$ts ) { // We want to catch 0, '', null... but not date strings starting with a letter.
- $uts = time();
- $strtime = "@$uts";
- } elseif ( preg_match( '/^(\d{4})\-(\d\d)\-(\d\d) (\d\d):(\d\d):(\d\d)$/D', $ts, $da ) ) {
- # TS_DB
- } elseif ( preg_match( '/^(\d{4}):(\d\d):(\d\d) (\d\d):(\d\d):(\d\d)$/D', $ts, $da ) ) {
- # TS_EXIF
- } elseif ( preg_match( '/^(\d{4})(\d\d)(\d\d)(\d\d)(\d\d)(\d\d)$/D', $ts, $da ) ) {
- # TS_MW
- } elseif ( preg_match( '/^-?\d{1,13}$/D', $ts ) ) {
- # TS_UNIX
- $uts = $ts;
- $strtime = "@$ts"; // http://php.net/manual/en/datetime.formats.compound.php
- } elseif ( preg_match( '/^\d{2}-\d{2}-\d{4} \d{2}:\d{2}:\d{2}.\d{6}$/', $ts ) ) {
- # TS_ORACLE // session altered to DD-MM-YYYY HH24:MI:SS.FF6
- $strtime = preg_replace( '/(\d\d)\.(\d\d)\.(\d\d)(\.(\d+))?/', "$1:$2:$3",
- str_replace( '+00:00', 'UTC', $ts ) );
- } elseif ( preg_match( '/^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2})(?:\.*\d*)?Z$/', $ts, $da ) ) {
- # TS_ISO_8601
- } elseif ( preg_match( '/^(\d{4})(\d{2})(\d{2})T(\d{2})(\d{2})(\d{2})(?:\.*\d*)?Z$/', $ts, $da ) ) {
- #TS_ISO_8601_BASIC
- } elseif ( preg_match( '/^(\d{4})\-(\d\d)\-(\d\d) (\d\d):(\d\d):(\d\d)\.*\d*[\+\- ](\d\d)$/', $ts, $da ) ) {
- # TS_POSTGRES
- } elseif ( preg_match( '/^(\d{4})\-(\d\d)\-(\d\d) (\d\d):(\d\d):(\d\d)\.*\d* GMT$/', $ts, $da ) ) {
- # TS_POSTGRES
- } elseif (preg_match( '/^(\d{4})\-(\d\d)\-(\d\d) (\d\d):(\d\d):(\d\d)\.\d\d\d$/', $ts, $da ) ) {
- # TS_DB2
- } elseif ( preg_match( '/^[ \t\r\n]*([A-Z][a-z]{2},[ \t\r\n]*)?' . # Day of week
- '\d\d?[ \t\r\n]*[A-Z][a-z]{2}[ \t\r\n]*\d{2}(?:\d{2})?' . # dd Mon yyyy
- '[ \t\r\n]*\d\d[ \t\r\n]*:[ \t\r\n]*\d\d[ \t\r\n]*:[ \t\r\n]*\d\d/S', $ts ) ) { # hh:mm:ss
- # TS_RFC2822, accepting a trailing comment. See http://www.squid-cache.org/mail-archive/squid-users/200307/0122.html / r77171
- # The regex is a superset of rfc2822 for readability
- $strtime = strtok( $ts, ';' );
- } elseif ( preg_match( '/^[A-Z][a-z]{5,8}, \d\d-[A-Z][a-z]{2}-\d{2} \d\d:\d\d:\d\d/', $ts ) ) {
- # TS_RFC850
- $strtime = $ts;
- } elseif ( preg_match( '/^[A-Z][a-z]{2} [A-Z][a-z]{2} +\d{1,2} \d\d:\d\d:\d\d \d{4}/', $ts ) ) {
- # asctime
- $strtime = $ts;
- } else {
- # Bogus value...
+ try {
+ $timestamp = new MWTimestamp( $ts );
+ return $timestamp->getTimestamp( $outputtype );
+ } catch( TimestampException $e ) {
wfDebug("wfTimestamp() fed bogus time value: TYPE=$outputtype; VALUE=$ts\n");
-
return false;
}
-
- static $formats = array(
- TS_UNIX => 'U',
- TS_MW => 'YmdHis',
- TS_DB => 'Y-m-d H:i:s',
- TS_ISO_8601 => 'Y-m-d\TH:i:s\Z',
- TS_ISO_8601_BASIC => 'Ymd\THis\Z',
- TS_EXIF => 'Y:m:d H:i:s', // This shouldn't ever be used, but is included for completeness
- TS_RFC2822 => 'D, d M Y H:i:s',
- TS_ORACLE => 'd-m-Y H:i:s.000000', // Was 'd-M-y h.i.s A' . ' +00:00' before r51500
- TS_POSTGRES => 'Y-m-d H:i:s',
- TS_DB2 => 'Y-m-d H:i:s',
- );
-
- if ( !isset( $formats[$outputtype] ) ) {
- throw new MWException( 'wfTimestamp() called with illegal output type.' );
- }
-
- if ( function_exists( "date_create" ) ) {
- if ( count( $da ) ) {
- $ds = sprintf("%04d-%02d-%02dT%02d:%02d:%02d.00+00:00",
- (int)$da[1], (int)$da[2], (int)$da[3],
- (int)$da[4], (int)$da[5], (int)$da[6]);
-
- $d = date_create( $ds, new DateTimeZone( 'GMT' ) );
- } elseif ( $strtime ) {
- $d = date_create( $strtime, new DateTimeZone( 'GMT' ) );
- } else {
- return false;
- }
-
- if ( !$d ) {
- wfDebug("wfTimestamp() fed