summaryrefslogtreecommitdiff
path: root/includes
diff options
context:
space:
mode:
authorPierre Schmitz <pierre@archlinux.de>2014-12-27 15:41:37 +0100
committerPierre Schmitz <pierre@archlinux.de>2014-12-31 11:43:28 +0100
commitc1f9b1f7b1b77776192048005dcc66dcf3df2bfb (patch)
tree2b38796e738dd74cb42ecd9bfd151803108386bc /includes
parentb88ab0086858470dd1f644e64cb4e4f62bb2be9b (diff)
Update to MediaWiki 1.24.1
Diffstat (limited to 'includes')
-rw-r--r--includes/AjaxDispatcher.php25
-rw-r--r--includes/AjaxResponse.php74
-rw-r--r--includes/ArrayUtils.php69
-rw-r--r--includes/AuthPlugin.php65
-rw-r--r--includes/AutoLoader.php757
-rw-r--r--includes/Autopromote.php15
-rw-r--r--includes/Block.php370
-rw-r--r--includes/Category.php57
-rw-r--r--includes/CategoryFinder.php (renamed from includes/Categoryfinder.php)77
-rw-r--r--includes/CategoryViewer.php203
-rw-r--r--includes/ChangeTags.php147
-rw-r--r--includes/Collation.php175
-rw-r--r--includes/ConfEditor.php1109
-rw-r--r--includes/Cookie.php59
-rw-r--r--includes/DefaultSettings.php1382
-rw-r--r--includes/Defines.php65
-rw-r--r--includes/DeprecatedGlobal.php17
-rw-r--r--includes/EditPage.php1422
-rw-r--r--includes/Exception.php824
-rw-r--r--includes/Export.php373
-rw-r--r--includes/FakeTitle.php141
-rw-r--r--includes/Fallback.php50
-rw-r--r--includes/Feed.php111
-rw-r--r--includes/FeedUtils.php52
-rw-r--r--includes/FileDeleteForm.php68
-rw-r--r--includes/ForkController.php20
-rw-r--r--includes/FormOptions.php58
-rw-r--r--includes/GitInfo.php323
-rw-r--r--includes/GlobalFunctions.php1376
-rw-r--r--includes/HTMLForm.php2965
-rw-r--r--includes/HistoryBlob.php146
-rw-r--r--includes/Hooks.php24
-rw-r--r--includes/Html.php226
-rw-r--r--includes/HtmlFormatter.php97
-rw-r--r--includes/HttpFunctions.php127
-rw-r--r--includes/Import.php518
-rw-r--r--includes/Init.php136
-rw-r--r--includes/Licenses.php58
-rw-r--r--includes/LinkFilter.php115
-rw-r--r--includes/Linker.php991
-rw-r--r--includes/MWNamespace.php (renamed from includes/Namespace.php)122
-rw-r--r--includes/MWTimestamp.php (renamed from includes/Timestamp.php)80
-rw-r--r--includes/MagicWord.php175
-rw-r--r--includes/MediaWiki.php (renamed from includes/Wiki.php)331
-rw-r--r--includes/MediaWikiVersionFetcher.php31
-rw-r--r--includes/Message.php464
-rw-r--r--includes/MessageBlobStore.php106
-rw-r--r--includes/Metadata.php204
-rw-r--r--includes/MimeMagic.php360
-rw-r--r--includes/MovePage.php343
-rw-r--r--includes/OutputHandler.php15
-rw-r--r--includes/OutputPage.php1761
-rw-r--r--includes/PHPVersionError.php29
-rw-r--r--includes/PathRouter.php28
-rw-r--r--includes/PoolCounter.php329
-rw-r--r--includes/Preferences.php527
-rw-r--r--includes/PrefixSearch.php239
-rw-r--r--includes/ProtectionForm.php313
-rw-r--r--includes/ProxyTools.php86
-rw-r--r--includes/Revision.php517
-rw-r--r--includes/RevisionList.php60
-rw-r--r--includes/Sanitizer.php232
-rw-r--r--includes/Setup.php307
-rw-r--r--includes/SiteConfiguration.php74
-rw-r--r--includes/SiteStats.php340
-rw-r--r--includes/SpecialPage.php1446
-rw-r--r--includes/SpecialPageFactory.php591
-rw-r--r--includes/SquidPurgeClient.php65
-rw-r--r--includes/StatCounter.php34
-rw-r--r--includes/Status.php151
-rw-r--r--includes/StreamFile.php16
-rw-r--r--includes/StubObject.php115
-rw-r--r--includes/TimestampException.php7
-rw-r--r--includes/Title.php1932
-rw-r--r--includes/TitleArray.php67
-rw-r--r--includes/TitleArrayFromResult.php86
-rw-r--r--includes/User.php1160
-rw-r--r--includes/UserArray.php83
-rw-r--r--includes/UserArrayFromResult.php90
-rw-r--r--includes/UserMailer.php883
-rw-r--r--includes/UserRightsProxy.php75
-rw-r--r--includes/WatchedItem.php194
-rw-r--r--includes/WebRequest.php479
-rw-r--r--includes/WebResponse.php41
-rw-r--r--includes/WebStart.php62
-rw-r--r--includes/WikiError.php154
-rw-r--r--includes/WikiMap.php58
-rw-r--r--includes/Xml.php368
-rw-r--r--includes/ZhClient.php164
-rw-r--r--includes/ZhConversion.php3
-rw-r--r--includes/actions/Action.php (renamed from includes/Action.php)312
-rw-r--r--includes/actions/CachedAction.php23
-rw-r--r--includes/actions/CreditsAction.php51
-rw-r--r--includes/actions/DeleteAction.php10
-rw-r--r--includes/actions/EditAction.php38
-rw-r--r--includes/actions/FormAction.php123
-rw-r--r--includes/actions/FormlessAction.php45
-rw-r--r--includes/actions/HistoryAction.php218
-rw-r--r--includes/actions/InfoAction.php97
-rw-r--r--includes/actions/MarkpatrolledAction.php1
-rw-r--r--includes/actions/ProtectAction.php29
-rw-r--r--includes/actions/RawAction.php97
-rw-r--r--includes/actions/RenderAction.php3
-rw-r--r--includes/actions/RevertAction.php61
-rw-r--r--includes/actions/RevisiondeleteAction.php1
-rw-r--r--includes/actions/RollbackAction.php27
-rw-r--r--includes/actions/SubmitAction.php42
-rw-r--r--includes/actions/UnprotectAction.php43
-rw-r--r--includes/actions/UnwatchAction.php57
-rw-r--r--includes/actions/ViewAction.php1
-rw-r--r--includes/actions/WatchAction.php59
-rw-r--r--includes/api/ApiBase.php2267
-rw-r--r--includes/api/ApiBlock.php77
-rw-r--r--includes/api/ApiClearHasMsg.php58
-rw-r--r--includes/api/ApiComparePages.php55
-rw-r--r--includes/api/ApiCreateAccount.php106
-rw-r--r--includes/api/ApiDelete.php91
-rw-r--r--includes/api/ApiDisabled.php2
-rw-r--r--includes/api/ApiEditPage.php217
-rw-r--r--includes/api/ApiEmailUser.php43
-rw-r--r--includes/api/ApiExpandTemplates.php120
-rw-r--r--includes/api/ApiFeedContributions.php55
-rw-r--r--includes/api/ApiFeedRecentChanges.php207
-rw-r--r--includes/api/ApiFeedWatchlist.php64
-rw-r--r--includes/api/ApiFileRevert.php67
-rw-r--r--includes/api/ApiFormatBase.php146
-rw-r--r--includes/api/ApiFormatDbg.php4
-rw-r--r--includes/api/ApiFormatDump.php4
-rw-r--r--includes/api/ApiFormatFeedWrapper.php101
-rw-r--r--includes/api/ApiFormatJson.php13
-rw-r--r--includes/api/ApiFormatPhp.php3
-rw-r--r--includes/api/ApiFormatRaw.php8
-rw-r--r--includes/api/ApiFormatTxt.php4
-rw-r--r--includes/api/ApiFormatWddx.php17
-rw-r--r--includes/api/ApiFormatXml.php36
-rw-r--r--includes/api/ApiFormatYaml.php8
-rw-r--r--includes/api/ApiHelp.php32
-rw-r--r--includes/api/ApiImageRotate.php42
-rw-r--r--includes/api/ApiImport.php50
-rw-r--r--includes/api/ApiLogin.php105
-rw-r--r--includes/api/ApiLogout.php6
-rw-r--r--includes/api/ApiMain.php476
-rw-r--r--includes/api/ApiModuleManager.php176
-rw-r--r--includes/api/ApiMove.php105
-rw-r--r--includes/api/ApiOpenSearch.php34
-rw-r--r--includes/api/ApiOptions.php51
-rw-r--r--includes/api/ApiPageSet.php207
-rw-r--r--includes/api/ApiParamInfo.php93
-rw-r--r--includes/api/ApiParse.php278
-rw-r--r--includes/api/ApiPatrol.php39
-rw-r--r--includes/api/ApiProtect.php99
-rw-r--r--includes/api/ApiPurge.php95
-rw-r--r--includes/api/ApiQuery.php302
-rw-r--r--includes/api/ApiQueryAllCategories.php40
-rw-r--r--includes/api/ApiQueryAllImages.php136
-rw-r--r--includes/api/ApiQueryAllLinks.php124
-rw-r--r--includes/api/ApiQueryAllMessages.php40
-rw-r--r--includes/api/ApiQueryAllPages.php63
-rw-r--r--includes/api/ApiQueryAllUsers.php175
-rw-r--r--includes/api/ApiQueryBacklinks.php83
-rw-r--r--includes/api/ApiQueryBacklinksprop.php472
-rw-r--r--includes/api/ApiQueryBase.php490
-rw-r--r--includes/api/ApiQueryBlocks.php147
-rw-r--r--includes/api/ApiQueryCategories.php52
-rw-r--r--includes/api/ApiQueryCategoryInfo.php42
-rw-r--r--includes/api/ApiQueryCategoryMembers.php141
-rw-r--r--includes/api/ApiQueryContributors.php282
-rw-r--r--includes/api/ApiQueryDeletedrevs.php275
-rw-r--r--includes/api/ApiQueryDuplicateFiles.php18
-rw-r--r--includes/api/ApiQueryExtLinksUsage.php44
-rw-r--r--includes/api/ApiQueryExternalLinks.php25
-rw-r--r--includes/api/ApiQueryFileRepoInfo.php18
-rw-r--r--includes/api/ApiQueryFilearchive.php178
-rw-r--r--includes/api/ApiQueryIWBacklinks.php51
-rw-r--r--includes/api/ApiQueryIWLinks.php77
-rw-r--r--includes/api/ApiQueryImageInfo.php425
-rw-r--r--includes/api/ApiQueryImages.php30
-rw-r--r--includes/api/ApiQueryInfo.php166
-rw-r--r--includes/api/ApiQueryLangBacklinks.php48
-rw-r--r--includes/api/ApiQueryLangLinks.php73
-rw-r--r--includes/api/ApiQueryLinks.php30
-rw-r--r--includes/api/ApiQueryLogEvents.php289
-rw-r--r--includes/api/ApiQueryORM.php3
-rw-r--r--includes/api/ApiQueryPagePropNames.php7
-rw-r--r--includes/api/ApiQueryPageProps.php14
-rw-r--r--includes/api/ApiQueryPagesWithProp.php15
-rw-r--r--includes/api/ApiQueryPrefixSearch.php124
-rw-r--r--includes/api/ApiQueryProtectedTitles.php88
-rw-r--r--includes/api/ApiQueryQueryPage.php65
-rw-r--r--includes/api/ApiQueryRandom.php61
-rw-r--r--includes/api/ApiQueryRecentChanges.php446
-rw-r--r--includes/api/ApiQueryRevisions.php316
-rw-r--r--includes/api/ApiQuerySearch.php165
-rw-r--r--includes/api/ApiQuerySiteinfo.php340
-rw-r--r--includes/api/ApiQueryStashImageInfo.php20
-rw-r--r--includes/api/ApiQueryTags.php25
-rw-r--r--includes/api/ApiQueryTokens.php104
-rw-r--r--includes/api/ApiQueryUserContributions.php262
-rw-r--r--includes/api/ApiQueryUserInfo.php114
-rw-r--r--includes/api/ApiQueryUsers.php117
-rw-r--r--includes/api/ApiQueryWatchlist.php410
-rw-r--r--includes/api/ApiQueryWatchlistRaw.php41
-rw-r--r--includes/api/ApiResult.php314
-rw-r--r--includes/api/ApiRevisionDelete.php236
-rw-r--r--includes/api/ApiRollback.php126
-rw-r--r--includes/api/ApiRsd.php10
-rw-r--r--includes/api/ApiSetNotificationTimestamp.php185
-rw-r--r--includes/api/ApiTokens.php21
-rw-r--r--includes/api/ApiUnblock.php50
-rw-r--r--includes/api/ApiUndelete.php58
-rw-r--r--includes/api/ApiUpload.php186
-rw-r--r--includes/api/ApiUserrights.php51
-rw-r--r--includes/api/ApiWatch.php155
-rw-r--r--includes/cache/BacklinkCache.php125
-rw-r--r--includes/cache/CacheDependency.php230
-rw-r--r--includes/cache/CacheHelper.php (renamed from includes/CacheHelper.php)64
-rw-r--r--includes/cache/FileCacheBase.php15
-rw-r--r--includes/cache/GenderCache.php28
-rw-r--r--includes/cache/HTMLFileCache.php47
-rw-r--r--includes/cache/LinkBatch.php47
-rw-r--r--includes/cache/LinkCache.php75
-rw-r--r--includes/cache/LocalisationCache.php571
-rw-r--r--includes/cache/MapCacheLRU.php123
-rw-r--r--includes/cache/MessageCache.php83
-rw-r--r--includes/cache/ObjectFileCache.php4
-rw-r--r--includes/cache/ResourceFileCache.php7
-rw-r--r--includes/cache/UserCache.php16
-rw-r--r--includes/cache/bloom/BloomCache.php323
-rw-r--r--includes/cache/bloom/BloomCacheRedis.php370
-rw-r--r--includes/cache/bloom/BloomFilters.php79
-rw-r--r--includes/changes/ChangesFeed.php (renamed from includes/ChangesFeed.php)71
-rw-r--r--includes/changes/ChangesList.php250
-rw-r--r--includes/changes/EnhancedChangesList.php336
-rw-r--r--includes/changes/OldChangesList.php95
-rw-r--r--includes/changes/RCCacheEntry.php16
-rw-r--r--includes/changes/RCCacheEntryFactory.php275
-rw-r--r--includes/changes/RecentChange.php523
-rw-r--r--includes/clientpool/RedisConnectionPool.php197
-rw-r--r--includes/composer/ComposerHookHandler.php37
-rw-r--r--includes/composer/ComposerPackageModifier.php62
-rw-r--r--includes/composer/ComposerVersionNormalizer.php66
-rw-r--r--includes/config/Config.php47
-rw-r--r--includes/config/ConfigException.php29
-rw-r--r--includes/config/ConfigFactory.php112
-rw-r--r--includes/config/GlobalVarConfig.php108
-rw-r--r--includes/config/HashConfig.php75
-rw-r--r--includes/config/MultiConfig.php72
-rw-r--r--includes/config/MutableConfig.php38
-rw-r--r--includes/content/AbstractContent.php277
-rw-r--r--includes/content/CodeContentHandler.php65
-rw-r--r--includes/content/Content.php163
-rw-r--r--includes/content/ContentHandler.php298
-rw-r--r--includes/content/CssContent.php28
-rw-r--r--includes/content/CssContentHandler.php37
-rw-r--r--includes/content/JavaScriptContent.php20
-rw-r--r--includes/content/JavaScriptContentHandler.php37
-rw-r--r--includes/content/JsonContent.php120
-rw-r--r--includes/content/JsonContentHandler.php26
-rw-r--r--includes/content/MessageContent.php54
-rw-r--r--includes/content/TextContent.php137
-rw-r--r--includes/content/TextContentHandler.php48
-rw-r--r--includes/content/WikitextContent.php175
-rw-r--r--includes/content/WikitextContentHandler.php44
-rw-r--r--includes/context/ContextSource.php34
-rw-r--r--includes/context/DerivativeContext.php58
-rw-r--r--includes/context/IContextSource.php20
-rw-r--r--includes/context/RequestContext.php187
-rw-r--r--includes/dao/DBAccessBase.php8
-rw-r--r--includes/dao/IDBAccessObject.php13
-rw-r--r--includes/db/ChronologyProtector.php13
-rw-r--r--includes/db/CloneDatabase.php65
-rw-r--r--includes/db/Database.php1325
-rw-r--r--includes/db/DatabaseError.php181
-rw-r--r--includes/db/DatabaseMssql.php1502
-rw-r--r--includes/db/DatabaseMysql.php35
-rw-r--r--includes/db/DatabaseMysqlBase.php451
-rw-r--r--includes/db/DatabaseMysqli.php138
-rw-r--r--includes/db/DatabaseOracle.php376
-rw-r--r--includes/db/DatabasePostgres.php426
-rw-r--r--includes/db/DatabaseSqlite.php289
-rw-r--r--includes/db/DatabaseUtility.php71
-rw-r--r--includes/db/IORMRow.php32
-rw-r--r--includes/db/IORMTable.php65
-rw-r--r--includes/db/LBFactory.php152
-rw-r--r--includes/db/LBFactoryMulti.php (renamed from includes/db/LBFactory_Multi.php)175
-rw-r--r--includes/db/LBFactorySingle.php (renamed from includes/db/LBFactory_Single.php)50
-rw-r--r--includes/db/LoadBalancer.php458
-rw-r--r--includes/db/LoadMonitor.php129
-rw-r--r--includes/db/ORMIterator.php1
-rw-r--r--includes/db/ORMResult.php14
-rw-r--r--includes/db/ORMRow.php55
-rw-r--r--includes/db/ORMTable.php123
-rw-r--r--includes/debug/MWDebug.php (renamed from includes/debug/Debug.php)121
-rw-r--r--includes/deferred/CallableUpdate.php (renamed from includes/CallableUpdate.php)5
-rw-r--r--includes/deferred/DataUpdate.php (renamed from includes/DataUpdate.php)13
-rw-r--r--includes/deferred/DeferredUpdates.php (renamed from includes/DeferredUpdates.php)43
-rw-r--r--includes/deferred/HTMLCacheUpdate.php (renamed from includes/cache/HTMLCacheUpdate.php)17
-rw-r--r--includes/deferred/LinksUpdate.php (renamed from includes/LinksUpdate.php)254
-rw-r--r--includes/deferred/SearchUpdate.php (renamed from includes/search/SearchUpdate.php)52
-rw-r--r--includes/deferred/SiteStatsUpdate.php254
-rw-r--r--includes/deferred/SqlDataUpdate.php (renamed from includes/SqlDataUpdate.php)45
-rw-r--r--includes/deferred/SquidUpdate.php (renamed from includes/cache/SquidUpdate.php)25
-rw-r--r--includes/deferred/ViewCountUpdate.php (renamed from includes/ViewCountUpdate.php)26
-rw-r--r--includes/diff/ArrayDiffFormatter.php82
-rw-r--r--includes/diff/DairikiDiff.php911
-rw-r--r--includes/diff/DiffFormatter.php247
-rw-r--r--includes/diff/DifferenceEngine.php502
-rw-r--r--includes/diff/TableDiffFormatter.php214
-rw-r--r--includes/diff/UnifiedDiffFormatter.php74
-rw-r--r--includes/diff/WikiDiff3.php89
-rw-r--r--includes/exception/BadTitleError.php51
-rw-r--r--includes/exception/ErrorPageError.php61
-rw-r--r--includes/exception/FatalError.php43
-rw-r--r--includes/exception/HttpError.php93
-rw-r--r--includes/exception/MWException.php262
-rw-r--r--includes/exception/MWExceptionHandler.php372
-rw-r--r--includes/exception/PermissionsError.php58
-rw-r--r--includes/exception/ReadOnlyError.php36
-rw-r--r--includes/exception/ThrottledError.php40
-rw-r--r--includes/exception/UserBlockedError.php33
-rw-r--r--includes/exception/UserNotLoggedIn.php102
-rw-r--r--includes/externalstore/ExternalStore.php10
-rw-r--r--includes/externalstore/ExternalStoreDB.php92
-rw-r--r--includes/externalstore/ExternalStoreMedium.php9
-rw-r--r--includes/externalstore/ExternalStoreMwstore.php11
-rw-r--r--includes/filebackend/FSFile.php38
-rw-r--r--includes/filebackend/FSFileBackend.php201
-rw-r--r--includes/filebackend/FileBackend.php300
-rw-r--r--includes/filebackend/FileBackendGroup.php46
-rw-r--r--includes/filebackend/FileBackendMultiWrite.php102
-rw-r--r--includes/filebackend/FileBackendStore.php383
-rw-r--r--includes/filebackend/FileOp.php183
-rw-r--r--includes/filebackend/FileOpBatch.php21
-rw-r--r--includes/filebackend/MemoryFileBackend.php274
-rw-r--r--includes/filebackend/README2
-rw-r--r--includes/filebackend/SwiftFileBackend.php2108
-rw-r--r--includes/filebackend/TempFSFile.php50
-rw-r--r--includes/filebackend/filejournal/DBFileJournal.php22
-rw-r--r--includes/filebackend/filejournal/FileJournal.php68
-rw-r--r--includes/filebackend/lockmanager/DBLockManager.php44
-rw-r--r--includes/filebackend/lockmanager/FSLockManager.php35
-rw-r--r--includes/filebackend/lockmanager/LSLockManager.php218
-rw-r--r--includes/filebackend/lockmanager/LockManager.php41
-rw-r--r--includes/filebackend/lockmanager/LockManagerGroup.php22
-rw-r--r--includes/filebackend/lockmanager/MemcLockManager.php50
-rw-r--r--includes/filebackend/lockmanager/QuorumLockManager.php22
-rw-r--r--includes/filebackend/lockmanager/RedisLockManager.php150
-rw-r--r--includes/filebackend/lockmanager/ScopedLock.php15
-rw-r--r--includes/filerepo/FSRepo.php6
-rw-r--r--includes/filerepo/FileRepo.php453
-rw-r--r--includes/filerepo/FileRepoStatus.php11
-rw-r--r--includes/filerepo/ForeignAPIRepo.php139
-rw-r--r--includes/filerepo/ForeignDBRepo.php46
-rw-r--r--includes/filerepo/ForeignDBViaLBRepo.php24
-rw-r--r--includes/filerepo/LocalRepo.php195
-rw-r--r--includes/filerepo/NullRepo.php6
-rw-r--r--includes/filerepo/RepoGroup.php186
-rw-r--r--includes/filerepo/file/ArchivedFile.php165
-rw-r--r--includes/filerepo/file/File.php827
-rw-r--r--includes/filerepo/file/ForeignAPIFile.php53
-rw-r--r--includes/filerepo/file/ForeignDBFile.php58
-rw-r--r--includes/filerepo/file/LocalFile.php994
-rw-r--r--includes/filerepo/file/OldLocalFile.php125
-rw-r--r--includes/filerepo/file/UnregisteredLocalFile.php63
-rw-r--r--includes/gallery/ImageGalleryBase.php165
-rw-r--r--includes/gallery/NolinesImageGallery.php1
-rw-r--r--includes/gallery/PackedImageGallery.php11
-rw-r--r--includes/gallery/PackedOverlayImageGallery.php22
-rw-r--r--includes/gallery/TraditionalImageGallery.php114
-rw-r--r--includes/htmlform/HTMLApiField.php19
-rw-r--r--includes/htmlform/HTMLAutoCompleteSelectField.php165
-rw-r--r--includes/htmlform/HTMLButtonField.php42
-rw-r--r--includes/htmlform/HTMLCheckField.php91
-rw-r--r--includes/htmlform/HTMLCheckMatrix.php250
-rw-r--r--includes/htmlform/HTMLEditTools.php51
-rw-r--r--includes/htmlform/HTMLFloatField.php46
-rw-r--r--includes/htmlform/HTMLForm.php1472
-rw-r--r--includes/htmlform/HTMLFormField.php893
-rw-r--r--includes/htmlform/HTMLFormFieldCloner.php382
-rw-r--r--includes/htmlform/HTMLFormFieldRequiredOptionsException.php9
-rw-r--r--includes/htmlform/HTMLHiddenField.php44
-rw-r--r--includes/htmlform/HTMLInfoField.php54
-rw-r--r--includes/htmlform/HTMLIntField.php27
-rw-r--r--includes/htmlform/HTMLMultiSelectField.php122
-rw-r--r--includes/htmlform/HTMLNestedFilterable.php11
-rw-r--r--includes/htmlform/HTMLRadioField.php71
-rw-r--r--includes/htmlform/HTMLSelectAndOtherField.php126
-rw-r--r--includes/htmlform/HTMLSelectField.php44
-rw-r--r--includes/htmlform/HTMLSelectLimitField.php35
-rw-r--r--includes/htmlform/HTMLSelectOrOtherField.php83
-rw-r--r--includes/htmlform/HTMLSubmitField.php9
-rw-r--r--includes/htmlform/HTMLTextAreaField.php38
-rw-r--r--includes/htmlform/HTMLTextField.php65
-rw-r--r--includes/installer/CliInstaller.php20
-rw-r--r--includes/installer/DatabaseInstaller.php99
-rw-r--r--includes/installer/DatabaseUpdater.php161
-rw-r--r--includes/installer/InstallDocFormatter.php2
-rw-r--r--includes/installer/Installer.i18n.php21554
-rw-r--r--includes/installer/Installer.php457
-rw-r--r--includes/installer/LocalSettingsGenerator.php87
-rw-r--r--includes/installer/MssqlInstaller.php737
-rw-r--r--includes/installer/MssqlUpdater.php138
-rw-r--r--includes/installer/MysqlInstaller.php33
-rw-r--r--includes/installer/MysqlUpdater.php81
-rw-r--r--includes/installer/OracleInstaller.php1
-rw-r--r--includes/installer/OracleUpdater.php23
-rw-r--r--includes/installer/PhpBugTests.php26
-rw-r--r--includes/installer/PostgresInstaller.php43
-rw-r--r--includes/installer/PostgresUpdater.php51
-rw-r--r--includes/installer/SqliteInstaller.php10
-rw-r--r--includes/installer/SqliteUpdater.php23
-rw-r--r--includes/installer/WebInstaller.php264
-rw-r--r--includes/installer/WebInstallerOutput.php173
-rw-r--r--includes/installer/WebInstallerPage.php366
-rw-r--r--includes/installer/i18n/af.json154
-rw-r--r--includes/installer/i18n/aln.json9
-rw-r--r--includes/installer/i18n/am.json5
-rw-r--r--includes/installer/i18n/an.json9
-rw-r--r--includes/installer/i18n/ang.json9
-rw-r--r--includes/installer/i18n/ar.json120
-rw-r--r--includes/installer/i18n/arc.json22
-rw-r--r--includes/installer/i18n/ary.json10
-rw-r--r--includes/installer/i18n/arz.json18
-rw-r--r--includes/installer/i18n/as.json10
-rw-r--r--includes/installer/i18n/ast.json71
-rw-r--r--includes/installer/i18n/av.json8
-rw-r--r--includes/installer/i18n/avk.json4
-rw-r--r--includes/installer/i18n/az.json33
-rw-r--r--includes/installer/i18n/ba.json10
-rw-r--r--includes/installer/i18n/bar.json13
-rw-r--r--includes/installer/i18n/bcc.json5
-rw-r--r--includes/installer/i18n/bcl.json37
-rw-r--r--includes/installer/i18n/be-tarask.json333
-rw-r--r--includes/installer/i18n/be.json20
-rw-r--r--includes/installer/i18n/bg.json293
-rw-r--r--includes/installer/i18n/bjn.json10
-rw-r--r--includes/installer/i18n/bn.json125
-rw-r--r--includes/installer/i18n/bpy.json5
-rw-r--r--includes/installer/i18n/br.json283
-rw-r--r--includes/installer/i18n/bs.json59
-rw-r--r--includes/installer/i18n/bto.json65
-rw-r--r--includes/installer/i18n/ca.json203
-rw-r--r--includes/installer/i18n/ce.json92
-rw-r--r--includes/installer/i18n/ceb.json5
-rw-r--r--includes/installer/i18n/ckb.json42
-rw-r--r--includes/installer/i18n/cps.json10
-rw-r--r--includes/installer/i18n/crh-cyrl.json5
-rw-r--r--includes/installer/i18n/crh-latn.json5
-rw-r--r--includes/installer/i18n/cs.json334
-rw-r--r--includes/installer/i18n/csb.json4
-rw-r--r--includes/installer/i18n/cu.json10
-rw-r--r--includes/installer/i18n/cv.json9
-rw-r--r--includes/installer/i18n/cy.json12
-rw-r--r--includes/installer/i18n/da.json38
-rw-r--r--includes/installer/i18n/de-ch.json8
-rw-r--r--includes/installer/i18n/de-formal.json12
-rw-r--r--includes/installer/i18n/de.json340
-rw-r--r--includes/installer/i18n/diq.json67
-rw-r--r--includes/installer/i18n/dsb.json9
-rw-r--r--includes/installer/i18n/dtp.json9
-rw-r--r--includes/installer/i18n/el.json111
-rw-r--r--includes/installer/i18n/en-gb.json22
-rw-r--r--includes/installer/i18n/en.json326
-rw-r--r--includes/installer/i18n/eo.json50
-rw-r--r--includes/installer/i18n/es-formal.json9
-rw-r--r--includes/installer/i18n/es.json352
-rw-r--r--includes/installer/i18n/et.json68
-rw-r--r--includes/installer/i18n/eu.json78
-rw-r--r--includes/installer/i18n/ext.json5
-rw-r--r--includes/installer/i18n/fa.json331
-rw-r--r--includes/installer/i18n/fi.json220
-rw-r--r--includes/installer/i18n/fo.json40
-rw-r--r--includes/installer/i18n/fr.json348
-rw-r--r--includes/installer/i18n/frc.json5
-rw-r--r--includes/installer/i18n/frp.json153
-rw-r--r--includes/installer/i18n/frr.json10
-rw-r--r--includes/installer/i18n/fur.json15
-rw-r--r--includes/installer/i18n/fy.json9
-rw-r--r--includes/installer/i18n/ga.json13
-rw-r--r--includes/installer/i18n/gag.json5
-rw-r--r--includes/installer/i18n/gan-hans.json5
-rw-r--r--includes/installer/i18n/gan-hant.json9
-rw-r--r--includes/installer/i18n/gd.json9
-rw-r--r--includes/installer/i18n/gl.json331
-rw-r--r--includes/installer/i18n/gom-latn.json9
-rw-r--r--includes/installer/i18n/grc.json11
-rw-r--r--includes/installer/i18n/gsw.json68
-rw-r--r--includes/installer/i18n/gu.json45
-rw-r--r--includes/installer/i18n/gv.json4
-rw-r--r--includes/installer/i18n/hak.json5
-rw-r--r--includes/installer/i18n/haw.json64
-rw-r--r--includes/installer/i18n/he.json330
-rw-r--r--includes/installer/i18n/hi.json49
-rw-r--r--includes/installer/i18n/hif-latn.json9
-rw-r--r--includes/installer/i18n/hil.json9
-rw-r--r--includes/installer/i18n/hr.json5
-rw-r--r--includes/installer/i18n/hrx.json314
-rw-r--r--includes/installer/i18n/hsb.json256
-rw-r--r--includes/installer/i18n/ht.json10
-rw-r--r--includes/installer/i18n/hu-formal.json33
-rw-r--r--includes/installer/i18n/hu.json304
-rw-r--r--includes/installer/i18n/hy.json5
-rw-r--r--includes/installer/i18n/ia.json318
-rw-r--r--includes/installer/i18n/id.json323
-rw-r--r--includes/installer/i18n/ie.json4
-rw-r--r--includes/installer/i18n/ig.json17
-rw-r--r--includes/installer/i18n/ilo.json4
-rw-r--r--includes/installer/i18n/io.json9
-rw-r--r--includes/installer/i18n/is.json5
-rw-r--r--includes/installer/i18n/it.json334
-rw-r--r--includes/installer/i18n/ja.json338
-rw-r--r--includes/installer/i18n/jam.json9
-rw-r--r--includes/installer/i18n/jut.json9
-rw-r--r--includes/installer/i18n/jv.json5
-rw-r--r--includes/installer/i18n/ka.json97
-rw-r--r--includes/installer/i18n/kaa.json5
-rw-r--r--includes/installer/i18n/kbd-cyrl.json10
-rw-r--r--includes/installer/i18n/khw.json8
-rw-r--r--includes/installer/i18n/kiu.json9
-rw-r--r--includes/installer/i18n/kk-arab.json5
-rw-r--r--includes/installer/i18n/kk-cyrl.json5
-rw-r--r--includes/installer/i18n/kk-latn.json5
-rw-r--r--includes/installer/i18n/km.json32
-rw-r--r--includes/installer/i18n/kn.json46
-rw-r--r--includes/installer/i18n/ko.json323
-rw-r--r--includes/installer/i18n/krc.json29
-rw-r--r--includes/installer/i18n/ksh.json319
-rw-r--r--includes/installer/i18n/ku-latn.json17
-rw-r--r--includes/installer/i18n/lad.json10
-rw-r--r--includes/installer/i18n/lb.json212
-rw-r--r--includes/installer/i18n/lez.json27
-rw-r--r--includes/installer/i18n/lfn.json5
-rw-r--r--includes/installer/i18n/lg.json9
-rw-r--r--includes/installer/i18n/li.json9
-rw-r--r--includes/installer/i18n/lo.json4
-rw-r--r--includes/installer/i18n/lrc.json24
-rw-r--r--includes/installer/i18n/lt.json89
-rw-r--r--includes/installer/i18n/lv.json45
-rw-r--r--includes/installer/i18n/lzh.json10
-rw-r--r--includes/installer/i18n/lzz.json9
-rw-r--r--includes/installer/i18n/mai.json9
-rw-r--r--includes/installer/i18n/mdf.json5
-rw-r--r--includes/installer/i18n/mg.json65
-rw-r--r--includes/installer/i18n/mhr.json4
-rw-r--r--includes/installer/i18n/min.json11
-rw-r--r--includes/installer/i18n/mk.json329
-rw-r--r--includes/installer/i18n/ml.json120
-rw-r--r--includes/installer/i18n/mn.json10
-rw-r--r--includes/installer/i18n/mr.json62
-rw-r--r--includes/installer/i18n/ms.json151
-rw-r--r--includes/installer/i18n/mt.json90
-rw-r--r--includes/installer/i18n/my.json8
-rw-r--r--includes/installer/i18n/myv.json16
-rw-r--r--includes/installer/i18n/mzn.json8
-rw-r--r--includes/installer/i18n/nah.json4
-rw-r--r--includes/installer/i18n/nan.json59
-rw-r--r--includes/installer/i18n/nap.json16
-rw-r--r--includes/installer/i18n/nb.json324
-rw-r--r--includes/installer/i18n/nds-nl.json9
-rw-r--r--includes/installer/i18n/nds.json14
-rw-r--r--includes/installer/i18n/ne.json26
-rw-r--r--includes/installer/i18n/nl-informal.json79
-rw-r--r--includes/installer/i18n/nl.json330
-rw-r--r--includes/installer/i18n/nn.json41
-rw-r--r--includes/installer/i18n/oc.json181
-rw-r--r--includes/installer/i18n/or.json33
-rw-r--r--includes/installer/i18n/os.json9
-rw-r--r--includes/installer/i18n/pa.json13
-rw-r--r--includes/installer/i18n/pam.json5
-rw-r--r--includes/installer/i18n/pcd.json4
-rw-r--r--includes/installer/i18n/pdc.json13
-rw-r--r--includes/installer/i18n/pl.json340
-rw-r--r--includes/installer/i18n/pms.json301
-rw-r--r--includes/installer/i18n/pnt.json8
-rw-r--r--includes/installer/i18n/prg.json9
-rw-r--r--includes/installer/i18n/ps.json65
-rw-r--r--includes/installer/i18n/pt-br.json244
-rw-r--r--includes/installer/i18n/pt.json335
-rw-r--r--includes/installer/i18n/qqq.json344
-rw-r--r--includes/installer/i18n/qu.json20
-rw-r--r--includes/installer/i18n/rgn.json4
-rw-r--r--includes/installer/i18n/rm.json9
-rw-r--r--includes/installer/i18n/ro.json140
-rw-r--r--includes/installer/i18n/roa-tara.json56
-rw-r--r--includes/installer/i18n/ru.json344
-rw-r--r--includes/installer/i18n/rue.json9
-rw-r--r--includes/installer/i18n/sa.json8
-rw-r--r--includes/installer/i18n/sah.json5
-rw-r--r--includes/installer/i18n/sc.json14
-rw-r--r--includes/installer/i18n/scn.json5
-rw-r--r--includes/installer/i18n/sco.json314
-rw-r--r--includes/installer/i18n/sdc.json19
-rw-r--r--includes/installer/i18n/sei.json4
-rw-r--r--includes/installer/i18n/sh.json10
-rw-r--r--includes/installer/i18n/shi.json10
-rw-r--r--includes/installer/i18n/si.json142
-rw-r--r--includes/installer/i18n/sk.json78
-rw-r--r--includes/installer/i18n/sl.json174
-rw-r--r--includes/installer/i18n/sli.json9
-rw-r--r--includes/installer/i18n/so.json9
-rw-r--r--includes/installer/i18n/sq.json5
-rw-r--r--includes/installer/i18n/sr-ec.json73
-rw-r--r--includes/installer/i18n/sr-el.json39
-rw-r--r--includes/installer/i18n/srn.json9
-rw-r--r--includes/installer/i18n/ss.json4
-rw-r--r--includes/installer/i18n/stq.json9
-rw-r--r--includes/installer/i18n/su.json5
-rw-r--r--includes/installer/i18n/sv.json330
-rw-r--r--includes/installer/i18n/sw.json9
-rw-r--r--includes/installer/i18n/szl.json9
-rw-r--r--includes/installer/i18n/ta.json90
-rw-r--r--includes/installer/i18n/tcy.json5
-rw-r--r--includes/installer/i18n/te.json240
-rw-r--r--includes/installer/i18n/tet.json9
-rw-r--r--includes/installer/i18n/tg-cyrl.json9
-rw-r--r--includes/installer/i18n/tg-latn.json9
-rw-r--r--includes/installer/i18n/th.json10
-rw-r--r--includes/installer/i18n/tk.json9
-rw-r--r--includes/installer/i18n/tl.json305
-rw-r--r--includes/installer/i18n/tly.json8
-rw-r--r--includes/installer/i18n/tr.json201
-rw-r--r--includes/installer/i18n/tt-cyrl.json10
-rw-r--r--includes/installer/i18n/tt-latn.json10
-rw-r--r--includes/installer/i18n/tyv.json8
-rw-r--r--includes/installer/i18n/udm.json8
-rw-r--r--includes/installer/i18n/ug-arab.json9
-rw-r--r--includes/installer/i18n/uk.json332
-rw-r--r--includes/installer/i18n/ur.json34
-rw-r--r--includes/installer/i18n/uz.json10
-rw-r--r--includes/installer/i18n/vec.json10
-rw-r--r--includes/installer/i18n/vep.json10
-rw-r--r--includes/installer/i18n/vi.json195
-rw-r--r--includes/installer/i18n/vo.json5
-rw-r--r--includes/installer/i18n/vro.json5
-rw-r--r--includes/installer/i18n/wa.json8
-rw-r--r--includes/installer/i18n/war.json72
-rw-r--r--includes/installer/i18n/wo.json9
-rw-r--r--includes/installer/i18n/wuu.json9
-rw-r--r--includes/installer/i18n/xal.json9
-rw-r--r--includes/installer/i18n/yi.json58
-rw-r--r--includes/installer/i18n/yo.json19
-rw-r--r--includes/installer/i18n/yue.json5
-rw-r--r--includes/installer/i18n/zea.json9
-rw-r--r--includes/installer/i18n/zh-hans.json345
-rw-r--r--includes/installer/i18n/zh-hant.json335
-rw-r--r--includes/installer/i18n/zh-hk.json8
-rw-r--r--includes/installer/i18n/zh-tw.json4
-rw-r--r--includes/interwiki/Interwiki.php195
-rw-r--r--includes/job/jobs/HTMLCacheUpdateJob.php263
-rw-r--r--includes/jobqueue/Job.php (renamed from includes/job/Job.php)129
-rw-r--r--includes/jobqueue/JobQueue.php (renamed from includes/job/JobQueue.php)156
-rw-r--r--includes/jobqueue/JobQueueDB.php (renamed from includes/job/JobQueueDB.php)143
-rw-r--r--includes/jobqueue/JobQueueFederated.php (renamed from includes/job/JobQueueFederated.php)218
-rw-r--r--includes/jobqueue/JobQueueGroup.php (renamed from includes/job/JobQueueGroup.php)143
-rw-r--r--includes/jobqueue/JobQueueRedis.php (renamed from includes/job/JobQueueRedis.php)357
-rw-r--r--includes/jobqueue/JobRunner.php350
-rw-r--r--includes/jobqueue/JobSpecification.php189
-rw-r--r--includes/jobqueue/README (renamed from includes/job/README)0
-rw-r--r--includes/jobqueue/aggregator/JobQueueAggregator.php (renamed from includes/job/aggregator/JobQueueAggregator.php)12
-rw-r--r--includes/jobqueue/aggregator/JobQueueAggregatorMemc.php (renamed from includes/job/aggregator/JobQueueAggregatorMemc.php)5
-rw-r--r--includes/jobqueue/aggregator/JobQueueAggregatorRedis.php (renamed from includes/job/aggregator/JobQueueAggregatorRedis.php)93
-rw-r--r--includes/jobqueue/jobs/AssembleUploadChunksJob.php (renamed from includes/job/jobs/AssembleUploadChunksJob.php)15
-rw-r--r--includes/jobqueue/jobs/DoubleRedirectJob.php (renamed from includes/job/jobs/DoubleRedirectJob.php)57
-rw-r--r--includes/jobqueue/jobs/DuplicateJob.php (renamed from includes/job/jobs/DuplicateJob.php)12
-rw-r--r--includes/jobqueue/jobs/EmaillingJob.php (renamed from includes/job/jobs/EmaillingJob.php)5
-rw-r--r--includes/jobqueue/jobs/EnotifNotifyJob.php (renamed from includes/job/jobs/EnotifNotifyJob.php)9
-rw-r--r--includes/jobqueue/jobs/HTMLCacheUpdateJob.php162
-rw-r--r--includes/jobqueue/jobs/NullJob.php (renamed from includes/job/jobs/NullJob.php)10
-rw-r--r--includes/jobqueue/jobs/PublishStashedFileJob.php (renamed from includes/job/jobs/PublishStashedFileJob.php)18
-rw-r--r--includes/jobqueue/jobs/RefreshLinksJob.php199
-rw-r--r--includes/jobqueue/jobs/RefreshLinksJob2.php (renamed from includes/job/jobs/RefreshLinksJob.php)101
-rw-r--r--includes/jobqueue/jobs/UploadFromUrlJob.php (renamed from includes/job/jobs/UploadFromUrlJob.php)31
-rw-r--r--includes/jobqueue/utils/BacklinkJobUtils.php122
-rw-r--r--includes/json/FormatJson.php150
-rw-r--r--includes/libs/CSSJanus.php246
-rw-r--r--includes/libs/CSSMin.php300
-rw-r--r--includes/libs/GenericArrayObject.php5
-rw-r--r--includes/libs/HashRing.php (renamed from includes/HashRing.php)109
-rw-r--r--includes/libs/HttpStatus.php8
-rw-r--r--includes/libs/IEContentAnalyzer.php7
-rw-r--r--includes/libs/IPSet.php277
-rw-r--r--includes/libs/JavaScriptMinifier.php1
-rw-r--r--includes/libs/MWMessagePack.php189
-rw-r--r--includes/libs/MappedIterator.php (renamed from includes/MappedIterator.php)7
-rw-r--r--includes/libs/MultiHttpClient.php389
-rw-r--r--includes/libs/ProcessCacheLRU.php (renamed from includes/cache/ProcessCacheLRU.php)27
-rw-r--r--includes/libs/RunningStat.php176
-rw-r--r--includes/libs/ScopedCallback.php (renamed from includes/ScopedCallback.php)4
-rw-r--r--includes/libs/ScopedPHPTimeout.php (renamed from includes/ScopedPHPTimeout.php)0
-rw-r--r--includes/libs/XmlTypeCheck.php (renamed from includes/XmlTypeCheck.php)0
-rw-r--r--includes/libs/jsminplus.php1
-rw-r--r--includes/libs/lessc.inc.php88
-rw-r--r--includes/libs/virtualrest/SwiftVirtualRESTService.php175
-rw-r--r--includes/libs/virtualrest/VirtualRESTService.php107
-rw-r--r--includes/libs/virtualrest/VirtualRESTServiceClient.php289
-rw-r--r--includes/limit.sh83
-rw-r--r--includes/logging/DeleteLogFormatter.php208
-rw-r--r--includes/logging/LogEntry.php126
-rw-r--r--includes/logging/LogEventsList.php235
-rw-r--r--includes/logging/LogFormatter.php126
-rw-r--r--includes/logging/LogPage.php178
-rw-r--r--includes/logging/LogPager.php112
-rw-r--r--includes/logging/MoveLogFormatter.php8
-rw-r--r--includes/logging/NewUsersLogFormatter.php3
-rw-r--r--includes/logging/PageLangLogFormatter.php61
-rw-r--r--includes/logging/PatrolLog.php15
-rw-r--r--includes/logging/PatrolLogFormatter.php2
-rw-r--r--includes/logging/RightsLogFormatter.php1
-rw-r--r--includes/mail/EmailNotification.php512
-rw-r--r--includes/mail/MailAddress.php91
-rw-r--r--includes/mail/UserMailer.php425
-rw-r--r--includes/media/BMP.php14
-rw-r--r--includes/media/Bitmap.php488
-rw-r--r--includes/media/BitmapMetadataHandler.php58
-rw-r--r--includes/media/Bitmap_ClientOnly.php15
-rw-r--r--includes/media/DjVu.php140
-rw-r--r--includes/media/DjVuImage.php82
-rw-r--r--includes/media/Exif.php511
-rw-r--r--includes/media/ExifBitmap.php74
-rw-r--r--includes/media/FormatMetadata.php2061
-rw-r--r--includes/media/GIF.php48
-rw-r--r--includes/media/GIFMetadataExtractor.php51
-rw-r--r--includes/media/IPTC.php47
-rw-r--r--includes/media/ImageHandler.php72
-rw-r--r--includes/media/Jpeg.php94
-rw-r--r--includes/media/JpegMetadataExtractor.php24
-rw-r--r--includes/media/MediaHandler.php415
-rw-r--r--includes/media/MediaTransformOutput.php98
-rw-r--r--includes/media/PNG.php50
-rw-r--r--includes/media/PNGMetadataExtractor.php92
-rw-r--r--includes/media/SVG.php202
-rw-r--r--includes/media/SVGMetadataExtractor.php92
-rw-r--r--includes/media/Tiff.php24
-rw-r--r--includes/media/TransformationalImageHandler.php593
-rw-r--r--includes/media/XCF.php141
-rw-r--r--includes/media/XMP.php213
-rw-r--r--includes/media/XMPInfo.php992
-rw-r--r--includes/media/XMPValidate.php82
-rw-r--r--includes/mime.info14
-rw-r--r--includes/mime.types8
-rw-r--r--includes/normal/Makefile5
-rw-r--r--includes/normal/RandomTest.php20
-rw-r--r--includes/normal/Utf8Case.php2109
-rw-r--r--includes/normal/Utf8CaseGenerate.php112
-rw-r--r--includes/normal/Utf8Test.php47
-rw-r--r--includes/normal/UtfNormal.php291
-rw-r--r--includes/normal/UtfNormalBench.php39
-rw-r--r--includes/normal/UtfNormalData.inc3
-rw-r--r--includes/normal/UtfNormalDataK.inc1
-rw-r--r--includes/normal/UtfNormalDefines.php1
-rw-r--r--includes/normal/UtfNormalGenerate.php103
-rw-r--r--includes/normal/UtfNormalMemStress.php49
-rw-r--r--includes/normal/UtfNormalTest.php70
-rw-r--r--includes/normal/UtfNormalTest2.php304
-rw-r--r--includes/normal/UtfNormalUtil.php42
-rw-r--r--includes/objectcache/APCBagOStuff.php30
-rw-r--r--includes/objectcache/BagOStuff.php180
-rw-r--r--includes/objectcache/DBABagOStuff.php307
-rw-r--r--includes/objectcache/EhcacheBagOStuff.php324
-rw-r--r--includes/objectcache/EmptyBagOStuff.php37
-rw-r--r--includes/objectcache/HashBagOStuff.php31
-rw-r--r--includes/objectcache/MemcachedBagOStuff.php58
-rw-r--r--includes/objectcache/MemcachedClient.php274
-rw-r--r--includes/objectcache/MemcachedPeclBagOStuff.php87
-rw-r--r--includes/objectcache/MemcachedPhpBagOStuff.php28
-rw-r--r--includes/objectcache/MultiWriteBagOStuff.php83
-rw-r--r--includes/objectcache/ObjectCache.php28
-rw-r--r--includes/objectcache/ObjectCacheSessionHandler.php31
-rw-r--r--includes/objectcache/RedisBagOStuff.php215
-rw-r--r--includes/objectcache/SqlBagOStuff.php222
-rw-r--r--includes/objectcache/WinCacheBagOStuff.php22
-rw-r--r--includes/objectcache/XCacheBagOStuff.php30
-rw-r--r--includes/page/Article.php (renamed from includes/Article.php)786
-rw-r--r--includes/page/CategoryPage.php (renamed from includes/CategoryPage.php)4
-rw-r--r--includes/page/ImagePage.php (renamed from includes/ImagePage.php)409
-rw-r--r--includes/page/WikiCategoryPage.php (renamed from includes/WikiCategoryPage.php)0
-rw-r--r--includes/page/WikiFilePage.php (renamed from includes/WikiFilePage.php)58
-rw-r--r--includes/page/WikiPage.php (renamed from includes/WikiPage.php)1315
-rw-r--r--includes/pager/AlphabeticPager.php108
-rw-r--r--includes/pager/IndexPager.php (renamed from includes/Pager.php)715
-rw-r--r--includes/pager/Pager.php35
-rw-r--r--includes/pager/ReverseChronologicalPager.php118
-rw-r--r--includes/pager/TablePager.php469
-rw-r--r--includes/parser/CacheTime.php98
-rw-r--r--includes/parser/CoreParserFunctions.php710
-rw-r--r--includes/parser/CoreTagHooks.php26
-rw-r--r--includes/parser/DateFormatter.php51
-rw-r--r--includes/parser/LinkHolderArray.php243
-rw-r--r--includes/parser/MWTidy.php (renamed from includes/parser/Tidy.php)37
-rw-r--r--includes/parser/Parser.php1364
-rw-r--r--includes/parser/ParserCache.php108
-rw-r--r--includes/parser/ParserDiffTest.php (renamed from includes/parser/Parser_DiffTest.php)26
-rw-r--r--includes/parser/ParserOptions.php517
-rw-r--r--includes/parser/ParserOutput.php449
-rw-r--r--includes/parser/Preprocessor.php176
-rw-r--r--includes/parser/Preprocessor_DOM.php485
-rw-r--r--includes/parser/Preprocessor_Hash.php620
-rw-r--r--includes/parser/StripState.php58
-rw-r--r--includes/password/BcryptPassword.php88
-rw-r--r--includes/password/EncryptedPassword.php98
-rw-r--r--includes/password/InvalidPassword.php47
-rw-r--r--includes/password/LayeredParameterizedPassword.php140
-rw-r--r--includes/password/MWOldPassword.php48
-rw-r--r--includes/password/MWSaltedPassword.php46
-rw-r--r--includes/password/ParameterizedPassword.php119
-rw-r--r--includes/password/Password.php186
-rw-r--r--includes/password/PasswordError.php28
-rw-r--r--includes/password/PasswordFactory.php178
-rw-r--r--includes/password/Pbkdf2Password.php85
-rw-r--r--includes/poolcounter/PoolCounter.php173
-rw-r--r--includes/poolcounter/PoolCounterRedis.php417
-rw-r--r--includes/poolcounter/PoolCounterWork.php160
-rw-r--r--includes/poolcounter/PoolCounterWorkViaCallback.php92
-rw-r--r--includes/poolcounter/PoolWorkArticleView.php208
-rw-r--r--includes/profiler/Profiler.php637
-rw-r--r--includes/profiler/ProfilerMwprof.php256
-rw-r--r--includes/profiler/ProfilerSimple.php133
-rw-r--r--includes/profiler/ProfilerSimpleDB.php111
-rw-r--r--includes/profiler/ProfilerSimpleText.php6
-rw-r--r--includes/profiler/ProfilerSimpleTrace.php59
-rw-r--r--includes/profiler/ProfilerSimpleUDP.php17
-rw-r--r--includes/profiler/ProfilerStandard.php559
-rw-r--r--includes/profiler/ProfilerStub.php38
-rw-r--r--includes/rcfeed/IRCColourfulRCFeedFormatter.php49
-rw-r--r--includes/rcfeed/JSONRCFeedFormatter.php112
-rw-r--r--includes/rcfeed/MachineReadableRCFeedFormatter.php130
-rw-r--r--includes/rcfeed/RCFeedEngine.php33
-rw-r--r--includes/rcfeed/RCFeedFormatter.php27
-rw-r--r--includes/rcfeed/RedisPubSubFeedEngine.php62
-rw-r--r--includes/rcfeed/UDPRCFeedEngine.php26
-rw-r--r--includes/rcfeed/XMLRCFeedFormatter.php29
-rw-r--r--includes/resourceloader/DerivativeResourceLoaderContext.php202
-rw-r--r--includes/resourceloader/ResourceLoader.php670
-rw-r--r--includes/resourceloader/ResourceLoaderContext.php49
-rw-r--r--includes/resourceloader/ResourceLoaderEditToolbarModule.php102
-rw-r--r--includes/resourceloader/ResourceLoaderFileModule.php473
-rw-r--r--includes/resourceloader/ResourceLoaderFilePageModule.php2
-rw-r--r--includes/resourceloader/ResourceLoaderFilePath.php74
-rw-r--r--includes/resourceloader/ResourceLoaderLESSFunctions.php67
-rw-r--r--includes/resourceloader/ResourceLoaderLanguageDataModule.php84
-rw-r--r--includes/resourceloader/ResourceLoaderLanguageNamesModule.php79
-rw-r--r--includes/resourceloader/ResourceLoaderModule.php221
-rw-r--r--includes/resourceloader/ResourceLoaderNoscriptModule.php6
-rw-r--r--includes/resourceloader/ResourceLoaderSiteModule.php12
-rw-r--r--includes/resourceloader/ResourceLoaderStartUpModule.php412
-rw-r--r--includes/resourceloader/ResourceLoaderUserCSSPrefsModule.php31
-rw-r--r--includes/resourceloader/ResourceLoaderUserGroupsModule.php21
-rw-r--r--includes/resourceloader/ResourceLoaderUserModule.php18
-rw-r--r--includes/resourceloader/ResourceLoaderUserOptionsModule.php16
-rw-r--r--includes/resourceloader/ResourceLoaderUserTokensModule.php10
-rw-r--r--includes/resourceloader/ResourceLoaderWikiModule.php110
-rw-r--r--includes/revisiondelete/RevDelArchiveItem.php105
-rw-r--r--includes/revisiondelete/RevDelArchiveList.php66
-rw-r--r--includes/revisiondelete/RevDelArchivedFileItem.php129
-rw-r--r--includes/revisiondelete/RevDelArchivedFileList.php56
-rw-r--r--includes/revisiondelete/RevDelArchivedRevisionItem.php53
-rw-r--r--includes/revisiondelete/RevDelFileItem.php237
-rw-r--r--includes/revisiondelete/RevDelFileList.php128
-rw-r--r--includes/revisiondelete/RevDelItem.php62
-rw-r--r--includes/revisiondelete/RevDelList.php (renamed from includes/revisiondelete/RevisionDeleteAbstracts.php)75
-rw-r--r--includes/revisiondelete/RevDelLogItem.php151
-rw-r--r--includes/revisiondelete/RevDelLogList.php103
-rw-r--r--includes/revisiondelete/RevDelRevisionItem.php187
-rw-r--r--includes/revisiondelete/RevDelRevisionList.php143
-rw-r--r--includes/revisiondelete/RevisionDelete.php964
-rw-r--r--includes/revisiondelete/RevisionDeleteUser.php38
-rw-r--r--includes/revisiondelete/RevisionDeleter.php37
-rw-r--r--includes/search/SearchDatabase.php57
-rw-r--r--includes/search/SearchEngine.php1116
-rw-r--r--includes/search/SearchHighlighter.php575
-rw-r--r--includes/search/SearchMssql.php110
-rw-r--r--includes/search/SearchMySQL.php122
-rw-r--r--includes/search/SearchOracle.php77
-rw-r--r--includes/search/SearchPostgres.php89
-rw-r--r--includes/search/SearchResult.php237
-rw-r--r--includes/search/SearchResultSet.php211
-rw-r--r--includes/search/SearchSqlite.php116
-rw-r--r--includes/site/MediaWikiSite.php44
-rw-r--r--includes/site/Site.php32
-rw-r--r--includes/site/SiteList.php88
-rw-r--r--includes/site/SiteSQLStore.php52
-rw-r--r--includes/site/SiteStore.php8
-rw-r--r--includes/skins/Skin.php (renamed from includes/Skin.php)489
-rw-r--r--includes/skins/SkinException.php29
-rw-r--r--includes/skins/SkinFactory.php214
-rw-r--r--includes/skins/SkinFallback.php36
-rw-r--r--includes/skins/SkinFallbackTemplate.php109
-rw-r--r--includes/skins/SkinTemplate.php (renamed from includes/SkinTemplate.php)511
-rw-r--r--includes/specialpage/ChangesListSpecialPage.php468
-rw-r--r--includes/specialpage/FormSpecialPage.php193
-rw-r--r--includes/specialpage/ImageQueryPage.php (renamed from includes/ImageQueryPage.php)15
-rw-r--r--includes/specialpage/IncludableSpecialPage.php39
-rw-r--r--includes/specialpage/PageQueryPage.php (renamed from includes/PageQueryPage.php)24
-rw-r--r--includes/specialpage/QueryPage.php (renamed from includes/QueryPage.php)318
-rw-r--r--includes/specialpage/RedirectSpecialPage.php209
-rw-r--r--includes/specialpage/SpecialPage.php663
-rw-r--r--includes/specialpage/SpecialPageFactory.php702
-rw-r--r--includes/specialpage/UnlistedSpecialPage.php37
-rw-r--r--includes/specialpage/WantedQueryPage.php130
-rw-r--r--includes/specials/SpecialActiveusers.php237
-rw-r--r--includes/specials/SpecialAllMessages.php (renamed from includes/specials/SpecialAllmessages.php)105
-rw-r--r--includes/specials/SpecialAllPages.php384
-rw-r--r--includes/specials/SpecialAllpages.php573
-rw-r--r--includes/specials/SpecialBlock.php141
-rw-r--r--includes/specials/SpecialBlockList.php65
-rw-r--r--includes/specials/SpecialBooksources.php30
-rw-r--r--includes/specials/SpecialBrokenRedirects.php4
-rw-r--r--includes/specials/SpecialCachedPage.php24
-rw-r--r--includes/specials/SpecialCategories.php72
-rw-r--r--includes/specials/SpecialChangeEmail.php255
-rw-r--r--includes/specials/SpecialChangePassword.php385
-rw-r--r--includes/specials/SpecialComparePages.php4
-rw-r--r--includes/specials/SpecialConfirmemail.php44
-rw-r--r--includes/specials/SpecialContributions.php254
-rw-r--r--includes/specials/SpecialCreateAccount.php56
-rw-r--r--includes/specials/SpecialDeletedContributions.php42
-rw-r--r--includes/specials/SpecialDiff.php61
-rw-r--r--includes/specials/SpecialEditWatchlist.php222
-rw-r--r--includes/specials/SpecialEmailuser.php60
-rw-r--r--includes/specials/SpecialExpandTemplates.php286
-rw-r--r--includes/specials/SpecialExport.php87
-rw-r--r--includes/specials/SpecialFewestrevisions.php2
-rw-r--r--includes/specials/SpecialFileDuplicateSearch.php12
-rw-r--r--includes/specials/SpecialFilepath.php8
-rw-r--r--includes/specials/SpecialImport.php164
-rw-r--r--includes/specials/SpecialJavaScriptTest.php33
-rw-r--r--includes/specials/SpecialLinkSearch.php114
-rw-r--r--includes/specials/SpecialListDuplicatedFiles.php113
-rw-r--r--includes/specials/SpecialListfiles.php223
-rw-r--r--includes/specials/SpecialListgrouprights.php200
-rw-r--r--includes/specials/SpecialListredirects.php11
-rw-r--r--includes/specials/SpecialListusers.php65
-rw-r--r--includes/specials/SpecialLockdb.php10
-rw-r--r--includes/specials/SpecialLog.php33
-rw-r--r--includes/specials/SpecialLonelypages.php52
-rw-r--r--includes/specials/SpecialMIMEsearch.php58
-rw-r--r--includes/specials/SpecialMediaStatistics.php325
-rw-r--r--includes/specials/SpecialMergeHistory.php105
-rw-r--r--includes/specials/SpecialMostinterwikis.php4
-rw-r--r--includes/specials/SpecialMostlinked.php6
-rw-r--r--includes/specials/SpecialMostlinkedcategories.php1
-rw-r--r--includes/specials/SpecialMostlinkedtemplates.php11
-rw-r--r--includes/specials/SpecialMostrevisions.php1
-rw-r--r--includes/specials/SpecialMovepage.php98
-rw-r--r--includes/specials/SpecialMyLanguage.php93
-rw-r--r--includes/specials/SpecialMyRedirectPages.php114
-rw-r--r--includes/specials/SpecialNewimages.php37
-rw-r--r--includes/specials/SpecialNewpages.php68
-rw-r--r--includes/specials/SpecialPageLanguage.php195
-rw-r--r--includes/specials/SpecialPagesWithProp.php45
-rw-r--r--includes/specials/SpecialPasswordReset.php43
-rw-r--r--includes/specials/SpecialPermanentLink.php45
-rw-r--r--includes/specials/SpecialPreferences.php16
-rw-r--r--includes/specials/SpecialPrefixindex.php46
-rw-r--r--includes/specials/SpecialProtectedpages.php406
-rw-r--r--includes/specials/SpecialProtectedtitles.php17
-rw-r--r--includes/specials/SpecialRandomInCategory.php77
-rw-r--r--includes/specials/SpecialRandompage.php9
-rw-r--r--includes/specials/SpecialRecentchanges.php562
-rw-r--r--includes/specials/SpecialRecentchangeslinked.php61
-rw-r--r--includes/specials/SpecialRedirect.php72
-rw-r--r--includes/specials/SpecialResetTokens.php12
-rw-r--r--includes/specials/SpecialRevisiondelete.php286
-rw-r--r--includes/specials/SpecialRunJobs.php112
-rw-r--r--includes/specials/SpecialSearch.php661
-rw-r--r--includes/specials/SpecialShortpages.php21
-rw-r--r--includes/specials/SpecialSpecialpages.php27
-rw-r--r--includes/specials/SpecialStatistics.php168
-rw-r--r--includes/specials/SpecialTags.php10
-rw-r--r--includes/specials/SpecialTrackingCategories.php148
-rw-r--r--includes/specials/SpecialUnblock.php38
-rw-r--r--includes/specials/SpecialUncategorizedimages.php13
-rw-r--r--includes/specials/SpecialUncategorizedpages.php26
-rw-r--r--includes/specials/SpecialUndelete.php393
-rw-r--r--includes/specials/SpecialUnlockdb.php11
-rw-r--r--includes/specials/SpecialUnusedcategories.php27
-rw-r--r--includes/specials/SpecialUnusedimages.php25
-rw-r--r--includes/specials/SpecialUnusedtemplates.php18
-rw-r--r--includes/specials/SpecialUnwatchedpages.php28
-rw-r--r--includes/specials/SpecialUpload.php254
-rw-r--r--includes/specials/SpecialUploadStash.php121
-rw-r--r--includes/specials/SpecialUserlogin.php455
-rw-r--r--includes/specials/SpecialUserlogout.php1
-rw-r--r--includes/specials/SpecialUserrights.php165
-rw-r--r--includes/specials/SpecialVersion.php738
-rw-r--r--includes/specials/SpecialWantedcategories.php68
-rw-r--r--includes/specials/SpecialWantedfiles.php77
-rw-r--r--includes/specials/SpecialWantedpages.php7
-rw-r--r--includes/specials/SpecialWantedtemplates.php22
-rw-r--r--includes/specials/SpecialWatchlist.php652
-rw-r--r--includes/specials/SpecialWhatlinkshere.php216
-rw-r--r--includes/specials/SpecialWithoutinterwiki.php34
-rw-r--r--includes/templates/NoLocalSettings.php32
-rw-r--r--includes/templates/Usercreate.php80
-rw-r--r--includes/templates/Userlogin.php45
-rw-r--r--includes/title/MalformedTitleException.php32
-rw-r--r--includes/title/MediaWikiPageLinkRenderer.php131
-rw-r--r--includes/title/MediaWikiTitleCodec.php400
-rw-r--r--includes/title/PageLinkRenderer.php67
-rw-r--r--includes/title/TitleFormatter.php90
-rw-r--r--includes/title/TitleParser.php47
-rw-r--r--includes/title/TitleValue.php161
-rw-r--r--includes/upload/UploadBase.php462
-rw-r--r--includes/upload/UploadFromChunks.php110
-rw-r--r--includes/upload/UploadFromFile.php9
-rw-r--r--includes/upload/UploadFromStash.php46
-rw-r--r--includes/upload/UploadFromUrl.php72
-rw-r--r--includes/upload/UploadStash.php286
-rw-r--r--includes/utils/ArrayUtils.php187
-rw-r--r--includes/utils/Cdb.php (renamed from includes/Cdb.php)133
-rw-r--r--includes/utils/CdbDBA.php75
-rw-r--r--includes/utils/CdbPHP.php (renamed from includes/Cdb_PHP.php)141
-rw-r--r--includes/utils/IP.php (renamed from includes/IP.php)297
-rw-r--r--includes/utils/MWCryptHKDF.php332
-rw-r--r--includes/utils/MWCryptRand.php (renamed from includes/MWCryptRand.php)83
-rw-r--r--includes/utils/MWFunction.php (renamed from includes/MWFunction.php)14
-rw-r--r--includes/utils/README9
-rw-r--r--includes/utils/StringUtils.php (renamed from includes/StringUtils.php)84
-rw-r--r--includes/utils/UIDGenerator.php (renamed from includes/UIDGenerator.php)208
-rw-r--r--includes/utils/ZipDirectoryReader.php (renamed from includes/ZipDirectoryReader.php)94
1020 files changed, 100653 insertions, 77151 deletions
diff --git a/includes/AjaxDispatcher.php b/includes/AjaxDispatcher.php
index c9ca1283..9bc92be9 100644
--- a/includes/AjaxDispatcher.php
+++ b/includes/AjaxDispatcher.php
@@ -48,14 +48,21 @@ class AjaxDispatcher {
private $args;
/**
+ * @var Config
+ */
+ private $config;
+
+ /**
* Load up our object with user supplied data
*/
- function __construct() {
+ function __construct( Config $config ) {
wfProfileIn( __METHOD__ );
+ $this->config = $config;
+
$this->mode = "";
- if ( ! empty( $_GET["rs"] ) ) {
+ if ( !empty( $_GET["rs"] ) ) {
$this->mode = "get";
}
@@ -66,7 +73,7 @@ class AjaxDispatcher {
switch ( $this->mode ) {
case 'get':
$this->func_name = isset( $_GET["rs"] ) ? $_GET["rs"] : '';
- if ( ! empty( $_GET["rsargs"] ) ) {
+ if ( !empty( $_GET["rsargs"] ) ) {
$this->args = $_GET["rsargs"];
} else {
$this->args = array();
@@ -74,7 +81,7 @@ class AjaxDispatcher {
break;
case 'post':
$this->func_name = isset( $_POST["rs"] ) ? $_POST["rs"] : '';
- if ( ! empty( $_POST["rsargs"] ) ) {
+ if ( !empty( $_POST["rsargs"] ) ) {
$this->args = $_POST["rsargs"];
} else {
$this->args = array();
@@ -95,17 +102,17 @@ class AjaxDispatcher {
* BEWARE! Data are passed as they have been supplied by the user,
* they should be carefully handled in the function processing the
* request.
+ *
+ * @param User $user
*/
- function performAction() {
- global $wgAjaxExportList, $wgUser;
-
+ function performAction( User $user ) {
if ( empty( $this->mode ) ) {
return;
}
wfProfileIn( __METHOD__ );
- if ( ! in_array( $this->func_name, $wgAjaxExportList ) ) {
+ if ( !in_array( $this->func_name, $this->config->get( 'AjaxExportList' ) ) ) {
wfDebug( __METHOD__ . ' Bad Request for unknown function ' . $this->func_name . "\n" );
wfHttpError(
@@ -113,7 +120,7 @@ class AjaxDispatcher {
'Bad Request',
"unknown function " . $this->func_name
);
- } elseif ( !User::isEveryoneAllowed( 'read' ) && !$wgUser->isAllowed( 'read' ) ) {
+ } elseif ( !User::isEveryoneAllowed( 'read' ) && !$user->isAllowed( 'read' ) ) {
wfHttpError(
403,
'Forbidden',
diff --git a/includes/AjaxResponse.php b/includes/AjaxResponse.php
index d5536529..8e9f490f 100644
--- a/includes/AjaxResponse.php
+++ b/includes/AjaxResponse.php
@@ -28,7 +28,6 @@
* @ingroup Ajax
*/
class AjaxResponse {
-
/**
* Number of seconds to get the response cached by a proxy
* @var int $mCacheDuration
@@ -49,7 +48,7 @@ class AjaxResponse {
/**
* Date for the HTTP header Last-modified
- * @var string|false $mLastModified
+ * @var string|bool $mLastModified
*/
private $mLastModified;
@@ -72,11 +71,18 @@ class AjaxResponse {
private $mText;
/**
- * @param $text string|null
+ * @var Config
*/
- function __construct( $text = null ) {
+ private $mConfig;
+
+ /**
+ * @param string|null $text
+ * @param Config|null $config
+ */
+ function __construct( $text = null, Config $config = null ) {
$this->mCacheDuration = null;
$this->mVary = null;
+ $this->mConfig = $config ?: ConfigFactory::getDefaultInstance()->makeConfig( 'main' );
$this->mDisabled = false;
$this->mText = '';
@@ -91,7 +97,7 @@ class AjaxResponse {
/**
* Set the number of seconds to get the response cached by a proxy
- * @param $duration int
+ * @param int $duration
*/
function setCacheDuration( $duration ) {
$this->mCacheDuration = $duration;
@@ -99,7 +105,7 @@ class AjaxResponse {
/**
* Set the HTTP Vary header
- * @param $vary string
+ * @param string $vary
*/
function setVary( $vary ) {
$this->mVary = $vary;
@@ -107,7 +113,7 @@ class AjaxResponse {
/**
* Set the HTTP response code
- * @param $code string
+ * @param string $code
*/
function setResponseCode( $code ) {
$this->mResponseCode = $code;
@@ -115,7 +121,7 @@ class AjaxResponse {
/**
* Set the HTTP header Content-Type
- * @param $type string
+ * @param string $type
*/
function setContentType( $type ) {
$this->mContentType = $type;
@@ -130,10 +136,10 @@ class AjaxResponse {
/**
* Add content to the response
- * @param $text string
+ * @param string $text
*/
function addText( $text ) {
- if ( ! $this->mDisabled && $text ) {
+ if ( !$this->mDisabled && $text ) {
$this->mText .= $text;
}
}
@@ -142,7 +148,7 @@ class AjaxResponse {
* Output text
*/
function printText() {
- if ( ! $this->mDisabled ) {
+ if ( !$this->mDisabled ) {
print $this->mText;
}
}
@@ -151,8 +157,6 @@ class AjaxResponse {
* Construct the header and output it
*/
function sendHeaders() {
- global $wgUseSquid, $wgUseESI;
-
if ( $this->mResponseCode ) {
$n = preg_replace( '/^ *(\d+)/', '\1', $this->mResponseCode );
header( "Status: " . $this->mResponseCode, true, (int)$n );
@@ -171,12 +175,12 @@ class AjaxResponse {
# and tell the client to always check with the squid. Otherwise,
# tell the client to use a cached copy, without a way to purge it.
- if ( $wgUseSquid ) {
+ if ( $this->mConfig->get( 'UseSquid' ) ) {
# Expect explicit purge of the proxy cache, but require end user agents
# to revalidate against the proxy on each visit.
# Surrogate-Control controls our Squid, Cache-Control downstream caches
- if ( $wgUseESI ) {
+ if ( $this->mConfig->get( 'UseESI' ) ) {
header( 'Surrogate-Control: max-age=' . $this->mCacheDuration . ', content="ESI/1.0"' );
header( 'Cache-Control: s-maxage=0, must-revalidate, max-age=0' );
} else {
@@ -184,10 +188,10 @@ class AjaxResponse {
}
} else {
-
# Let the client do the caching. Cache is not purged.
header ( "Expires: " . gmdate( "D, d M Y H:i:s", time() + $this->mCacheDuration ) . " GMT" );
- header ( "Cache-Control: s-maxage={$this->mCacheDuration},public,max-age={$this->mCacheDuration}" );
+ header ( "Cache-Control: s-maxage={$this->mCacheDuration}," .
+ "public,max-age={$this->mCacheDuration}" );
}
} else {
@@ -207,7 +211,7 @@ class AjaxResponse {
* possible. If successful, the AjaxResponse is disabled so that
* any future call to AjaxResponse::printText() have no effect.
*
- * @param $timestamp string
+ * @param string $timestamp
* @return bool Returns true if the response code was set to 304 Not Modified.
*/
function checkLastModified( $timestamp ) {
@@ -215,17 +219,12 @@ class AjaxResponse {
$fname = 'AjaxResponse::checkLastModified';
if ( !$timestamp || $timestamp == '19700101000000' ) {
- wfDebug( "$fname: CACHE DISABLED, NO TIMESTAMP\n" );
+ wfDebug( "$fname: CACHE DISABLED, NO TIMESTAMP\n", 'log' );
return false;
}
if ( !$wgCachePages ) {
- wfDebug( "$fname: CACHE DISABLED\n", false );
- return false;
- }
-
- if ( $wgUser->getOption( 'nocache' ) ) {
- wfDebug( "$fname: USER DISABLED CACHE\n", false );
+ wfDebug( "$fname: CACHE DISABLED\n", 'log' );
return false;
}
@@ -239,32 +238,37 @@ class AjaxResponse {
$modsince = preg_replace( '/;.*$/', '', $_SERVER["HTTP_IF_MODIFIED_SINCE"] );
$modsinceTime = strtotime( $modsince );
$ismodsince = wfTimestamp( TS_MW, $modsinceTime ? $modsinceTime : 1 );
- wfDebug( "$fname: -- client send If-Modified-Since: " . $modsince . "\n", false );
- wfDebug( "$fname: -- we might send Last-Modified : $lastmod\n", false );
+ wfDebug( "$fname: -- client send If-Modified-Since: " . $modsince . "\n", 'log' );
+ wfDebug( "$fname: -- we might send Last-Modified : $lastmod\n", 'log' );
- if ( ( $ismodsince >= $timestamp ) && $wgUser->validateCache( $ismodsince ) && $ismodsince >= $wgCacheEpoch ) {
+ if ( ( $ismodsince >= $timestamp )
+ && $wgUser->validateCache( $ismodsince ) &&
+ $ismodsince >= $wgCacheEpoch
+ ) {
ini_set( 'zlib.output_compression', 0 );
$this->setResponseCode( "304 Not Modified" );
$this->disable();
$this->mLastModified = $lastmod;
- wfDebug( "$fname: CACHED client: $ismodsince ; user: {$wgUser->getTouched()} ; page: $timestamp ; site $wgCacheEpoch\n", false );
+ wfDebug( "$fname: CACHED client: $ismodsince ; user: {$wgUser->getTouched()} ; " .
+ "page: $timestamp ; site $wgCacheEpoch\n", 'log' );
return true;
} else {
- wfDebug( "$fname: READY client: $ismodsince ; user: {$wgUser->getTouched()} ; page: $timestamp ; site $wgCacheEpoch\n", false );
+ wfDebug( "$fname: READY client: $ismodsince ; user: {$wgUser->getTouched()} ; " .
+ "page: $timestamp ; site $wgCacheEpoch\n", 'log' );
$this->mLastModified = $lastmod;
}
} else {
- wfDebug( "$fname: client did not send If-Modified-Since header\n", false );
+ wfDebug( "$fname: client did not send If-Modified-Since header\n", 'log' );
$this->mLastModified = $lastmod;
}
return false;
}
/**
- * @param $mckey string
- * @param $touched int
+ * @param string $mckey
+ * @param int $touched
* @return bool
*/
function loadFromMemcached( $mckey, $touched ) {
@@ -291,8 +295,8 @@ class AjaxResponse {
}
/**
- * @param $mckey string
- * @param $expiry int
+ * @param string $mckey
+ * @param int $expiry
* @return bool
*/
function storeInMemcached( $mckey, $expiry = 86400 ) {
diff --git a/includes/ArrayUtils.php b/includes/ArrayUtils.php
deleted file mode 100644
index 985271f7..00000000
--- a/includes/ArrayUtils.php
+++ /dev/null
@@ -1,69 +0,0 @@
-<?php
-
-class ArrayUtils {
- /**
- * Sort the given array in a pseudo-random order which depends only on the
- * given key and each element value. This is typically used for load
- * balancing between servers each with a local cache.
- *
- * Keys are preserved. The input array is modified in place.
- *
- * Note: Benchmarking on PHP 5.3 and 5.4 indicates that for small
- * strings, md5() is only 10% slower than hash('joaat',...) etc.,
- * since the function call overhead dominates. So there's not much
- * justification for breaking compatibility with installations
- * compiled with ./configure --disable-hash.
- *
- * @param $array The array to sort
- * @param $key The string key
- * @param $separator A separator used to delimit the array elements and the
- * key. This can be chosen to provide backwards compatibility with
- * various consistent hash implementations that existed before this
- * function was introduced.
- */
- public static function consistentHashSort( &$array, $key, $separator = "\000" ) {
- $hashes = array();
- foreach ( $array as $elt ) {
- $hashes[$elt] = md5( $elt . $separator . $key );
- }
- uasort( $array, function ( $a, $b ) use ( $hashes ) {
- return strcmp( $hashes[$a], $hashes[$b] );
- } );
- }
-
- /**
- * Given an array of non-normalised probabilities, this function will select
- * an element and return the appropriate key
- *
- * @param $weights array
- *
- * @return bool|int|string
- */
- public static function pickRandom( $weights ) {
- if ( !is_array( $weights ) || count( $weights ) == 0 ) {
- return false;
- }
-
- $sum = array_sum( $weights );
- if ( $sum == 0 ) {
- # No loads on any of them
- # In previous versions, this triggered an unweighted random selection,
- # but this feature has been removed as of April 2006 to allow for strict
- # separation of query groups.
- return false;
- }
- $max = mt_getrandmax();
- $rand = mt_rand( 0, $max ) / $max * $sum;
-
- $sum = 0;
- foreach ( $weights as $i => $w ) {
- $sum += $w;
- # Do not return keys if they have 0 weight.
- # Note that the "all 0 weight" case is handed above
- if ( $w > 0 && $sum >= $rand ) {
- break;
- }
- }
- return $i;
- }
-}
diff --git a/includes/AuthPlugin.php b/includes/AuthPlugin.php
index 84cf3d5e..45ad4d1b 100644
--- a/includes/AuthPlugin.php
+++ b/includes/AuthPlugin.php
@@ -3,7 +3,7 @@
* Authentication plugin interface
*
* Copyright © 2004 Brion Vibber <brion@pobox.com>
- * http://www.mediawiki.org/
+ * https://www.mediawiki.org/
*
* 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
@@ -34,7 +34,6 @@
* someone logs in who can be authenticated externally.
*/
class AuthPlugin {
-
/**
* @var string
*/
@@ -46,7 +45,7 @@ class AuthPlugin {
* you might need to munge it (for instance, for lowercase initial
* letters).
*
- * @param string $username username.
+ * @param string $username Username.
* @return bool
*/
public function userExists( $username ) {
@@ -60,8 +59,8 @@ class AuthPlugin {
* you might need to munge it (for instance, for lowercase initial
* letters).
*
- * @param string $username username.
- * @param string $password user password.
+ * @param string $username Username.
+ * @param string $password User password.
* @return bool
*/
public function authenticate( $username, $password ) {
@@ -72,7 +71,7 @@ class AuthPlugin {
/**
* Modify options in the login template.
*
- * @param $template UserLoginTemplate object.
+ * @param UserLoginTemplate $template
* @param string $type 'signup' or 'login'. Added in 1.16.
*/
public function modifyUITemplate( &$template, &$type ) {
@@ -83,7 +82,7 @@ class AuthPlugin {
/**
* Set the domain this plugin is supposed to use when authenticating.
*
- * @param string $domain authentication domain.
+ * @param string $domain Authentication domain.
*/
public function setDomain( $domain ) {
$this->domain = $domain;
@@ -105,7 +104,7 @@ class AuthPlugin {
/**
* Check to see if the specific domain is a valid domain.
*
- * @param string $domain authentication domain.
+ * @param string $domain Authentication domain.
* @return bool
*/
public function validDomain( $domain ) {
@@ -121,7 +120,7 @@ class AuthPlugin {
* The User object is passed by reference so it can be modified; don't
* forget the & on your function declaration.
*
- * @param $user User object
+ * @param User $user
* @return bool
*/
public function updateUser( &$user ) {
@@ -140,7 +139,7 @@ class AuthPlugin {
*
* This is just a question, and shouldn't perform any actions.
*
- * @return Boolean
+ * @return bool
*/
public function autoCreate() {
return false;
@@ -151,9 +150,9 @@ class AuthPlugin {
* and use the same keys. 'Realname' 'Emailaddress' and 'Nickname'
* all reference this.
*
- * @param $prop string
+ * @param string $prop
*
- * @return Boolean
+ * @return bool
*/
public function allowPropChange( $prop = '' ) {
if ( $prop == 'realname' && is_callable( array( $this, 'allowRealNameChange' ) ) ) {
@@ -193,8 +192,8 @@ class AuthPlugin {
*
* Return true if successful.
*
- * @param $user User object.
- * @param string $password password.
+ * @param User $user
+ * @param string $password Password.
* @return bool
*/
public function setPassword( $user, $password ) {
@@ -205,8 +204,8 @@ class AuthPlugin {
* Update user information in the external authentication database.
* Return true if successful.
*
- * @param $user User object.
- * @return Boolean
+ * @param User $user
+ * @return bool
*/
public function updateExternalDB( $user ) {
return true;
@@ -216,10 +215,10 @@ class AuthPlugin {
* Update user groups in the external authentication database.
* Return true if successful.
*
- * @param $user User object.
- * @param $addgroups Groups to add.
- * @param $delgroups Groups to remove.
- * @return Boolean
+ * @param User $user
+ * @param array $addgroups Groups to add.
+ * @param array $delgroups Groups to remove.
+ * @return bool
*/
public function updateExternalDBGroups( $user, $addgroups, $delgroups = array() ) {
return true;
@@ -228,7 +227,7 @@ class AuthPlugin {
/**
* Check to see if external accounts can be created.
* Return true if external accounts can be created.
- * @return Boolean
+ * @return bool
*/
public function canCreateAccounts() {
return false;
@@ -238,11 +237,11 @@ class AuthPlugin {
* Add a user to the external authentication database.
* Return true if successful.
*
- * @param $user User: only the name should be assumed valid at this point
- * @param $password String
- * @param $email String
- * @param $realname String
- * @return Boolean
+ * @param User $user Only the name should be assumed valid at this point
+ * @param string $password
+ * @param string $email
+ * @param string $realname
+ * @return bool
*/
public function addUser( $user, $password, $email = '', $realname = '' ) {
return true;
@@ -254,7 +253,7 @@ class AuthPlugin {
*
* This is just a question, and shouldn't perform any actions.
*
- * @return Boolean
+ * @return bool
*/
public function strict() {
return false;
@@ -264,8 +263,8 @@ class AuthPlugin {
* Check if a user should authenticate locally if the global authentication fails.
* If either this or strict() returns true, local authentication is not used.
*
- * @param string $username username.
- * @return Boolean
+ * @param string $username Username.
+ * @return bool
*/
public function strictUserAuth( $username ) {
return false;
@@ -279,8 +278,8 @@ class AuthPlugin {
* The User object is passed by reference so it can be modified; don't
* forget the & on your function declaration.
*
- * @param $user User object.
- * @param $autocreate Boolean: True if user is being autocreated on login
+ * @param User $user
+ * @param bool $autocreate True if user is being autocreated on login
*/
public function initUser( &$user, $autocreate = false ) {
# Override this to do something.
@@ -289,7 +288,7 @@ class AuthPlugin {
/**
* If you want to munge the case of an account name before the final
* check, now is your chance.
- * @param $username string
+ * @param string $username
* @return string
*/
public function getCanonicalName( $username ) {
@@ -299,7 +298,7 @@ class AuthPlugin {
/**
* Get an instance of a User object
*
- * @param $user User
+ * @param User $user
*
* @return AuthPluginUser
*/
diff --git a/includes/AutoLoader.php b/includes/AutoLoader.php
index 0706fe3f..6b0daa14 100644
--- a/includes/AutoLoader.php
+++ b/includes/AutoLoader.php
@@ -29,49 +29,32 @@ global $wgAutoloadLocalClasses;
$wgAutoloadLocalClasses = array(
# Includes
- 'Action' => 'includes/Action.php',
'AjaxDispatcher' => 'includes/AjaxDispatcher.php',
'AjaxResponse' => 'includes/AjaxResponse.php',
- 'AlphabeticPager' => 'includes/Pager.php',
- 'ArrayUtils' => 'includes/ArrayUtils.php',
- 'Article' => 'includes/Article.php',
'AtomFeed' => 'includes/Feed.php',
'AuthPlugin' => 'includes/AuthPlugin.php',
'AuthPluginUser' => 'includes/AuthPlugin.php',
'Autopromote' => 'includes/Autopromote.php',
- 'BadTitleError' => 'includes/Exception.php',
- 'BaseTemplate' => 'includes/SkinTemplate.php',
'Block' => 'includes/Block.php',
+ 'BloomCache' => 'includes/cache/bloom/BloomCache.php',
+ 'BloomCacheRedis' => 'includes/cache/bloom/BloomCacheRedis.php',
+ 'BloomFilterTitleHasLogs' => 'includes/cache/bloom/BloomFilters.php',
'CacheHelper' => 'includes/CacheHelper.php',
'Category' => 'includes/Category.php',
- 'Categoryfinder' => 'includes/Categoryfinder.php',
- 'CategoryPage' => 'includes/CategoryPage.php',
+ 'CategoryFinder' => 'includes/CategoryFinder.php',
'CategoryViewer' => 'includes/CategoryViewer.php',
- 'CdbFunctions' => 'includes/Cdb_PHP.php',
- 'CdbReader' => 'includes/Cdb.php',
- 'CdbReader_DBA' => 'includes/Cdb.php',
- 'CdbReader_PHP' => 'includes/Cdb_PHP.php',
- 'CdbWriter' => 'includes/Cdb.php',
- 'CdbWriter_DBA' => 'includes/Cdb.php',
- 'CdbWriter_PHP' => 'includes/Cdb_PHP.php',
- 'ChangesFeed' => 'includes/ChangesFeed.php',
'ChangeTags' => 'includes/ChangeTags.php',
'ChannelFeed' => 'includes/Feed.php',
'Collation' => 'includes/Collation.php',
+ 'CollationCkb' => 'includes/Collation.php',
+ 'CollationEt' => 'includes/Collation.php',
'ConcatenatedGzipHistoryBlob' => 'includes/HistoryBlob.php',
- 'ConfEditor' => 'includes/ConfEditor.php',
- 'ConfEditorParseError' => 'includes/ConfEditor.php',
- 'ConfEditorToken' => 'includes/ConfEditor.php',
'Cookie' => 'includes/Cookie.php',
'CookieJar' => 'includes/Cookie.php',
'CurlHttpRequest' => 'includes/HttpFunctions.php',
- 'DeferrableUpdate' => 'includes/DeferredUpdates.php',
- 'DeferredUpdates' => 'includes/DeferredUpdates.php',
- 'MWCallableUpdate' => 'includes/CallableUpdate.php',
'DeprecatedGlobal' => 'includes/DeprecatedGlobal.php',
'DerivativeRequest' => 'includes/WebRequest.php',
'DiffHistoryBlob' => 'includes/HistoryBlob.php',
- 'DoubleReplacer' => 'includes/StringUtils.php',
'DummyLinker' => 'includes/Linker.php',
'Dump7ZipOutput' => 'includes/Export.php',
'DumpBZip2Output' => 'includes/Export.php',
@@ -85,126 +68,83 @@ $wgAutoloadLocalClasses = array(
'DumpOutput' => 'includes/Export.php',
'DumpPipeOutput' => 'includes/Export.php',
'EditPage' => 'includes/EditPage.php',
- 'EmailNotification' => 'includes/UserMailer.php',
- 'ErrorPageError' => 'includes/Exception.php',
- 'ExplodeIterator' => 'includes/StringUtils.php',
- 'FakeTitle' => 'includes/FakeTitle.php',
+ 'EmptyBloomCache' => 'includes/cache/bloom/BloomCache.php',
'Fallback' => 'includes/Fallback.php',
- 'FatalError' => 'includes/Exception.php',
'FauxRequest' => 'includes/WebRequest.php',
'FauxResponse' => 'includes/WebResponse.php',
'FeedItem' => 'includes/Feed.php',
'FeedUtils' => 'includes/FeedUtils.php',
'FileDeleteForm' => 'includes/FileDeleteForm.php',
'ForkController' => 'includes/ForkController.php',
- 'FormlessAction' => 'includes/Action.php',
- 'FormAction' => 'includes/Action.php',
'FormOptions' => 'includes/FormOptions.php',
- 'FormSpecialPage' => 'includes/SpecialPage.php',
'GitInfo' => 'includes/GitInfo.php',
- 'HashRing' => 'includes/HashRing.php',
- 'HashtableReplacer' => 'includes/StringUtils.php',
'HistoryBlob' => 'includes/HistoryBlob.php',
'HistoryBlobCurStub' => 'includes/HistoryBlob.php',
'HistoryBlobStub' => 'includes/HistoryBlob.php',
'Hooks' => 'includes/Hooks.php',
'Html' => 'includes/Html.php',
'HtmlFormatter' => 'includes/HtmlFormatter.php',
- 'HTMLApiField' => 'includes/HTMLForm.php',
- 'HTMLButtonField' => 'includes/HTMLForm.php',
- 'HTMLCheckField' => 'includes/HTMLForm.php',
- 'HTMLCheckMatrix' => 'includes/HTMLForm.php',
- 'HTMLEditTools' => 'includes/HTMLForm.php',
- 'HTMLFloatField' => 'includes/HTMLForm.php',
- 'HTMLForm' => 'includes/HTMLForm.php',
- 'HTMLFormField' => 'includes/HTMLForm.php',
- 'HTMLFormFieldRequiredOptionsException' => 'includes/HTMLForm.php',
- 'HTMLHiddenField' => 'includes/HTMLForm.php',
- 'HTMLInfoField' => 'includes/HTMLForm.php',
- 'HTMLIntField' => 'includes/HTMLForm.php',
- 'HTMLNestedFilterable' => 'includes/HTMLForm.php',
- 'HTMLMultiSelectField' => 'includes/HTMLForm.php',
- 'HTMLRadioField' => 'includes/HTMLForm.php',
- 'HTMLSelectAndOtherField' => 'includes/HTMLForm.php',
- 'HTMLSelectField' => 'includes/HTMLForm.php',
- 'HTMLSelectOrOtherField' => 'includes/HTMLForm.php',
- 'HTMLSubmitField' => 'includes/HTMLForm.php',
- 'HTMLTextAreaField' => 'includes/HTMLForm.php',
- 'HTMLTextField' => 'includes/HTMLForm.php',
+ 'HTMLApiField' => 'includes/htmlform/HTMLApiField.php',
+ 'HTMLAutoCompleteSelectField' => 'includes/htmlform/HTMLAutoCompleteSelectField.php',
+ 'HTMLButtonField' => 'includes/htmlform/HTMLButtonField.php',
+ 'HTMLCheckField' => 'includes/htmlform/HTMLCheckField.php',
+ 'HTMLCheckMatrix' => 'includes/htmlform/HTMLCheckMatrix.php',
+ 'HTMLFormFieldCloner' => 'includes/htmlform/HTMLFormFieldCloner.php',
+ 'HTMLEditTools' => 'includes/htmlform/HTMLEditTools.php',
+ 'HTMLFloatField' => 'includes/htmlform/HTMLFloatField.php',
+ 'HTMLForm' => 'includes/htmlform/HTMLForm.php',
+ 'HTMLFormField' => 'includes/htmlform/HTMLFormField.php',
+ 'HTMLFormFieldRequiredOptionsException' =>
+ 'includes/htmlform/HTMLFormFieldRequiredOptionsException.php',
+ 'HTMLHiddenField' => 'includes/htmlform/HTMLHiddenField.php',
+ 'HTMLInfoField' => 'includes/htmlform/HTMLInfoField.php',
+ 'HTMLIntField' => 'includes/htmlform/HTMLIntField.php',
+ 'HTMLNestedFilterable' => 'includes/htmlform/HTMLNestedFilterable.php',
+ 'HTMLMultiSelectField' => 'includes/htmlform/HTMLMultiSelectField.php',
+ 'HTMLRadioField' => 'includes/htmlform/HTMLRadioField.php',
+ 'HTMLSelectAndOtherField' => 'includes/htmlform/HTMLSelectAndOtherField.php',
+ 'HTMLSelectField' => 'includes/htmlform/HTMLSelectField.php',
+ 'HTMLSelectLimitField' => 'includes/htmlform/HTMLSelectLimitField.php',
+ 'HTMLSelectOrOtherField' => 'includes/htmlform/HTMLSelectOrOtherField.php',
+ 'HTMLSubmitField' => 'includes/htmlform/HTMLSubmitField.php',
+ 'HTMLTextAreaField' => 'includes/htmlform/HTMLTextAreaField.php',
+ 'HTMLTextField' => 'includes/htmlform/HTMLTextField.php',
'Http' => 'includes/HttpFunctions.php',
- 'HttpError' => 'includes/Exception.php',
- 'ICacheHelper' => 'includes/CacheHelper.php',
'IcuCollation' => 'includes/Collation.php',
'IdentityCollation' => 'includes/Collation.php',
- 'ImageHistoryList' => 'includes/ImagePage.php',
- 'ImageHistoryPseudoPager' => 'includes/ImagePage.php',
- 'ImagePage' => 'includes/ImagePage.php',
- 'ImageQueryPage' => 'includes/ImageQueryPage.php',
'ImportStreamSource' => 'includes/Import.php',
'ImportStringSource' => 'includes/Import.php',
- 'IncludableSpecialPage' => 'includes/SpecialPage.php',
- 'IndexPager' => 'includes/Pager.php',
'Interwiki' => 'includes/interwiki/Interwiki.php',
- 'IP' => 'includes/IP.php',
- 'LCStore' => 'includes/cache/LocalisationCache.php',
- 'LCStore_Accel' => 'includes/cache/LocalisationCache.php',
- 'LCStore_CDB' => 'includes/cache/LocalisationCache.php',
- 'LCStore_DB' => 'includes/cache/LocalisationCache.php',
- 'LCStore_Null' => 'includes/cache/LocalisationCache.php',
'License' => 'includes/Licenses.php',
'Licenses' => 'includes/Licenses.php',
'Linker' => 'includes/Linker.php',
'LinkFilter' => 'includes/LinkFilter.php',
- 'LinksUpdate' => 'includes/LinksUpdate.php',
- 'LinksDeletionUpdate' => 'includes/LinksUpdate.php',
- 'LocalisationCache' => 'includes/cache/LocalisationCache.php',
- 'LocalisationCache_BulkLoad' => 'includes/cache/LocalisationCache.php',
'MagicWord' => 'includes/MagicWord.php',
'MagicWordArray' => 'includes/MagicWord.php',
- 'MailAddress' => 'includes/UserMailer.php',
- 'MappedIterator' => 'includes/MappedIterator.php',
- 'MediaWiki' => 'includes/Wiki.php',
- 'MediaWiki_I18N' => 'includes/SkinTemplate.php',
+ 'MediaWiki' => 'includes/MediaWiki.php',
+ 'MediaWikiVersionFetcher' => 'includes/MediaWikiVersionFetcher.php',
'Message' => 'includes/Message.php',
'MessageBlobStore' => 'includes/MessageBlobStore.php',
'MimeMagic' => 'includes/MimeMagic.php',
- 'MWCryptRand' => 'includes/MWCryptRand.php',
- 'MWException' => 'includes/Exception.php',
- 'MWExceptionHandler' => 'includes/Exception.php',
- 'MWFunction' => 'includes/MWFunction.php',
+ 'MovePage' => 'includes/MovePage.php',
'MWHookException' => 'includes/Hooks.php',
'MWHttpRequest' => 'includes/HttpFunctions.php',
- 'MWInit' => 'includes/Init.php',
- 'MWNamespace' => 'includes/Namespace.php',
+ 'MWNamespace' => 'includes/MWNamespace.php',
'OutputPage' => 'includes/OutputPage.php',
- 'Page' => 'includes/WikiPage.php',
- 'PageQueryPage' => 'includes/PageQueryPage.php',
- 'Pager' => 'includes/Pager.php',
- 'PasswordError' => 'includes/User.php',
'PathRouter' => 'includes/PathRouter.php',
'PathRouterPatternReplacer' => 'includes/PathRouter.php',
- 'PermissionsError' => 'includes/Exception.php',
'PhpHttpRequest' => 'includes/HttpFunctions.php',
- 'PoolCounter' => 'includes/PoolCounter.php',
- 'PoolCounter_Stub' => 'includes/PoolCounter.php',
- 'PoolCounterWork' => 'includes/PoolCounter.php',
- 'PoolCounterWorkViaCallback' => 'includes/PoolCounter.php',
- 'PoolWorkArticleView' => 'includes/WikiPage.php',
+ 'PoolCounter' => 'includes/poolcounter/PoolCounter.php',
+ 'PoolCounter_Stub' => 'includes/poolcounter/PoolCounter.php',
+ 'PoolCounterRedis' => 'includes/poolcounter/PoolCounterRedis.php',
+ 'PoolCounterWork' => 'includes/poolcounter/PoolCounterWork.php',
+ 'PoolCounterWorkViaCallback' => 'includes/poolcounter/PoolCounterWorkViaCallback.php',
+ 'PoolWorkArticleView' => 'includes/poolcounter/PoolWorkArticleView.php',
'Preferences' => 'includes/Preferences.php',
'PreferencesForm' => 'includes/Preferences.php',
'PrefixSearch' => 'includes/PrefixSearch.php',
'ProtectionForm' => 'includes/ProtectionForm.php',
- 'QueryPage' => 'includes/QueryPage.php',
- 'QuickTemplate' => 'includes/SkinTemplate.php',
'RawMessage' => 'includes/Message.php',
- 'RdfMetaData' => 'includes/Metadata.php',
- 'ReadOnlyError' => 'includes/Exception.php',
- 'RedirectSpecialArticle' => 'includes/SpecialPage.php',
- 'RedirectSpecialPage' => 'includes/SpecialPage.php',
- 'RegexlikeReplacer' => 'includes/StringUtils.php',
- 'ReplacementArray' => 'includes/StringUtils.php',
- 'Replacer' => 'includes/StringUtils.php',
- 'ReverseChronologicalPager' => 'includes/Pager.php',
'RevisionItem' => 'includes/RevisionList.php',
'RevisionItemBase' => 'includes/RevisionList.php',
'RevisionListBase' => 'includes/RevisionList.php',
@@ -212,125 +152,72 @@ $wgAutoloadLocalClasses = array(
'RevisionList' => 'includes/RevisionList.php',
'RSSFeed' => 'includes/Feed.php',
'Sanitizer' => 'includes/Sanitizer.php',
- 'DataUpdate' => 'includes/DataUpdate.php',
- 'SqlDataUpdate' => 'includes/SqlDataUpdate.php',
- 'ScopedCallback' => 'includes/ScopedCallback.php',
- 'ScopedPHPTimeout' => 'includes/ScopedPHPTimeout.php',
'SiteConfiguration' => 'includes/SiteConfiguration.php',
'SiteStats' => 'includes/SiteStats.php',
'SiteStatsInit' => 'includes/SiteStats.php',
- 'SiteStatsUpdate' => 'includes/SiteStats.php',
- 'Skin' => 'includes/Skin.php',
- 'SkinTemplate' => 'includes/SkinTemplate.php',
- 'SpecialCreateAccount' => 'includes/SpecialPage.php',
- 'SpecialListAdmins' => 'includes/SpecialPage.php',
- 'SpecialListBots' => 'includes/SpecialPage.php',
- 'SpecialMycontributions' => 'includes/SpecialPage.php',
- 'SpecialMypage' => 'includes/SpecialPage.php',
- 'SpecialMytalk' => 'includes/SpecialPage.php',
- 'SpecialMyuploads' => 'includes/SpecialPage.php',
- 'SpecialAllMyUploads' => 'includes/SpecialPage.php',
- 'SpecialPage' => 'includes/SpecialPage.php',
- 'SpecialPageFactory' => 'includes/SpecialPageFactory.php',
- 'SpecialRedirectToSpecial' => 'includes/SpecialPage.php',
'SquidPurgeClient' => 'includes/SquidPurgeClient.php',
'SquidPurgeClientPool' => 'includes/SquidPurgeClient.php',
'StatCounter' => 'includes/StatCounter.php',
'Status' => 'includes/Status.php',
'StreamFile' => 'includes/StreamFile.php',
- 'StringUtils' => 'includes/StringUtils.php',
- 'StubContLang' => 'includes/StubObject.php',
+ 'StringPrefixSearch' => 'includes/PrefixSearch.php',
'StubObject' => 'includes/StubObject.php',
'StubUserLang' => 'includes/StubObject.php',
- 'TablePager' => 'includes/Pager.php',
- 'MWTimestamp' => 'includes/Timestamp.php',
- 'TimestampException' => 'includes/Timestamp.php',
+ 'MWTimestamp' => 'includes/MWTimestamp.php',
+ 'TimestampException' => 'includes/TimestampException.php',
'Title' => 'includes/Title.php',
'TitleArray' => 'includes/TitleArray.php',
- 'TitleArrayFromResult' => 'includes/TitleArray.php',
- 'ThrottledError' => 'includes/Exception.php',
- 'UIDGenerator' => 'includes/UIDGenerator.php',
- 'UnlistedSpecialPage' => 'includes/SpecialPage.php',
+ 'TitleArrayFromResult' => 'includes/TitleArrayFromResult.php',
+ 'TitlePrefixSearch' => 'includes/PrefixSearch.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',
+ 'UserArrayFromResult' => 'includes/UserArrayFromResult.php',
'UserRightsProxy' => 'includes/UserRightsProxy.php',
- 'ViewCountUpdate' => 'includes/ViewCountUpdate.php',
- 'WantedQueryPage' => 'includes/QueryPage.php',
'WatchedItem' => 'includes/WatchedItem.php',
'WebRequest' => 'includes/WebRequest.php',
'WebRequestUpload' => 'includes/WebRequest.php',
'WebResponse' => 'includes/WebResponse.php',
- 'WikiCategoryPage' => 'includes/WikiCategoryPage.php',
- 'WikiError' => 'includes/WikiError.php',
- 'WikiErrorMsg' => 'includes/WikiError.php',
'WikiExporter' => 'includes/Export.php',
- 'WikiFilePage' => 'includes/WikiFilePage.php',
'WikiImporter' => 'includes/Import.php',
- 'WikiPage' => 'includes/WikiPage.php',
'WikiRevision' => 'includes/Import.php',
'WikiMap' => 'includes/WikiMap.php',
'WikiReference' => 'includes/WikiMap.php',
- 'WikiXmlError' => 'includes/WikiError.php',
'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',
-
- # content handler
- 'AbstractContent' => 'includes/content/AbstractContent.php',
- 'ContentHandler' => 'includes/content/ContentHandler.php',
- 'Content' => 'includes/content/Content.php',
- 'CssContentHandler' => 'includes/content/CssContentHandler.php',
- 'CssContent' => 'includes/content/CssContent.php',
- 'JavaScriptContentHandler' => 'includes/content/JavaScriptContentHandler.php',
- 'JavaScriptContent' => 'includes/content/JavaScriptContent.php',
- 'MessageContent' => 'includes/content/MessageContent.php',
- 'MWContentSerializationException' => 'includes/content/ContentHandler.php',
- 'TextContentHandler' => 'includes/content/TextContentHandler.php',
- 'TextContent' => 'includes/content/TextContent.php',
- 'WikitextContentHandler' => 'includes/content/WikitextContentHandler.php',
- 'WikitextContent' => 'includes/content/WikitextContent.php',
# includes/actions
+ 'Action' => 'includes/actions/Action.php',
'CachedAction' => 'includes/actions/CachedAction.php',
'CreditsAction' => 'includes/actions/CreditsAction.php',
'DeleteAction' => 'includes/actions/DeleteAction.php',
'EditAction' => 'includes/actions/EditAction.php',
+ 'FormlessAction' => 'includes/actions/FormlessAction.php',
+ 'FormAction' => 'includes/actions/FormAction.php',
'HistoryAction' => 'includes/actions/HistoryAction.php',
- 'HistoryPage' => 'includes/actions/HistoryAction.php',
'HistoryPager' => 'includes/actions/HistoryAction.php',
'InfoAction' => 'includes/actions/InfoAction.php',
'MarkpatrolledAction' => 'includes/actions/MarkpatrolledAction.php',
'ProtectAction' => 'includes/actions/ProtectAction.php',
'PurgeAction' => 'includes/actions/PurgeAction.php',
'RawAction' => 'includes/actions/RawAction.php',
- 'RawPage' => 'includes/actions/RawAction.php',
'RenderAction' => 'includes/actions/RenderAction.php',
'RevertAction' => 'includes/actions/RevertAction.php',
- 'RevertFileAction' => 'includes/actions/RevertAction.php',
'RevisiondeleteAction' => 'includes/actions/RevisiondeleteAction.php',
'RollbackAction' => 'includes/actions/RollbackAction.php',
- 'SubmitAction' => 'includes/actions/EditAction.php',
- 'UnprotectAction' => 'includes/actions/ProtectAction.php',
- 'UnwatchAction' => 'includes/actions/WatchAction.php',
+ 'SubmitAction' => 'includes/actions/SubmitAction.php',
+ 'UnprotectAction' => 'includes/actions/UnprotectAction.php',
+ 'UnwatchAction' => 'includes/actions/UnwatchAction.php',
'ViewAction' => 'includes/actions/ViewAction.php',
'WatchAction' => 'includes/actions/WatchAction.php',
# includes/api
'ApiBase' => 'includes/api/ApiBase.php',
'ApiBlock' => 'includes/api/ApiBlock.php',
+ 'ApiClearHasMsg' => 'includes/api/ApiClearHasMsg.php',
'ApiComparePages' => 'includes/api/ApiComparePages.php',
'ApiCreateAccount' => 'includes/api/ApiCreateAccount.php',
'ApiDelete' => 'includes/api/ApiDelete.php',
@@ -339,12 +226,13 @@ $wgAutoloadLocalClasses = array(
'ApiEmailUser' => 'includes/api/ApiEmailUser.php',
'ApiExpandTemplates' => 'includes/api/ApiExpandTemplates.php',
'ApiFeedContributions' => 'includes/api/ApiFeedContributions.php',
+ 'ApiFeedRecentChanges' => 'includes/api/ApiFeedRecentChanges.php',
'ApiFeedWatchlist' => 'includes/api/ApiFeedWatchlist.php',
'ApiFileRevert' => 'includes/api/ApiFileRevert.php',
'ApiFormatBase' => 'includes/api/ApiFormatBase.php',
'ApiFormatDbg' => 'includes/api/ApiFormatDbg.php',
'ApiFormatDump' => 'includes/api/ApiFormatDump.php',
- 'ApiFormatFeedWrapper' => 'includes/api/ApiFormatBase.php',
+ 'ApiFormatFeedWrapper' => 'includes/api/ApiFormatFeedWrapper.php',
'ApiFormatJson' => 'includes/api/ApiFormatJson.php',
'ApiFormatNone' => 'includes/api/ApiFormatNone.php',
'ApiFormatPhp' => 'includes/api/ApiFormatPhp.php',
@@ -379,12 +267,14 @@ $wgAutoloadLocalClasses = array(
'ApiQueryAllPages' => 'includes/api/ApiQueryAllPages.php',
'ApiQueryAllUsers' => 'includes/api/ApiQueryAllUsers.php',
'ApiQueryBacklinks' => 'includes/api/ApiQueryBacklinks.php',
+ 'ApiQueryBacklinksprop' => 'includes/api/ApiQueryBacklinksprop.php',
'ApiQueryBase' => 'includes/api/ApiQueryBase.php',
'ApiQueryBlocks' => 'includes/api/ApiQueryBlocks.php',
'ApiQueryCategories' => 'includes/api/ApiQueryCategories.php',
'ApiQueryCategoryInfo' => 'includes/api/ApiQueryCategoryInfo.php',
'ApiQueryCategoryMembers' => 'includes/api/ApiQueryCategoryMembers.php',
'ApiQueryContributions' => 'includes/api/ApiQueryUserContributions.php',
+ 'ApiQueryContributors' => 'includes/api/ApiQueryContributors.php',
'ApiQueryDeletedrevs' => 'includes/api/ApiQueryDeletedrevs.php',
'ApiQueryDisabled' => 'includes/api/ApiQueryDisabled.php',
'ApiQueryDuplicateFiles' => 'includes/api/ApiQueryDuplicateFiles.php',
@@ -405,6 +295,7 @@ $wgAutoloadLocalClasses = array(
'ApiQueryPageProps' => 'includes/api/ApiQueryPageProps.php',
'ApiQueryPagesWithProp' => 'includes/api/ApiQueryPagesWithProp.php',
'ApiQueryPagePropNames' => 'includes/api/ApiQueryPagePropNames.php',
+ 'ApiQueryPrefixSearch' => 'includes/api/ApiQueryPrefixSearch.php',
'ApiQueryProtectedTitles' => 'includes/api/ApiQueryProtectedTitles.php',
'ApiQueryQueryPage' => 'includes/api/ApiQueryQueryPage.php',
'ApiQueryRandom' => 'includes/api/ApiQueryRandom.php',
@@ -415,11 +306,13 @@ $wgAutoloadLocalClasses = array(
'ApiQuerySiteinfo' => 'includes/api/ApiQuerySiteinfo.php',
'ApiQueryStashImageInfo' => 'includes/api/ApiQueryStashImageInfo.php',
'ApiQueryTags' => 'includes/api/ApiQueryTags.php',
+ 'ApiQueryTokens' => 'includes/api/ApiQueryTokens.php',
'ApiQueryUserInfo' => 'includes/api/ApiQueryUserInfo.php',
'ApiQueryUsers' => 'includes/api/ApiQueryUsers.php',
'ApiQueryWatchlist' => 'includes/api/ApiQueryWatchlist.php',
'ApiQueryWatchlistRaw' => 'includes/api/ApiQueryWatchlistRaw.php',
'ApiResult' => 'includes/api/ApiResult.php',
+ 'ApiRevisionDelete' => 'includes/api/ApiRevisionDelete.php',
'ApiRollback' => 'includes/api/ApiRollback.php',
'ApiRsd' => 'includes/api/ApiRsd.php',
'ApiSetNotificationTimestamp' => 'includes/api/ApiSetNotificationTimestamp.php',
@@ -434,35 +327,73 @@ $wgAutoloadLocalClasses = array(
# includes/cache
'BacklinkCache' => 'includes/cache/BacklinkCache.php',
'CacheDependency' => 'includes/cache/CacheDependency.php',
+ 'CacheHelper' => 'includes/cache/CacheHelper.php',
'ConstantDependency' => 'includes/cache/CacheDependency.php',
'DependencyWrapper' => 'includes/cache/CacheDependency.php',
'FileCacheBase' => 'includes/cache/FileCacheBase.php',
'FileDependency' => 'includes/cache/CacheDependency.php',
'GenderCache' => 'includes/cache/GenderCache.php',
'GlobalDependency' => 'includes/cache/CacheDependency.php',
- 'HTMLCacheUpdate' => 'includes/cache/HTMLCacheUpdate.php',
'HTMLFileCache' => 'includes/cache/HTMLFileCache.php',
+ 'ICacheHelper' => 'includes/cache/CacheHelper.php',
+ 'LCStore' => 'includes/cache/LocalisationCache.php',
+ 'LCStoreCDB' => 'includes/cache/LocalisationCache.php',
+ 'LCStoreDB' => 'includes/cache/LocalisationCache.php',
+ 'LCStoreNull' => 'includes/cache/LocalisationCache.php',
'LinkBatch' => 'includes/cache/LinkBatch.php',
'LinkCache' => 'includes/cache/LinkCache.php',
+ 'LocalisationCache' => 'includes/cache/LocalisationCache.php',
+ 'LocalisationCacheBulkLoad' => 'includes/cache/LocalisationCache.php',
+ 'MapCacheLRU' => 'includes/cache/MapCacheLRU.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',
+ 'UserCache' => 'includes/cache/UserCache.php',
# includes/changes
+ 'ChangesFeed' => 'includes/changes/ChangesFeed.php',
'ChangesList' => 'includes/changes/ChangesList.php',
'EnhancedChangesList' => 'includes/changes/EnhancedChangesList.php',
'OldChangesList' => 'includes/changes/OldChangesList.php',
'RCCacheEntry' => 'includes/changes/RCCacheEntry.php',
+ 'RCCacheEntryFactory' => 'includes/changes/RCCacheEntryFactory.php',
'RecentChange' => 'includes/changes/RecentChange.php',
# includes/clientpool
'RedisConnectionPool' => 'includes/clientpool/RedisConnectionPool.php',
'RedisConnRef' => 'includes/clientpool/RedisConnectionPool.php',
+ # includes/composer
+ 'ComposerPackageModifier' => 'includes/composer/ComposerPackageModifier.php',
+ 'ComposerVersionNormalizer' => 'includes/composer/ComposerVersionNormalizer.php',
+
+ # includes/config
+ 'Config' => 'includes/config/Config.php',
+ 'ConfigException' => 'includes/config/ConfigException.php',
+ 'ConfigFactory' => 'includes/config/ConfigFactory.php',
+ 'GlobalVarConfig' => 'includes/config/GlobalVarConfig.php',
+ 'HashConfig' => 'includes/config/HashConfig.php',
+ 'MultiConfig' => 'includes/config/MultiConfig.php',
+ 'MutableConfig' => 'includes/config/MutableConfig.php',
+
+ # includes/content
+ 'AbstractContent' => 'includes/content/AbstractContent.php',
+ 'CodeContentHandler' => 'includes/content/CodeContentHandler.php',
+ 'Content' => 'includes/content/Content.php',
+ 'ContentHandler' => 'includes/content/ContentHandler.php',
+ 'CssContent' => 'includes/content/CssContent.php',
+ 'CssContentHandler' => 'includes/content/CssContentHandler.php',
+ 'JavaScriptContent' => 'includes/content/JavaScriptContent.php',
+ 'JavaScriptContentHandler' => 'includes/content/JavaScriptContentHandler.php',
+ 'JsonContent' => 'includes/content/JsonContent.php',
+ 'JsonContentHandler' => 'includes/content/JsonContentHandler.php',
+ 'MessageContent' => 'includes/content/MessageContent.php',
+ 'MWContentSerializationException' => 'includes/content/ContentHandler.php',
+ 'TextContent' => 'includes/content/TextContent.php',
+ 'TextContentHandler' => 'includes/content/TextContentHandler.php',
+ 'WikitextContent' => 'includes/content/WikitextContent.php',
+ 'WikitextContentHandler' => 'includes/content/WikitextContentHandler.php',
+
# includes/context
'ContextSource' => 'includes/context/ContextSource.php',
'DerivativeContext' => 'includes/context/DerivativeContext.php',
@@ -491,6 +422,7 @@ $wgAutoloadLocalClasses = array(
'DBConnectionError' => 'includes/db/DatabaseError.php',
'DBConnRef' => 'includes/db/LoadBalancer.php',
'DBError' => 'includes/db/DatabaseError.php',
+ 'DBExpectedError' => 'includes/db/DatabaseError.php',
'DBObject' => 'includes/db/DatabaseUtility.php',
'IDatabase' => 'includes/db/Database.php',
'IORMRow' => 'includes/db/IORMRow.php',
@@ -501,18 +433,19 @@ $wgAutoloadLocalClasses = array(
'FakeResultWrapper' => 'includes/db/DatabaseUtility.php',
'Field' => 'includes/db/DatabaseUtility.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',
+ 'LBFactoryFake' => 'includes/db/LBFactory.php',
+ 'LBFactoryMulti' => 'includes/db/LBFactoryMulti.php',
+ 'LBFactorySimple' => 'includes/db/LBFactory.php',
+ 'LBFactorySingle' => 'includes/db/LBFactorySingle.php',
'LikeMatch' => 'includes/db/DatabaseUtility.php',
'LoadBalancer' => 'includes/db/LoadBalancer.php',
- 'LoadBalancer_Single' => 'includes/db/LBFactory_Single.php',
+ 'LoadBalancerSingle' => 'includes/db/LBFactorySingle.php',
'LoadMonitor' => 'includes/db/LoadMonitor.php',
- 'LoadMonitor_MySQL' => 'includes/db/LoadMonitor.php',
- 'LoadMonitor_Null' => 'includes/db/LoadMonitor.php',
+ 'LoadMonitorMySQL' => 'includes/db/LoadMonitor.php',
+ 'LoadMonitorNull' => 'includes/db/LoadMonitor.php',
'MssqlField' => 'includes/db/DatabaseMssql.php',
- 'MssqlResult' => 'includes/db/DatabaseMssql.php',
+ 'MssqlBlob' => 'includes/db/DatabaseMssql.php',
+ 'MssqlResultWrapper' => 'includes/db/DatabaseMssql.php',
'MySQLField' => 'includes/db/DatabaseMysqlBase.php',
'MySQLMasterPos' => 'includes/db/DatabaseMysqlBase.php',
'ORAField' => 'includes/db/DatabaseOracle.php',
@@ -528,27 +461,54 @@ $wgAutoloadLocalClasses = array(
'SQLiteField' => 'includes/db/DatabaseSqlite.php',
# includes/debug
- 'MWDebug' => 'includes/debug/Debug.php',
+ 'MWDebug' => 'includes/debug/MWDebug.php',
+
+ # includes/deferred
+ 'DataUpdate' => 'includes/deferred/DataUpdate.php',
+ 'DeferrableUpdate' => 'includes/deferred/DeferredUpdates.php',
+ 'DeferredUpdates' => 'includes/deferred/DeferredUpdates.php',
+ 'HTMLCacheUpdate' => 'includes/deferred/HTMLCacheUpdate.php',
+ 'LinksDeletionUpdate' => 'includes/deferred/LinksUpdate.php',
+ 'LinksUpdate' => 'includes/deferred/LinksUpdate.php',
+ 'MWCallableUpdate' => 'includes/deferred/CallableUpdate.php',
+ 'SearchUpdate' => 'includes/deferred/SearchUpdate.php',
+ 'SiteStatsUpdate' => 'includes/deferred/SiteStatsUpdate.php',
+ 'SqlDataUpdate' => 'includes/deferred/SqlDataUpdate.php',
+ 'SquidUpdate' => 'includes/deferred/SquidUpdate.php',
+ 'ViewCountUpdate' => 'includes/deferred/ViewCountUpdate.php',
# includes/diff
- '_DiffEngine' => 'includes/diff/DairikiDiff.php',
- '_DiffOp' => 'includes/diff/DairikiDiff.php',
- '_DiffOp_Add' => 'includes/diff/DairikiDiff.php',
- '_DiffOp_Change' => 'includes/diff/DairikiDiff.php',
- '_DiffOp_Copy' => 'includes/diff/DairikiDiff.php',
- '_DiffOp_Delete' => 'includes/diff/DairikiDiff.php',
- '_HWLDF_WordAccumulator' => 'includes/diff/DairikiDiff.php',
- 'ArrayDiffFormatter' => 'includes/diff/DairikiDiff.php',
+ 'DiffEngine' => 'includes/diff/DairikiDiff.php',
+ 'DiffOp' => 'includes/diff/DairikiDiff.php',
+ 'DiffOpAdd' => 'includes/diff/DairikiDiff.php',
+ 'DiffOpChange' => 'includes/diff/DairikiDiff.php',
+ 'DiffOpCopy' => 'includes/diff/DairikiDiff.php',
+ 'DiffOpDelete' => 'includes/diff/DairikiDiff.php',
+ 'HWLDFWordAccumulator' => 'includes/diff/DairikiDiff.php',
+ 'ArrayDiffFormatter' => 'includes/diff/ArrayDiffFormatter.php',
'Diff' => 'includes/diff/DairikiDiff.php',
'DifferenceEngine' => 'includes/diff/DifferenceEngine.php',
- 'DiffFormatter' => 'includes/diff/DairikiDiff.php',
+ 'DiffFormatter' => 'includes/diff/DiffFormatter.php',
'MappedDiff' => 'includes/diff/DairikiDiff.php',
'RangeDifference' => 'includes/diff/WikiDiff3.php',
- 'TableDiffFormatter' => 'includes/diff/DairikiDiff.php',
- 'UnifiedDiffFormatter' => 'includes/diff/DairikiDiff.php',
+ 'TableDiffFormatter' => 'includes/diff/TableDiffFormatter.php',
+ 'UnifiedDiffFormatter' => 'includes/diff/UnifiedDiffFormatter.php',
'WikiDiff3' => 'includes/diff/WikiDiff3.php',
'WordLevelDiff' => 'includes/diff/DairikiDiff.php',
+ # includes/exception
+ 'UserBlockedError' => 'includes/exception/UserBlockedError.php',
+ 'UserNotLoggedIn' => 'includes/exception/UserNotLoggedIn.php',
+ 'ThrottledError' => 'includes/exception/ThrottledError.php',
+ 'ReadOnlyError' => 'includes/exception/ReadOnlyError.php',
+ 'PermissionsError' => 'includes/exception/PermissionsError.php',
+ 'MWException' => 'includes/exception/MWException.php',
+ 'MWExceptionHandler' => 'includes/exception/MWExceptionHandler.php',
+ 'HttpError' => 'includes/exception/HttpError.php',
+ 'BadTitleError' => 'includes/exception/BadTitleError.php',
+ 'ErrorPageError' => 'includes/exception/ErrorPageError.php',
+ 'FatalError' => 'includes/exception/FatalError.php',
+
# includes/externalstore
'ExternalStore' => 'includes/externalstore/ExternalStore.php',
'ExternalStoreDB' => 'includes/externalstore/ExternalStoreDB.php',
@@ -560,6 +520,7 @@ $wgAutoloadLocalClasses = array(
'FileBackendGroup' => 'includes/filebackend/FileBackendGroup.php',
'FileBackend' => 'includes/filebackend/FileBackend.php',
'FileBackendError' => 'includes/filebackend/FileBackend.php',
+ 'FileBackendException' => 'includes/filebackend/FileBackend.php',
'FileBackendStore' => 'includes/filebackend/FileBackendStore.php',
'FileBackendStoreShardListIterator' => 'includes/filebackend/FileBackendStore.php',
'FileBackendStoreShardDirIterator' => 'includes/filebackend/FileBackendStore.php',
@@ -572,6 +533,7 @@ $wgAutoloadLocalClasses = array(
'FSFileBackendDirList' => 'includes/filebackend/FSFileBackend.php',
'FSFileBackendFileList' => 'includes/filebackend/FSFileBackend.php',
'FSFileOpHandle' => 'includes/filebackend/FSFileBackend.php',
+ 'MemoryFileBackend' => 'includes/filebackend/MemoryFileBackend.php',
'SwiftFileBackend' => 'includes/filebackend/SwiftFileBackend.php',
'SwiftFileBackendList' => 'includes/filebackend/SwiftFileBackend.php',
'SwiftFileBackendDirList' => 'includes/filebackend/SwiftFileBackend.php',
@@ -586,7 +548,6 @@ $wgAutoloadLocalClasses = array(
'ScopedLock' => 'includes/filebackend/lockmanager/ScopedLock.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/QuorumLockManager.php',
'MySqlLockManager' => 'includes/filebackend/lockmanager/DBLockManager.php',
@@ -634,73 +595,83 @@ $wgAutoloadLocalClasses = array(
'InstallDocFormatter' => 'includes/installer/InstallDocFormatter.php',
'Installer' => 'includes/installer/Installer.php',
'LocalSettingsGenerator' => 'includes/installer/LocalSettingsGenerator.php',
+ 'MssqlInstaller' => 'includes/installer/MssqlInstaller.php',
+ 'MssqlUpdater' => 'includes/installer/MssqlUpdater.php',
'MysqlInstaller' => 'includes/installer/MysqlInstaller.php',
'MysqlUpdater' => 'includes/installer/MysqlUpdater.php',
'OracleInstaller' => 'includes/installer/OracleInstaller.php',
'OracleUpdater' => 'includes/installer/OracleUpdater.php',
- 'PhpRefCallBugTester' => 'includes/installer/PhpBugTests.php',
'PhpXmlBugTester' => 'includes/installer/PhpBugTests.php',
'PostgresInstaller' => 'includes/installer/PostgresInstaller.php',
'PostgresUpdater' => 'includes/installer/PostgresUpdater.php',
'SqliteInstaller' => 'includes/installer/SqliteInstaller.php',
'SqliteUpdater' => 'includes/installer/SqliteUpdater.php',
'WebInstaller' => 'includes/installer/WebInstaller.php',
- 'WebInstaller_Complete' => 'includes/installer/WebInstallerPage.php',
- 'WebInstaller_Copying' => 'includes/installer/WebInstallerPage.php',
- 'WebInstaller_DBConnect' => 'includes/installer/WebInstallerPage.php',
- 'WebInstaller_DBSettings' => 'includes/installer/WebInstallerPage.php',
- 'WebInstaller_Document' => 'includes/installer/WebInstallerPage.php',
- 'WebInstaller_ExistingWiki' => 'includes/installer/WebInstallerPage.php',
- 'WebInstaller_Install' => 'includes/installer/WebInstallerPage.php',
- 'WebInstaller_Language' => 'includes/installer/WebInstallerPage.php',
- 'WebInstaller_Name' => 'includes/installer/WebInstallerPage.php',
- 'WebInstaller_Options' => 'includes/installer/WebInstallerPage.php',
- 'WebInstaller_Readme' => 'includes/installer/WebInstallerPage.php',
- 'WebInstaller_ReleaseNotes' => 'includes/installer/WebInstallerPage.php',
- 'WebInstaller_Restart' => 'includes/installer/WebInstallerPage.php',
- 'WebInstaller_Upgrade' => 'includes/installer/WebInstallerPage.php',
- 'WebInstaller_UpgradeDoc' => 'includes/installer/WebInstallerPage.php',
- 'WebInstaller_Welcome' => 'includes/installer/WebInstallerPage.php',
+ 'WebInstallerComplete' => 'includes/installer/WebInstallerPage.php',
+ 'WebInstallerCopying' => 'includes/installer/WebInstallerPage.php',
+ 'WebInstallerDBConnect' => 'includes/installer/WebInstallerPage.php',
+ 'WebInstallerDBSettings' => 'includes/installer/WebInstallerPage.php',
+ 'WebInstallerDocument' => 'includes/installer/WebInstallerPage.php',
+ 'WebInstallerExistingWiki' => 'includes/installer/WebInstallerPage.php',
+ 'WebInstallerInstall' => 'includes/installer/WebInstallerPage.php',
+ 'WebInstallerLanguage' => 'includes/installer/WebInstallerPage.php',
+ 'WebInstallerName' => 'includes/installer/WebInstallerPage.php',
+ 'WebInstallerOptions' => 'includes/installer/WebInstallerPage.php',
+ 'WebInstallerReadme' => 'includes/installer/WebInstallerPage.php',
+ 'WebInstallerReleaseNotes' => 'includes/installer/WebInstallerPage.php',
+ 'WebInstallerRestart' => 'includes/installer/WebInstallerPage.php',
+ 'WebInstallerUpgrade' => 'includes/installer/WebInstallerPage.php',
+ 'WebInstallerUpgradeDoc' => 'includes/installer/WebInstallerPage.php',
+ 'WebInstallerWelcome' => 'includes/installer/WebInstallerPage.php',
'WebInstallerOutput' => 'includes/installer/WebInstallerOutput.php',
'WebInstallerPage' => 'includes/installer/WebInstallerPage.php',
# includes/job
- 'Job' => 'includes/job/Job.php',
- 'JobQueue' => 'includes/job/JobQueue.php',
- 'JobQueueAggregator' => 'includes/job/aggregator/JobQueueAggregator.php',
- 'JobQueueAggregatorMemc' => 'includes/job/aggregator/JobQueueAggregatorMemc.php',
- 'JobQueueAggregatorRedis' => 'includes/job/aggregator/JobQueueAggregatorRedis.php',
- 'JobQueueDB' => 'includes/job/JobQueueDB.php',
- 'JobQueueConnectionError' => 'includes/job/JobQueue.php',
- 'JobQueueError' => 'includes/job/JobQueue.php',
- 'JobQueueGroup' => 'includes/job/JobQueueGroup.php',
- 'JobQueueFederated' => 'includes/job/JobQueueFederated.php',
- 'JobQueueRedis' => 'includes/job/JobQueueRedis.php',
-
- # includes/job/jobs
- 'DoubleRedirectJob' => 'includes/job/jobs/DoubleRedirectJob.php',
- 'DuplicateJob' => 'includes/job/jobs/DuplicateJob.php',
- 'EmaillingJob' => 'includes/job/jobs/EmaillingJob.php',
- 'EnotifNotifyJob' => 'includes/job/jobs/EnotifNotifyJob.php',
- 'HTMLCacheUpdateJob' => 'includes/job/jobs/HTMLCacheUpdateJob.php',
- 'NullJob' => 'includes/job/jobs/NullJob.php',
- 'RefreshLinksJob' => 'includes/job/jobs/RefreshLinksJob.php',
- 'RefreshLinksJob2' => 'includes/job/jobs/RefreshLinksJob.php',
- 'UploadFromUrlJob' => 'includes/job/jobs/UploadFromUrlJob.php',
- 'AssembleUploadChunksJob' => 'includes/job/jobs/AssembleUploadChunksJob.php',
- 'PublishStashedFileJob' => 'includes/job/jobs/PublishStashedFileJob.php',
+ 'IJobSpecification' => 'includes/jobqueue/JobSpecification.php',
+ 'Job' => 'includes/jobqueue/Job.php',
+ 'JobQueue' => 'includes/jobqueue/JobQueue.php',
+ 'JobQueueAggregator' => 'includes/jobqueue/aggregator/JobQueueAggregator.php',
+ 'JobQueueAggregatorMemc' => 'includes/jobqueue/aggregator/JobQueueAggregatorMemc.php',
+ 'JobQueueAggregatorRedis' => 'includes/jobqueue/aggregator/JobQueueAggregatorRedis.php',
+ 'JobQueueDB' => 'includes/jobqueue/JobQueueDB.php',
+ 'JobQueueConnectionError' => 'includes/jobqueue/JobQueue.php',
+ 'JobQueueError' => 'includes/jobqueue/JobQueue.php',
+ 'JobQueueGroup' => 'includes/jobqueue/JobQueueGroup.php',
+ 'JobQueueFederated' => 'includes/jobqueue/JobQueueFederated.php',
+ 'JobQueueRedis' => 'includes/jobqueue/JobQueueRedis.php',
+ 'JobRunner' => 'includes/jobqueue/JobRunner.php',
+ 'JobSpecification' => 'includes/jobqueue/JobSpecification.php',
+
+ # includes/jobqueue/jobs
+ 'DoubleRedirectJob' => 'includes/jobqueue/jobs/DoubleRedirectJob.php',
+ 'DuplicateJob' => 'includes/jobqueue/jobs/DuplicateJob.php',
+ 'EmaillingJob' => 'includes/jobqueue/jobs/EmaillingJob.php',
+ 'EnotifNotifyJob' => 'includes/jobqueue/jobs/EnotifNotifyJob.php',
+ 'HTMLCacheUpdateJob' => 'includes/jobqueue/jobs/HTMLCacheUpdateJob.php',
+ 'NullJob' => 'includes/jobqueue/jobs/NullJob.php',
+ 'RefreshLinksJob' => 'includes/jobqueue/jobs/RefreshLinksJob.php',
+ 'RefreshLinksJob2' => 'includes/jobqueue/jobs/RefreshLinksJob2.php',
+ 'UploadFromUrlJob' => 'includes/jobqueue/jobs/UploadFromUrlJob.php',
+ 'AssembleUploadChunksJob' => 'includes/jobqueue/jobs/AssembleUploadChunksJob.php',
+ 'PublishStashedFileJob' => 'includes/jobqueue/jobs/PublishStashedFileJob.php',
+
+ # includes/jobqueue/utils
+ 'BacklinkJobUtils' => 'includes/jobqueue/utils/BacklinkJobUtils.php',
# includes/json
'FormatJson' => 'includes/json/FormatJson.php',
# includes/libs
'CSSJanus' => 'includes/libs/CSSJanus.php',
- 'CSSJanus_Tokenizer' => 'includes/libs/CSSJanus.php',
+ 'CSSJanusTokenizer' => 'includes/libs/CSSJanus.php',
'CSSMin' => 'includes/libs/CSSMin.php',
'GenericArrayObject' => 'includes/libs/GenericArrayObject.php',
+ 'HashRing' => 'includes/libs/HashRing.php',
'HttpStatus' => 'includes/libs/HttpStatus.php',
'IEContentAnalyzer' => 'includes/libs/IEContentAnalyzer.php',
'IEUrlExtension' => 'includes/libs/IEUrlExtension.php',
+ 'MappedIterator' => 'includes/libs/MappedIterator.php',
+ 'IPSet' => 'includes/libs/IPSet.php',
'JavaScriptMinifier' => 'includes/libs/JavaScriptMinifier.php',
'JSCompilerContext' => 'includes/libs/jsminplus.php',
'JSMinPlus' => 'includes/libs/jsminplus.php',
@@ -708,6 +679,16 @@ $wgAutoloadLocalClasses = array(
'JSParser' => 'includes/libs/jsminplus.php',
'JSToken' => 'includes/libs/jsminplus.php',
'JSTokenizer' => 'includes/libs/jsminplus.php',
+ 'MultiHttpClient' => 'includes/libs/MultiHttpClient.php',
+ 'MWMessagePack' => 'includes/libs/MWMessagePack.php',
+ 'ProcessCacheLRU' => 'includes/libs/ProcessCacheLRU.php',
+ 'RunningStat' => 'includes/libs/RunningStat.php',
+ 'ScopedCallback' => 'includes/libs/ScopedCallback.php',
+ 'ScopedPHPTimeout' => 'includes/libs/ScopedPHPTimeout.php',
+ 'SwiftVirtualRESTService' => 'includes/libs/virtualrest/SwiftVirtualRESTService.php',
+ 'VirtualRESTService' => 'includes/libs/virtualrest/VirtualRESTService.php',
+ 'VirtualRESTServiceClient' => 'includes/libs/virtualrest/VirtualRESTServiceClient.php',
+ 'XmlTypeCheck' => 'includes/libs/XmlTypeCheck.php',
# includes/libs/lessphp
'lessc' => 'includes/libs/lessc.inc.php',
@@ -729,6 +710,7 @@ $wgAutoloadLocalClasses = array(
'ManualLogEntry' => 'includes/logging/LogEntry.php',
'MoveLogFormatter' => 'includes/logging/MoveLogFormatter.php',
'NewUsersLogFormatter' => 'includes/logging/NewUsersLogFormatter.php',
+ 'PageLangLogFormatter' => 'includes/logging/PageLangLogFormatter.php',
'PatrolLog' => 'includes/logging/PatrolLog.php',
'PatrolLogFormatter' => 'includes/logging/PatrolLogFormatter.php',
'RCDatabaseLogEntry' => 'includes/logging/LogEntry.php',
@@ -744,6 +726,11 @@ $wgAutoloadLocalClasses = array(
'PackedHoverImageGallery' => 'includes/gallery/PackedOverlayImageGallery.php',
'PackedOverlayImageGallery' => 'includes/gallery/PackedOverlayImageGallery.php',
+ # includes/mail
+ 'EmailNotification' => 'includes/mail/EmailNotification.php',
+ 'MailAddress' => 'includes/mail/MailAddress.php',
+ 'UserMailer' => 'includes/mail/UserMailer.php',
+
# includes/media
'BitmapHandler' => 'includes/media/Bitmap.php',
'BitmapHandler_ClientOnly' => 'includes/media/Bitmap_ClientOnly.php',
@@ -753,7 +740,6 @@ $wgAutoloadLocalClasses = array(
'DjVuImage' => 'includes/media/DjVuImage.php',
'Exif' => 'includes/media/Exif.php',
'ExifBitmapHandler' => 'includes/media/ExifBitmap.php',
- 'FormatExif' => 'includes/media/FormatMetadata.php',
'FormatMetadata' => 'includes/media/FormatMetadata.php',
'GIFHandler' => 'includes/media/GIF.php',
'GIFMetadataExtractor' => 'includes/media/GIFMetadataExtractor.php',
@@ -771,6 +757,7 @@ $wgAutoloadLocalClasses = array(
'SVGReader' => 'includes/media/SVGMetadataExtractor.php',
'ThumbnailImage' => 'includes/media/MediaTransformOutput.php',
'TiffHandler' => 'includes/media/Tiff.php',
+ 'TransformationalImageHandler' => 'includes/media/TransformationalImageHandler.php',
'TransformParameterError' => 'includes/media/MediaTransformOutput.php',
'XCFHandler' => 'includes/media/XCF.php',
'XMPInfo' => 'includes/media/XMPInfo.php',
@@ -783,10 +770,7 @@ $wgAutoloadLocalClasses = array(
# includes/objectcache
'APCBagOStuff' => 'includes/objectcache/APCBagOStuff.php',
'BagOStuff' => 'includes/objectcache/BagOStuff.php',
- 'DBABagOStuff' => 'includes/objectcache/DBABagOStuff.php',
- 'EhcacheBagOStuff' => 'includes/objectcache/EhcacheBagOStuff.php',
'EmptyBagOStuff' => 'includes/objectcache/EmptyBagOStuff.php',
- 'FakeMemCachedClient' => 'includes/objectcache/EmptyBagOStuff.php',
'HashBagOStuff' => 'includes/objectcache/HashBagOStuff.php',
'MediaWikiBagOStuff' => 'includes/objectcache/SqlBagOStuff.php',
'MemCachedClientforWiki' => 'includes/objectcache/MemcachedClient.php',
@@ -802,14 +786,32 @@ $wgAutoloadLocalClasses = array(
'WinCacheBagOStuff' => 'includes/objectcache/WinCacheBagOStuff.php',
'XCacheBagOStuff' => 'includes/objectcache/XCacheBagOStuff.php',
+ # includes/page
+ 'Article' => 'includes/page/Article.php',
+ 'CategoryPage' => 'includes/page/CategoryPage.php',
+ 'ImageHistoryList' => 'includes/page/ImagePage.php',
+ 'ImageHistoryPseudoPager' => 'includes/page/ImagePage.php',
+ 'ImagePage' => 'includes/page/ImagePage.php',
+ 'Page' => 'includes/page/WikiPage.php',
+ 'WikiCategoryPage' => 'includes/page/WikiCategoryPage.php',
+ 'WikiFilePage' => 'includes/page/WikiFilePage.php',
+ 'WikiPage' => 'includes/page/WikiPage.php',
+
+ # includes/pager
+ 'AlphabeticPager' => 'includes/pager/AlphabeticPager.php',
+ 'IndexPager' => 'includes/pager/IndexPager.php',
+ 'Pager' => 'includes/pager/Pager.php',
+ 'ReverseChronologicalPager' => 'includes/pager/ReverseChronologicalPager.php',
+ 'TablePager' => 'includes/pager/TablePager.php',
+
# includes/parser
'CacheTime' => 'includes/parser/CacheTime.php',
'CoreParserFunctions' => 'includes/parser/CoreParserFunctions.php',
'CoreTagHooks' => 'includes/parser/CoreTagHooks.php',
'DateFormatter' => 'includes/parser/DateFormatter.php',
'LinkHolderArray' => 'includes/parser/LinkHolderArray.php',
- 'MWTidy' => 'includes/parser/Tidy.php',
- 'MWTidyWrapper' => 'includes/parser/Tidy.php',
+ 'MWTidy' => 'includes/parser/MWTidy.php',
+ 'MWTidyWrapper' => 'includes/parser/MWTidy.php',
'PPCustomFrame_DOM' => 'includes/parser/Preprocessor_DOM.php',
'PPCustomFrame_Hash' => 'includes/parser/Preprocessor_Hash.php',
'PPDAccum_Hash' => 'includes/parser/Preprocessor_Hash.php',
@@ -834,20 +836,36 @@ $wgAutoloadLocalClasses = array(
'ParserCache' => 'includes/parser/ParserCache.php',
'ParserOptions' => 'includes/parser/ParserOptions.php',
'ParserOutput' => 'includes/parser/ParserOutput.php',
- 'Parser_DiffTest' => 'includes/parser/Parser_DiffTest.php',
+ 'ParserDiffTest' => 'includes/parser/ParserDiffTest.php',
'Preprocessor' => 'includes/parser/Preprocessor.php',
'Preprocessor_DOM' => 'includes/parser/Preprocessor_DOM.php',
'Preprocessor_Hash' => 'includes/parser/Preprocessor_Hash.php',
'StripState' => 'includes/parser/StripState.php',
+ # includes/password
+ 'BcryptPassword' => 'includes/password/BcryptPassword.php',
+ 'InvalidPassword' => 'includes/password/InvalidPassword.php',
+ 'LayeredParameterizedPassword' => 'includes/password/LayeredParameterizedPassword.php',
+ 'MWSaltedPassword' => 'includes/password/MWSaltedPassword.php',
+ 'MWOldPassword' => 'includes/password/MWOldPassword.php',
+ 'ParameterizedPassword' => 'includes/password/ParameterizedPassword.php',
+ 'Password' => 'includes/password/Password.php',
+ 'PasswordError' => 'includes/password/PasswordError.php',
+ 'PasswordFactory' => 'includes/password/PasswordFactory.php',
+ 'Pbkdf2Password' => 'includes/password/Pbkdf2Password.php',
+ 'EncryptedPassword' => 'includes/password/EncryptedPassword.php',
+
# includes/profiler
'Profiler' => 'includes/profiler/Profiler.php',
- 'ProfilerSimple' => 'includes/profiler/ProfilerSimple.php',
+ 'ProfilerMwprof' => 'includes/profiler/ProfilerMwprof.php',
+ 'ProfilerSimpleDB' => 'includes/profiler/ProfilerSimpleDB.php',
'ProfilerSimpleText' => 'includes/profiler/ProfilerSimpleText.php',
'ProfilerSimpleTrace' => 'includes/profiler/ProfilerSimpleTrace.php',
'ProfilerSimpleUDP' => 'includes/profiler/ProfilerSimpleUDP.php',
+ 'ProfilerStandard' => 'includes/profiler/ProfilerStandard.php',
'ProfilerStub' => 'includes/profiler/ProfilerStub.php',
'ProfileSection' => 'includes/profiler/Profiler.php',
+ 'TransactionProfiler' => 'includes/profiler/Profiler.php',
# includes/rcfeed
'RCFeedEngine' => 'includes/rcfeed/RCFeedEngine.php',
@@ -856,62 +874,65 @@ $wgAutoloadLocalClasses = array(
'RCFeedFormatter' => 'includes/rcfeed/RCFeedFormatter.php',
'IRCColourfulRCFeedFormatter' => 'includes/rcfeed/IRCColourfulRCFeedFormatter.php',
'JSONRCFeedFormatter' => 'includes/rcfeed/JSONRCFeedFormatter.php',
+ 'XMLRCFeedFormatter' => 'includes/rcfeed/XMLRCFeedFormatter.php',
+ 'MachineReadableRCFeedFormatter' => 'includes/rcfeed/MachineReadableRCFeedFormatter.php',
# includes/resourceloader
+ 'DerivativeResourceLoaderContext' =>
+ 'includes/resourceloader/DerivativeResourceLoaderContext.php',
'ResourceLoader' => 'includes/resourceloader/ResourceLoader.php',
'ResourceLoaderContext' => 'includes/resourceloader/ResourceLoaderContext.php',
+ 'ResourceLoaderEditToolbarModule' => 'includes/resourceloader/ResourceLoaderEditToolbarModule.php',
'ResourceLoaderFileModule' => 'includes/resourceloader/ResourceLoaderFileModule.php',
'ResourceLoaderFilePageModule' => 'includes/resourceloader/ResourceLoaderFilePageModule.php',
- 'ResourceLoaderLESSFunctions' => 'includes/resourceloader/ResourceLoaderLESSFunctions.php',
+ 'ResourceLoaderFilePath' => 'includes/resourceloader/ResourceLoaderFilePath.php',
'ResourceLoaderModule' => 'includes/resourceloader/ResourceLoaderModule.php',
'ResourceLoaderNoscriptModule' => 'includes/resourceloader/ResourceLoaderNoscriptModule.php',
'ResourceLoaderSiteModule' => 'includes/resourceloader/ResourceLoaderSiteModule.php',
'ResourceLoaderStartUpModule' => 'includes/resourceloader/ResourceLoaderStartUpModule.php',
- 'ResourceLoaderUserCSSPrefsModule' => 'includes/resourceloader/ResourceLoaderUserCSSPrefsModule.php',
+ 'ResourceLoaderUserCSSPrefsModule' =>
+ 'includes/resourceloader/ResourceLoaderUserCSSPrefsModule.php',
'ResourceLoaderUserGroupsModule' => 'includes/resourceloader/ResourceLoaderUserGroupsModule.php',
'ResourceLoaderUserModule' => 'includes/resourceloader/ResourceLoaderUserModule.php',
'ResourceLoaderUserOptionsModule' => 'includes/resourceloader/ResourceLoaderUserOptionsModule.php',
'ResourceLoaderUserTokensModule' => 'includes/resourceloader/ResourceLoaderUserTokensModule.php',
- 'ResourceLoaderLanguageDataModule' => 'includes/resourceloader/ResourceLoaderLanguageDataModule.php',
+ 'ResourceLoaderLanguageDataModule' =>
+ 'includes/resourceloader/ResourceLoaderLanguageDataModule.php',
+ 'ResourceLoaderLanguageNamesModule' =>
+ 'includes/resourceloader/ResourceLoaderLanguageNamesModule.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',
- 'RevDel_FileList' => 'includes/revisiondelete/RevisionDelete.php',
- 'RevDel_Item' => 'includes/revisiondelete/RevisionDeleteAbstracts.php',
- 'RevDel_List' => 'includes/revisiondelete/RevisionDeleteAbstracts.php',
- 'RevDel_LogItem' => 'includes/revisiondelete/RevisionDelete.php',
- 'RevDel_LogList' => 'includes/revisiondelete/RevisionDelete.php',
- 'RevDel_RevisionItem' => 'includes/revisiondelete/RevisionDelete.php',
- 'RevDel_RevisionList' => 'includes/revisiondelete/RevisionDelete.php',
+ 'RevDelArchivedFileItem' => 'includes/revisiondelete/RevDelArchivedFileItem.php',
+ 'RevDelArchivedFileList' => 'includes/revisiondelete/RevDelArchivedFileList.php',
+ 'RevDelArchivedRevisionItem' => 'includes/revisiondelete/RevDelArchivedRevisionItem.php',
+ 'RevDelArchiveItem' => 'includes/revisiondelete/RevDelArchiveItem.php',
+ 'RevDelArchiveList' => 'includes/revisiondelete/RevDelArchiveList.php',
+ 'RevDelFileItem' => 'includes/revisiondelete/RevDelFileItem.php',
+ 'RevDelFileList' => 'includes/revisiondelete/RevDelFileList.php',
+ 'RevDelItem' => 'includes/revisiondelete/RevDelItem.php',
+ 'RevDelList' => 'includes/revisiondelete/RevDelList.php',
+ 'RevDelLogItem' => 'includes/revisiondelete/RevDelLogItem.php',
+ 'RevDelLogList' => 'includes/revisiondelete/RevDelLogList.php',
+ 'RevDelRevisionItem' => 'includes/revisiondelete/RevDelRevisionItem.php',
+ 'RevDelRevisionList' => 'includes/revisiondelete/RevDelRevisionList.php',
'RevisionDeleter' => 'includes/revisiondelete/RevisionDeleter.php',
'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',
+ 'SearchDatabase' => 'includes/search/SearchDatabase.php',
'SearchEngine' => 'includes/search/SearchEngine.php',
'SearchEngineDummy' => 'includes/search/SearchEngine.php',
- 'SearchHighlighter' => 'includes/search/SearchEngine.php',
+ 'SearchHighlighter' => 'includes/search/SearchHighlighter.php',
'SearchMssql' => 'includes/search/SearchMssql.php',
'SearchMySQL' => 'includes/search/SearchMySQL.php',
- 'SearchNearMatchResultSet' => 'includes/search/SearchEngine.php',
+ 'SearchNearMatchResultSet' => 'includes/search/SearchResultSet.php',
'SearchOracle' => 'includes/search/SearchOracle.php',
'SearchPostgres' => 'includes/search/SearchPostgres.php',
- 'SearchResult' => 'includes/search/SearchEngine.php',
- 'SearchResultSet' => 'includes/search/SearchEngine.php',
- 'SearchResultTooMany' => 'includes/search/SearchEngine.php',
+ 'SearchResult' => 'includes/search/SearchResult.php',
+ 'SearchResultSet' => 'includes/search/SearchResultSet.php',
'SearchSqlite' => 'includes/search/SearchSqlite.php',
- 'SearchUpdate' => 'includes/search/SearchUpdate.php',
- 'SqliteSearchResultSet' => 'includes/search/SearchSqlite.php',
- 'SqlSearchResultSet' => 'includes/search/SearchEngine.php',
+ 'SqlSearchResultSet' => 'includes/search/SearchResultSet.php',
# includes/site
'MediaWikiSite' => 'includes/site/MediaWikiSite.php',
@@ -923,9 +944,35 @@ $wgAutoloadLocalClasses = array(
'Sites' => 'includes/site/SiteSQLStore.php',
'SiteStore' => 'includes/site/SiteStore.php',
+ # includes/skins
+ 'BaseTemplate' => 'includes/skins/SkinTemplate.php',
+ 'MediaWikiI18N' => 'includes/skins/SkinTemplate.php',
+ 'QuickTemplate' => 'includes/skins/SkinTemplate.php',
+ 'Skin' => 'includes/skins/Skin.php',
+ 'SkinException' => 'includes/skins/SkinException.php',
+ 'SkinFactory' => 'includes/skins/SkinFactory.php',
+ 'SkinFallback' => 'includes/skins/SkinFallback.php',
+ 'SkinFallbackTemplate' => 'includes/skins/SkinFallbackTemplate.php',
+ 'SkinTemplate' => 'includes/skins/SkinTemplate.php',
+
+ # includes/specialpage
+ 'ChangesListSpecialPage' => 'includes/specialpage/ChangesListSpecialPage.php',
+ 'FormSpecialPage' => 'includes/specialpage/FormSpecialPage.php',
+ 'ImageQueryPage' => 'includes/specialpage/ImageQueryPage.php',
+ 'IncludableSpecialPage' => 'includes/specialpage/IncludableSpecialPage.php',
+ 'PageQueryPage' => 'includes/specialpage/PageQueryPage.php',
+ 'QueryPage' => 'includes/specialpage/QueryPage.php',
+ 'RedirectSpecialArticle' => 'includes/specialpage/RedirectSpecialPage.php',
+ 'RedirectSpecialPage' => 'includes/specialpage/RedirectSpecialPage.php',
+ 'SpecialPage' => 'includes/specialpage/SpecialPage.php',
+ 'SpecialPageFactory' => 'includes/specialpage/SpecialPageFactory.php',
+ 'SpecialRedirectToSpecial' => 'includes/specialpage/RedirectSpecialPage.php',
+ 'UnlistedSpecialPage' => 'includes/specialpage/UnlistedSpecialPage.php',
+ 'WantedQueryPage' => 'includes/specialpage/WantedQueryPage.php',
+
# includes/specials
'ActiveUsersPager' => 'includes/specials/SpecialActiveusers.php',
- 'AllmessagesTablePager' => 'includes/specials/SpecialAllmessages.php',
+ 'AllMessagesTablePager' => 'includes/specials/SpecialAllMessages.php',
'AncientPagesPage' => 'includes/specials/SpecialAncientpages.php',
'BlockListPager' => 'includes/specials/SpecialBlockList.php',
'BrokenRedirectsPage' => 'includes/specials/SpecialBrokenRedirects.php',
@@ -941,15 +988,15 @@ $wgAutoloadLocalClasses = array(
'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',
'ListredirectsPage' => 'includes/specials/SpecialListredirects.php',
+ 'ListDuplicatedFilesPage' => 'includes/specials/SpecialListDuplicatedFiles.php',
'LoginForm' => 'includes/specials/SpecialUserlogin.php',
'LonelyPagesPage' => 'includes/specials/SpecialLonelypages.php',
'LongPagesPage' => 'includes/specials/SpecialLongpages.php',
+ 'MediaStatisticsPage' => 'includes/specials/SpecialMediaStatistics.php',
'MergeHistoryPager' => 'includes/specials/SpecialMergeHistory.php',
'MIMEsearchPage' => 'includes/specials/SpecialMIMEsearch.php',
'MostcategoriesPage' => 'includes/specials/SpecialMostcategories.php',
@@ -969,8 +1016,9 @@ $wgAutoloadLocalClasses = array(
'RandomPage' => 'includes/specials/SpecialRandompage.php',
'ShortPagesPage' => 'includes/specials/SpecialShortpages.php',
'SpecialActiveUsers' => 'includes/specials/SpecialActiveusers.php',
- 'SpecialAllmessages' => 'includes/specials/SpecialAllmessages.php',
- 'SpecialAllpages' => 'includes/specials/SpecialAllpages.php',
+ 'SpecialAllMessages' => 'includes/specials/SpecialAllMessages.php',
+ 'SpecialAllMyUploads' => 'includes/specials/SpecialMyRedirectPages.php',
+ 'SpecialAllPages' => 'includes/specials/SpecialAllPages.php',
'SpecialBlankpage' => 'includes/specials/SpecialBlankpage.php',
'SpecialBlock' => 'includes/specials/SpecialBlock.php',
'SpecialBlockList' => 'includes/specials/SpecialBlockList.php',
@@ -981,23 +1029,34 @@ $wgAutoloadLocalClasses = array(
'SpecialChangePassword' => 'includes/specials/SpecialChangePassword.php',
'SpecialComparePages' => 'includes/specials/SpecialComparePages.php',
'SpecialContributions' => 'includes/specials/SpecialContributions.php',
+ 'SpecialCreateAccount' => 'includes/specials/SpecialCreateAccount.php',
+ 'SpecialDiff' => 'includes/specials/SpecialDiff.php',
'SpecialEditWatchlist' => 'includes/specials/SpecialEditWatchlist.php',
'SpecialEmailUser' => 'includes/specials/SpecialEmailuser.php',
+ 'SpecialExpandTemplates' => 'includes/specials/SpecialExpandTemplates.php',
'SpecialExport' => 'includes/specials/SpecialExport.php',
'SpecialFilepath' => 'includes/specials/SpecialFilepath.php',
'SpecialImport' => 'includes/specials/SpecialImport.php',
'SpecialJavaScriptTest' => 'includes/specials/SpecialJavaScriptTest.php',
+ 'SpecialListAdmins' => 'includes/specials/SpecialListusers.php',
+ 'SpecialListBots' => 'includes/specials/SpecialListusers.php',
'SpecialListFiles' => 'includes/specials/SpecialListfiles.php',
'SpecialListGroupRights' => 'includes/specials/SpecialListgrouprights.php',
'SpecialListUsers' => 'includes/specials/SpecialListusers.php',
'SpecialLockdb' => 'includes/specials/SpecialLockdb.php',
'SpecialLog' => 'includes/specials/SpecialLog.php',
'SpecialMergeHistory' => 'includes/specials/SpecialMergeHistory.php',
+ 'SpecialMycontributions' => 'includes/specials/SpecialMyRedirectPages.php',
+ 'SpecialMyLanguage' => 'includes/specials/SpecialMyLanguage.php',
+ 'SpecialMypage' => 'includes/specials/SpecialMyRedirectPages.php',
+ 'SpecialMytalk' => 'includes/specials/SpecialMyRedirectPages.php',
+ 'SpecialMyuploads' => 'includes/specials/SpecialMyRedirectPages.php',
'SpecialNewFiles' => 'includes/specials/SpecialNewimages.php',
'SpecialNewpages' => 'includes/specials/SpecialNewpages.php',
+ 'SpecialPageLanguage' => 'includes/specials/SpecialPageLanguage.php',
'SpecialPasswordReset' => 'includes/specials/SpecialPasswordReset.php',
'SpecialPagesWithProp' => 'includes/specials/SpecialPagesWithProp.php',
- 'SpecialPermanentLink' => 'includes/SpecialPage.php',
+ 'SpecialPermanentLink' => 'includes/specials/SpecialPermanentLink.php',
'SpecialPreferences' => 'includes/specials/SpecialPreferences.php',
'SpecialPrefixindex' => 'includes/specials/SpecialPrefixindex.php',
'SpecialProtectedpages' => 'includes/specials/SpecialProtectedpages.php',
@@ -1005,14 +1064,16 @@ $wgAutoloadLocalClasses = array(
'SpecialRandomInCategory' => 'includes/specials/SpecialRandomInCategory.php',
'SpecialRandomredirect' => 'includes/specials/SpecialRandomredirect.php',
'SpecialRecentChanges' => 'includes/specials/SpecialRecentchanges.php',
- 'SpecialRecentchangeslinked' => 'includes/specials/SpecialRecentchangeslinked.php',
+ 'SpecialRecentChangesLinked' => 'includes/specials/SpecialRecentchangeslinked.php',
'SpecialRedirect' => 'includes/specials/SpecialRedirect.php',
'SpecialResetTokens' => 'includes/specials/SpecialResetTokens.php',
'SpecialRevisionDelete' => 'includes/specials/SpecialRevisiondelete.php',
+ 'SpecialRunJobs' => 'includes/specials/SpecialRunJobs.php',
'SpecialSearch' => 'includes/specials/SpecialSearch.php',
'SpecialSpecialpages' => 'includes/specials/SpecialSpecialpages.php',
'SpecialStatistics' => 'includes/specials/SpecialStatistics.php',
'SpecialTags' => 'includes/specials/SpecialTags.php',
+ 'SpecialTrackingCategories' => 'includes/specials/SpecialTrackingCategories.php',
'SpecialUnblock' => 'includes/specials/SpecialUnblock.php',
'SpecialUndelete' => 'includes/specials/SpecialUndelete.php',
'SpecialUnlockdb' => 'includes/specials/SpecialUnlockdb.php',
@@ -1042,13 +1103,21 @@ $wgAutoloadLocalClasses = array(
'WantedFilesPage' => 'includes/specials/SpecialWantedfiles.php',
'WantedPagesPage' => 'includes/specials/SpecialWantedpages.php',
'WantedTemplatesPage' => 'includes/specials/SpecialWantedtemplates.php',
- 'WatchlistEditor' => 'includes/specials/SpecialEditWatchlist.php',
'WithoutInterwikiPage' => 'includes/specials/SpecialWithoutinterwiki.php',
# includes/templates
'UserloginTemplate' => 'includes/templates/Userlogin.php',
'UsercreateTemplate' => 'includes/templates/Usercreate.php',
+ # includes/title
+ 'PageLinkRenderer' => 'includes/title/PageLinkRenderer.php',
+ 'TitleFormatter' => 'includes/title/TitleFormatter.php',
+ 'TitleParser' => 'includes/title/TitleParser.php',
+ 'TitleValue' => 'includes/title/TitleValue.php',
+ 'MalformedTitleException' => 'includes/title/MalformedTitleException.php',
+ 'MediaWikiPageLinkRenderer' => 'includes/title/MediaWikiPageLinkRenderer.php',
+ 'MediaWikiTitleCodec' => 'includes/title/MediaWikiTitleCodec.php',
+
# includes/upload
'UploadBase' => 'includes/upload/UploadBase.php',
'UploadFromFile' => 'includes/upload/UploadFromFile.php',
@@ -1067,18 +1136,43 @@ $wgAutoloadLocalClasses = array(
'UploadStashWrongOwnerException' => 'includes/upload/UploadStash.php',
'UploadStashNoSuchKeyException' => 'includes/upload/UploadStash.php',
+ # includes/utils
+ 'ArrayUtils' => 'includes/utils/ArrayUtils.php',
+ 'CdbException' => 'includes/utils/Cdb.php',
+ 'CdbFunctions' => 'includes/utils/CdbPHP.php',
+ 'CdbReader' => 'includes/utils/Cdb.php',
+ 'CdbReaderDBA' => 'includes/utils/CdbDBA.php',
+ 'CdbReaderPHP' => 'includes/utils/CdbPHP.php',
+ 'CdbWriter' => 'includes/utils/Cdb.php',
+ 'CdbWriterDBA' => 'includes/utils/CdbDBA.php',
+ 'CdbWriterPHP' => 'includes/utils/CdbPHP.php',
+ 'DoubleReplacer' => 'includes/utils/StringUtils.php',
+ 'ExplodeIterator' => 'includes/utils/StringUtils.php',
+ 'HashtableReplacer' => 'includes/utils/StringUtils.php',
+ 'IP' => 'includes/utils/IP.php',
+ 'MWCryptRand' => 'includes/utils/MWCryptRand.php',
+ 'MWCryptHKDF' => 'includes/utils/MWCryptHKDF.php',
+ 'MWFunction' => 'includes/utils/MWFunction.php',
+ 'RegexlikeReplacer' => 'includes/utils/StringUtils.php',
+ 'ReplacementArray' => 'includes/utils/StringUtils.php',
+ 'Replacer' => 'includes/utils/StringUtils.php',
+ 'StringUtils' => 'includes/utils/StringUtils.php',
+ 'UIDGenerator' => 'includes/utils/UIDGenerator.php',
+ 'ZipDirectoryReader' => 'includes/utils/ZipDirectoryReader.php',
+ 'ZipDirectoryReaderError' => 'includes/utils/ZipDirectoryReader.php',
+
# languages
- 'ConverterRule' => 'languages/LanguageConverter.php',
- 'FakeConverter' => 'languages/Language.php',
+ 'ConverterRule' => 'languages/ConverterRule.php',
+ 'FakeConverter' => 'languages/FakeConverter.php',
'Language' => 'languages/Language.php',
'LanguageConverter' => 'languages/LanguageConverter.php',
- 'CLDRPluralRuleConverter' => 'languages/utils/CLDRPluralRuleEvaluator.php',
- 'CLDRPluralRuleConverter_Expression' => 'languages/utils/CLDRPluralRuleEvaluator.php',
- 'CLDRPluralRuleConverter_Fragment' => 'languages/utils/CLDRPluralRuleEvaluator.php',
- 'CLDRPluralRuleConverter_Operator' => 'languages/utils/CLDRPluralRuleEvaluator.php',
+ 'CLDRPluralRuleConverter' => 'languages/utils/CLDRPluralRuleConverter.php',
+ 'CLDRPluralRuleConverterExpression' => 'languages/utils/CLDRPluralRuleConverterExpression.php',
+ 'CLDRPluralRuleConverterFragment' => 'languages/utils/CLDRPluralRuleConverterFragment.php',
+ 'CLDRPluralRuleConverterOperator' => 'languages/utils/CLDRPluralRuleConverterOperator.php',
'CLDRPluralRuleEvaluator' => 'languages/utils/CLDRPluralRuleEvaluator.php',
- 'CLDRPluralRuleEvaluator_Range' => 'languages/utils/CLDRPluralRuleEvaluator.php',
- 'CLDRPluralRuleError' => 'languages/utils/CLDRPluralRuleEvaluator.php',
+ 'CLDRPluralRuleEvaluatorRange' => 'languages/utils/CLDRPluralRuleEvaluatorRange.php',
+ 'CLDRPluralRuleError' => 'languages/utils/CLDRPluralRuleError.php',
# maintenance
'BackupDumper' => 'maintenance/backup.inc',
@@ -1092,6 +1186,7 @@ $wgAutoloadLocalClasses = array(
'FixExtLinksProtocolRelative' => 'maintenance/fixExtLinksProtocolRelative.php',
'LoggedUpdateMaintenance' => 'maintenance/Maintenance.php',
'Maintenance' => 'maintenance/Maintenance.php',
+ 'PopulateBacklinkNamespace' => 'maintenance/populateBacklinkNamespace.php',
'PopulateCategory' => 'maintenance/populateCategory.php',
'PopulateImageSha1' => 'maintenance/populateImageSha1.php',
'PopulateFilearchiveSha1' => 'maintenance/populateFilearchiveSha1.php',
@@ -1108,13 +1203,12 @@ $wgAutoloadLocalClasses = array(
'UserDupes' => 'maintenance/userDupes.inc',
# 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',
- 'textStatsOutput' => 'maintenance/language/StatOutputs.php',
- 'wikiStatsOutput' => 'maintenance/language/StatOutputs.php',
+ 'CsvStatsOutput' => 'maintenance/language/StatOutputs.php',
+ 'ExtensionLanguages' => 'maintenance/language/languages.inc',
+ 'Languages' => 'maintenance/language/languages.inc',
+ 'StatsOutput' => 'maintenance/language/StatOutputs.php',
+ 'TextStatsOutput' => 'maintenance/language/StatOutputs.php',
+ 'WikiStatsOutput' => 'maintenance/language/StatOutputs.php',
# maintenance/term
'AnsiTermColorer' => 'maintenance/term/MWTerm.php',
@@ -1123,29 +1217,19 @@ $wgAutoloadLocalClasses = array(
# mw-config
'InstallerOverrides' => 'mw-config/overrides.php',
'MyLocalSettingsGenerator' => 'mw-config/overrides.php',
-
- # skins
- 'CologneBlueTemplate' => 'skins/CologneBlue.php',
- 'ModernTemplate' => 'skins/Modern.php',
- 'MonoBookTemplate' => 'skins/MonoBook.php',
- 'SkinCologneBlue' => 'skins/CologneBlue.php',
- 'SkinModern' => 'skins/Modern.php',
- 'SkinMonoBook' => 'skins/MonoBook.php',
- 'SkinVector' => 'skins/Vector.php',
- 'VectorTemplate' => 'skins/Vector.php',
);
class AutoLoader {
+ static protected $autoloadLocalClassesLower = null;
+
/**
* autoload - take a class name and attempt to load it
*
- * @param string $className name of class we're looking for.
- * @return bool Returning false is important on failure as
- * it allows Zend to try and look in other registered autoloaders
- * as well.
+ * @param string $className Name of class we're looking for.
*/
static function autoload( $className ) {
- global $wgAutoloadClasses, $wgAutoloadLocalClasses;
+ global $wgAutoloadClasses, $wgAutoloadLocalClasses,
+ $wgAutoloadAttemptLowercase;
// 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,
@@ -1156,41 +1240,46 @@ class AutoLoader {
// do not strip the leading backlash in this case, causing autoloading to fail.
$className = ltrim( $className, '\\' );
+ $filename = false;
+
if ( isset( $wgAutoloadLocalClasses[$className] ) ) {
$filename = $wgAutoloadLocalClasses[$className];
} elseif ( isset( $wgAutoloadClasses[$className] ) ) {
$filename = $wgAutoloadClasses[$className];
- } else {
- # Try a different capitalisation
- # The case can sometimes be wrong when unserializing PHP 4 objects
- $filename = false;
+ } elseif ( $wgAutoloadAttemptLowercase ) {
+ /*
+ * Try a different capitalisation.
+ *
+ * PHP 4 objects are always serialized with the classname coerced to lowercase,
+ * and we are plagued with several legacy uses created by MediaWiki < 1.5, see
+ * https://wikitech.wikimedia.org/wiki/Text_storage_data
+ */
$lowerClass = strtolower( $className );
- foreach ( $wgAutoloadLocalClasses as $class2 => $file2 ) {
- if ( strtolower( $class2 ) == $lowerClass ) {
- $filename = $file2;
- }
+ if ( self::$autoloadLocalClassesLower === null ) {
+ self::$autoloadLocalClassesLower = array_change_key_case( $wgAutoloadLocalClasses, CASE_LOWER );
}
- if ( !$filename ) {
- if ( function_exists( 'wfDebug' ) ) {
- wfDebug( "Class {$className} not found; skipped loading\n" );
+ if ( isset( self::$autoloadLocalClassesLower[$lowerClass] ) ) {
+ if ( function_exists( 'wfDebugLog' ) ) {
+ wfDebugLog( 'autoloader', "Class {$className} was loaded using incorrect case" );
}
-
- # Give up
- return false;
+ $filename = self::$autoloadLocalClassesLower[$lowerClass];
}
}
- # Make an absolute path, this improves performance by avoiding some stat calls
+ if ( !$filename ) {
+ // Class not found; let the next autoloader try to find it
+ return;
+ }
+
+ // Make an absolute path, this improves performance by avoiding some stat calls
if ( substr( $filename, 0, 1 ) != '/' && substr( $filename, 1, 1 ) != ':' ) {
global $IP;
$filename = "$IP/$filename";
}
require $filename;
-
- return true;
}
/**
@@ -1198,12 +1287,20 @@ 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
+ * @param string $class
+ * @return bool Return the results of class_exists() so we know if we were successful
*/
static function loadClass( $class ) {
return class_exists( $class );
}
+
+ /**
+ * Method to clear the protected class property $autoloadLocalClassesLower.
+ * Used in tests.
+ */
+ static function resetAutoloadLocalClassesLower() {
+ self::$autoloadLocalClassesLower = null;
+ }
}
spl_autoload_register( array( 'AutoLoader', 'autoload' ) );
diff --git a/includes/Autopromote.php b/includes/Autopromote.php
index 170d7abf..81f3b7aa 100644
--- a/includes/Autopromote.php
+++ b/includes/Autopromote.php
@@ -29,7 +29,7 @@ class Autopromote {
/**
* Get the groups for the given user based on $wgAutopromote.
*
- * @param $user User The user to get the groups for
+ * @param User $user The user to get the groups for
* @return array Array of groups to promote to.
*/
public static function getAutopromoteGroups( User $user ) {
@@ -53,8 +53,8 @@ class Autopromote {
*
* Does not return groups the user already belongs to or has once belonged.
*
- * @param $user User The user to get the groups for
- * @param string $event key in $wgAutopromoteOnce (each one has groups/criteria)
+ * @param User $user The user to get the groups for
+ * @param string $event Key in $wgAutopromoteOnce (each one has groups/criteria)
*
* @return array Groups the user should be promoted to.
*
@@ -99,8 +99,8 @@ class Autopromote {
* This function evaluates the former type recursively, and passes off to
* self::checkCondition for evaluation of the latter type.
*
- * @param $cond Mixed: a condition, possibly containing other conditions
- * @param $user User The user to check the conditions against
+ * @param mixed $cond A condition, possibly containing other conditions
+ * @param User $user The user to check the conditions against
* @return bool Whether the condition is true
*/
private static function recCheckCondition( $cond, User $user ) {
@@ -156,7 +156,7 @@ class Autopromote {
* APCOND_AGE. Other types will throw an exception if no extension evaluates them.
*
* @param array $cond A condition, which must not contain other conditions
- * @param $user User The user to check the condition against
+ * @param User $user The user to check the condition against
* @throws MWException
* @return bool Whether the condition is true for the user
*/
@@ -197,7 +197,8 @@ class Autopromote {
return in_array( 'bot', User::getGroupPermissions( $user->getGroups() ) );
default:
$result = null;
- wfRunHooks( 'AutopromoteCondition', array( $cond[0], array_slice( $cond, 1 ), $user, &$result ) );
+ wfRunHooks( 'AutopromoteCondition', array( $cond[0],
+ array_slice( $cond, 1 ), $user, &$result ) );
if ( $result === null ) {
throw new MWException( "Unrecognized condition {$cond[0]} for autopromotion!" );
}
diff --git a/includes/Block.php b/includes/Block.php
index 34b89e73..6a29a056 100644
--- a/includes/Block.php
+++ b/includes/Block.php
@@ -20,33 +20,54 @@
* @file
*/
class Block {
- /* public*/ var $mReason, $mTimestamp, $mAuto, $mExpiry, $mHideName;
+ /** @var string */
+ public $mReason;
- protected
- $mId,
- $mFromMaster,
+ /** @var bool|string */
+ public $mTimestamp;
- $mBlockEmail,
- $mDisableUsertalk,
- $mCreateAccount,
- $mParentBlockId;
+ /** @var int */
+ public $mAuto;
- /// @var User|String
+ /** @var bool|string */
+ public $mExpiry;
+
+ public $mHideName;
+
+ /** @var int */
+ public $mParentBlockId;
+
+ /** @var int */
+ protected $mId;
+
+ /** @var bool */
+ protected $mFromMaster;
+
+ /** @var bool */
+ protected $mBlockEmail;
+
+ /** @var bool */
+ protected $mDisableUsertalk;
+
+ /** @var bool */
+ protected $mCreateAccount;
+
+ /** @var User|string */
protected $target;
- // @var Integer Hack for foreign blocking (CentralAuth)
+ /** @var int Hack for foreign blocking (CentralAuth) */
protected $forcedTargetID;
- /// @var Block::TYPE_ constant. Can only be USER, IP or RANGE internally
+ /** @var int Block::TYPE_ constant. Can only be USER, IP or RANGE internally */
protected $type;
- /// @var User
+ /** @var User */
protected $blocker;
- /// @var Bool
+ /** @var bool */
protected $isHardblock = true;
- /// @var Bool
+ /** @var bool */
protected $isAutoblocking = true;
# TYPE constants
@@ -57,14 +78,27 @@ class Block {
const TYPE_ID = 5;
/**
- * Constructor
- * @todo FIXME: Don't know what the best format to have for this constructor is, but fourteen
- * optional parameters certainly isn't it.
+ * @todo FIXME: Don't know what the best format to have for this constructor
+ * is, but fourteen optional parameters certainly isn't it.
+ * @param string $address
+ * @param int $user
+ * @param int $by
+ * @param string $reason
+ * @param mixed $timestamp
+ * @param int $auto
+ * @param string $expiry
+ * @param int $anonOnly
+ * @param int $createAccount
+ * @param int $enableAutoblock
+ * @param int $hideName
+ * @param int $blockEmail
+ * @param int $allowUsertalk
+ * @param string $byText
*/
function __construct( $address = '', $user = 0, $by = 0, $reason = '',
$timestamp = 0, $auto = 0, $expiry = '', $anonOnly = 0, $createAccount = 0, $enableAutoblock = 0,
- $hideName = 0, $blockEmail = 0, $allowUsertalk = 0, $byText = '' )
- {
+ $hideName = 0, $blockEmail = 0, $allowUsertalk = 0, $byText = ''
+ ) {
if ( $timestamp === 0 ) {
$timestamp = wfTimestampNow();
}
@@ -102,25 +136,10 @@ class Block {
}
/**
- * Load a block from the database, using either the IP address or
- * user ID. Tries the user ID first, and if that doesn't work, tries
- * the address.
- *
- * @param string $address IP address of user/anon
- * @param $user Integer: user id of user
- * @return Block Object
- * @deprecated since 1.18
- */
- public static function newFromDB( $address, $user = 0 ) {
- wfDeprecated( __METHOD__, '1.18' );
- return self::newFromTarget( User::whoIs( $user ), $address );
- }
-
- /**
* Load a blocked user from their block id.
*
- * @param $id Integer: Block id to search for
- * @return Block object or null
+ * @param int $id Block id to search for
+ * @return Block|null
*/
public static function newFromID( $id ) {
$dbr = wfGetDB( DB_SLAVE );
@@ -166,7 +185,7 @@ class Block {
* 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
*
- * @param $block Block
+ * @param Block $block
*
* @return bool
*/
@@ -187,52 +206,14 @@ class Block {
}
/**
- * Clear all member variables in the current object. Does not clear
- * the block from the DB.
- * @deprecated since 1.18
- */
- public function clear() {
- wfDeprecated( __METHOD__, '1.18' );
- # Noop
- }
-
- /**
- * Get a block from the DB, with either the given address or the given username
- *
- * @param string $address The IP address of the user, or blank to skip IP blocks
- * @param int $user The user ID, or zero for anonymous users
- * @return Boolean: the user is blocked from editing
- * @deprecated since 1.18
- */
- public function load( $address = '', $user = 0 ) {
- wfDeprecated( __METHOD__, '1.18' );
- if ( $user ) {
- $username = User::whoIs( $user );
- $block = self::newFromTarget( $username, $address );
- } else {
- $block = self::newFromTarget( null, $address );
- }
-
- if ( $block instanceof Block ) {
- # This is mildly evil, but hey, it's B/C :D
- foreach ( $block as $variable => $value ) {
- $this->$variable = $value;
- }
- return true;
- } else {
- return false;
- }
- }
-
- /**
* Load a block from the database which affects the already-set $this->target:
* 1) A block directly on the given user or IP
* 2) A rangeblock encompassing the given IP (smallest first)
* 3) An autoblock on the given IP
- * @param $vagueTarget User|String also search for blocks affecting this target. Doesn't
+ * @param User|string $vagueTarget Also search for blocks affecting this target. Doesn't
* make any sense to use TYPE_AUTO / TYPE_ID here. Leave blank to skip IP lookups.
* @throws MWException
- * @return Bool whether a relevant block was found
+ * @return bool Whether a relevant block was found
*/
protected function newLoad( $vagueTarget = null ) {
$db = wfGetDB( $this->mFromMaster ? DB_MASTER : DB_SLAVE );
@@ -333,7 +314,7 @@ class Block {
* Get a set of SQL conditions which will select rangeblocks encompassing a given range
* @param string $start Hexadecimal IP representation
* @param string $end Hexadecimal IP representation, or null to use $start = $end
- * @return String
+ * @return string
*/
public static function getRangeCond( $start, $end = null ) {
if ( $end === null ) {
@@ -365,8 +346,8 @@ class Block {
/**
* Get the component of an IP address which is certain to be the same between an IP
* address and a rangeblock containing that IP address.
- * @param $hex String Hexadecimal IP representation
- * @return String
+ * @param string $hex Hexadecimal IP representation
+ * @return string
*/
protected static function getIpFragment( $hex ) {
global $wgBlockCIDRLimit;
@@ -380,7 +361,7 @@ class Block {
/**
* Given a database row from the ipblocks table, initialize
* member variables
- * @param $row ResultWrapper: a row from the ipblocks table
+ * @param stdClass $row A row from the ipblocks table
*/
protected function initFromRow( $row ) {
$this->setTarget( $row->ipb_address );
@@ -415,7 +396,7 @@ class Block {
/**
* Create a new Block object from a database row
- * @param $row ResultWrapper row from the ipblocks table
+ * @param stdClass $row Row from the ipblocks table
* @return Block
*/
public static function newFromRow( $row ) {
@@ -428,7 +409,7 @@ class Block {
* Delete the row from the IP blocks table.
*
* @throws MWException
- * @return Boolean
+ * @return bool
*/
public function delete() {
if ( wfReadOnly() ) {
@@ -450,8 +431,8 @@ class Block {
* Insert a block into the block table. Will fail if there is a conflicting
* block (same name and options) already in the database.
*
- * @param $dbw DatabaseBase if you have one available
- * @return mixed: false on failure, assoc array on success:
+ * @param DatabaseBase $dbw If you have one available
+ * @return bool|array False on failure, assoc array on success:
* ('id' => block ID, 'autoIds' => array of autoblock IDs)
*/
public function insert( $dbw = null ) {
@@ -488,13 +469,15 @@ class Block {
* Update a block in the DB with new parameters.
* The ID field needs to be loaded first.
*
- * @return Int number of affected rows, which should probably be 1 or something has
- * gone slightly awry
+ * @return bool|array False on failure, array on success:
+ * ('id' => block ID, 'autoIds' => array of autoblock IDs)
*/
public function update() {
wfDebug( "Block::update; timestamp {$this->mTimestamp}\n" );
$dbw = wfGetDB( DB_MASTER );
+ $dbw->startAtomic( __METHOD__ );
+
$dbw->update(
'ipblocks',
$this->getDatabaseArray( $dbw ),
@@ -502,13 +485,39 @@ class Block {
__METHOD__
);
- return $dbw->affectedRows();
+ $affected = $dbw->affectedRows();
+
+ if ( $this->isAutoblocking() ) {
+ // update corresponding autoblock(s) (bug 48813)
+ $dbw->update(
+ 'ipblocks',
+ $this->getAutoblockUpdateArray(),
+ array( 'ipb_parent_block_id' => $this->getId() ),
+ __METHOD__
+ );
+ } else {
+ // autoblock no longer required, delete corresponding autoblock(s)
+ $dbw->delete(
+ 'ipblocks',
+ array( 'ipb_parent_block_id' => $this->getId() ),
+ __METHOD__
+ );
+ }
+
+ $dbw->endAtomic( __METHOD__ );
+
+ if ( $affected ) {
+ $auto_ipd_ids = $this->doRetroactiveAutoblock();
+ return array( 'id' => $this->mId, 'autoIds' => $auto_ipd_ids );
+ }
+
+ return false;
}
/**
* Get an array suitable for passing to $dbw->insert() or $dbw->update()
- * @param $db DatabaseBase
- * @return Array
+ * @param DatabaseBase $db
+ * @return array
*/
protected function getDatabaseArray( $db = null ) {
if ( !$db ) {
@@ -546,10 +555,24 @@ class Block {
}
/**
+ * @return array
+ */
+ protected function getAutoblockUpdateArray() {
+ return array(
+ 'ipb_by' => $this->getBy(),
+ 'ipb_by_text' => $this->getByName(),
+ 'ipb_reason' => $this->mReason,
+ 'ipb_create_account' => $this->prevents( 'createaccount' ),
+ 'ipb_deleted' => (int)$this->mHideName, // typecast required for SQLite
+ 'ipb_allow_usertalk' => !$this->prevents( 'editownusertalk' ),
+ );
+ }
+
+ /**
* Retroactively autoblocks the last IP used by the user (if it is a user)
* blocked by this Block.
*
- * @return Array: block IDs of retroactive autoblocks made
+ * @return array Block IDs of retroactive autoblocks made
*/
protected function doRetroactiveAutoblock() {
$blockIds = array();
@@ -573,7 +596,6 @@ class Block {
*
* @param Block $block
* @param array &$blockIds
- * @return Array: block IDs of retroactive autoblocks made
*/
protected static function defaultRetroactiveAutoblock( Block $block, array &$blockIds ) {
global $wgPutIPinRC;
@@ -614,7 +636,7 @@ class Block {
* TODO: this probably belongs somewhere else, but not sure where...
*
* @param string $ip The IP to check
- * @return Boolean
+ * @return bool
*/
public static function isWhitelistedFromAutoblocks( $ip ) {
global $wgMemc;
@@ -656,8 +678,8 @@ class Block {
/**
* Autoblocks the given IP, referring to this Block.
*
- * @param string $autoblockIP the IP to autoblock.
- * @return mixed: block ID if an autoblock was inserted, false if not.
+ * @param string $autoblockIP The IP to autoblock.
+ * @return int|bool Block ID if an autoblock was inserted, false if not.
*/
public function doAutoblock( $autoblockIP ) {
# If autoblocks are disabled, go away.
@@ -698,7 +720,8 @@ class Block {
wfDebug( "Autoblocking {$this->getTarget()}@" . $autoblockIP . "\n" );
$autoblock->setTarget( $autoblockIP );
$autoblock->setBlocker( $this->getBlocker() );
- $autoblock->mReason = wfMessage( 'autoblocker', $this->getTarget(), $this->mReason )->inContentLanguage()->plain();
+ $autoblock->mReason = wfMessage( 'autoblocker', $this->getTarget(), $this->mReason )
+ ->inContentLanguage()->plain();
$timestamp = wfTimestampNow();
$autoblock->mTimestamp = $timestamp;
$autoblock->mAuto = 1;
@@ -726,7 +749,7 @@ class Block {
/**
* Check if a block has expired. Delete it if it is.
- * @return Boolean
+ * @return bool
*/
public function deleteIfExpired() {
wfProfileIn( __METHOD__ );
@@ -746,7 +769,7 @@ class Block {
/**
* Has the block expired?
- * @return Boolean
+ * @return bool
*/
public function isExpired() {
$timestamp = wfTimestampNow();
@@ -761,7 +784,7 @@ class Block {
/**
* Is the block address valid (i.e. not a null string?)
- * @return Boolean
+ * @return bool
*/
public function isValid() {
return $this->getTarget() != null;
@@ -792,7 +815,7 @@ class Block {
/**
* Get the IP address at the start of the range in Hex form
* @throws MWException
- * @return String IP in Hex form
+ * @return string IP in Hex form
*/
public function getRangeStart() {
switch ( $this->type ) {
@@ -811,7 +834,7 @@ class Block {
/**
* Get the IP address at the end of the range in Hex form
* @throws MWException
- * @return String IP in Hex form
+ * @return string IP in Hex form
*/
public function getRangeEnd() {
switch ( $this->type ) {
@@ -830,7 +853,7 @@ class Block {
/**
* Get the user id of the blocking sysop
*
- * @return Integer (0 for foreign users)
+ * @return int (0 for foreign users)
*/
public function getBy() {
$blocker = $this->getBlocker();
@@ -842,7 +865,7 @@ class Block {
/**
* Get the username of the blocking sysop
*
- * @return String
+ * @return string
*/
public function getByName() {
$blocker = $this->getBlocker();
@@ -860,21 +883,10 @@ class Block {
}
/**
- * Get/set the SELECT ... FOR UPDATE flag
- * @deprecated since 1.18
- *
- * @param $x Bool
- */
- public function forUpdate( $x = null ) {
- wfDeprecated( __METHOD__, '1.18' );
- # noop
- }
-
- /**
* Get/set a flag determining whether the master is used for reads
*
- * @param $x Bool
- * @return Bool
+ * @param bool $x
+ * @return bool
*/
public function fromMaster( $x = null ) {
return wfSetVar( $this->mFromMaster, $x );
@@ -882,8 +894,8 @@ class Block {
/**
* Get/set whether the Block is a hardblock (affects logged-in users on a given IP/range
- * @param $x Bool
- * @return Bool
+ * @param bool $x
+ * @return bool
*/
public function isHardblock( $x = null ) {
wfSetVar( $this->isHardblock, $x );
@@ -906,9 +918,9 @@ class Block {
/**
* Get/set whether the Block prevents a given action
- * @param $action String
- * @param $x Bool
- * @return Bool
+ * @param string $action
+ * @param bool $x
+ * @return bool
*/
public function prevents( $action, $x = null ) {
switch ( $action ) {
@@ -932,7 +944,7 @@ class Block {
/**
* Get the block name, but with autoblocked IPs hidden as per standard privacy policy
- * @return String, text is escaped
+ * @return string Text is escaped
*/
public function getRedactedName() {
if ( $this->mAuto ) {
@@ -947,37 +959,10 @@ class Block {
}
/**
- * Encode expiry for DB
- *
- * @param string $expiry timestamp for expiry, or
- * @param $db DatabaseBase object
- * @return String
- * @deprecated since 1.18; use $dbw->encodeExpiry() instead
- */
- public static function encodeExpiry( $expiry, $db ) {
- wfDeprecated( __METHOD__, '1.18' );
- return $db->encodeExpiry( $expiry );
- }
-
- /**
- * Decode expiry which has come from the DB
- *
- * @param string $expiry Database expiry format
- * @param int $timestampType Requested timestamp format
- * @return String
- * @deprecated since 1.18; use $wgLang->formatExpiry() instead
- */
- public static function decodeExpiry( $expiry, $timestampType = TS_MW ) {
- wfDeprecated( __METHOD__, '1.18' );
- global $wgContLang;
- return $wgContLang->formatExpiry( $expiry, $timestampType );
- }
-
- /**
* Get a timestamp of the expiry for autoblocks
*
- * @param $timestamp String|Int
- * @return String
+ * @param string|int $timestamp
+ * @return string
*/
public static function getAutoblockExpiry( $timestamp ) {
global $wgAutoblockExpiry;
@@ -986,18 +971,6 @@ class Block {
}
/**
- * Gets rid of unneeded numbers in quad-dotted/octet IP strings
- * For example, 127.111.113.151/24 -> 127.111.113.0/24
- * @param string $range IP address to normalize
- * @return string
- * @deprecated since 1.18, call IP::sanitizeRange() directly
- */
- public static function normaliseRange( $range ) {
- wfDeprecated( __METHOD__, '1.18' );
- return IP::sanitizeRange( $range );
- }
-
- /**
* Purge expired blocks from the ipblocks table
*/
public static function purgeExpired() {
@@ -1007,38 +980,15 @@ class Block {
$method = __METHOD__;
$dbw = wfGetDB( DB_MASTER );
- $dbw->onTransactionIdle( function() use ( $dbw, $method ) {
+ $dbw->onTransactionIdle( function () use ( $dbw, $method ) {
$dbw->delete( 'ipblocks',
array( 'ipb_expiry < ' . $dbw->addQuotes( $dbw->timestamp() ) ), $method );
} );
}
/**
- * Get a value to insert into expiry field of the database when infinite expiry
- * is desired
- * @deprecated since 1.18, call $dbr->getInfinity() directly
- * @return String
- */
- public static function infinity() {
- wfDeprecated( __METHOD__, '1.18' );
- return wfGetDB( DB_SLAVE )->getInfinity();
- }
-
- /**
- * 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 string $expiry whatever was typed into the form
- * @return String: timestamp or "infinity" string for th DB implementation
- * @deprecated since 1.18 moved to SpecialBlock::parseExpiryInput()
- */
- public static function parseExpiryInput( $expiry ) {
- wfDeprecated( __METHOD__, '1.18' );
- return SpecialBlock::parseExpiryInput( $expiry );
- }
-
- /**
* Given a target and the target's type, get an existing Block object if possible.
- * @param $specificTarget String|User|Int a block target, which may be one of several types:
+ * @param string|User|int $specificTarget A block target, which may be one of several types:
* * A user to block, in which case $target will be a User
* * An IP to block, in which case $target will be a User generated by using
* User::newFromName( $ip, false ) to turn off name validation
@@ -1048,10 +998,10 @@ class Block {
* Calling this with a user, IP address or range will not select autoblocks, and will
* only select a block where the targets match exactly (so looking for blocks on
* 1.2.3.4 will not select 1.2.0.0/16 or even 1.2.3.4/32)
- * @param $vagueTarget String|User|Int as above, but we will search for *any* block which
+ * @param string|User|int $vagueTarget As above, but we will search for *any* block which
* affects that target (so for an IP address, get ranges containing that IP; and also
* get any relevant autoblocks). Leave empty or blank to skip IP-based lookups.
- * @param bool $fromMaster whether to use the DB_MASTER database
+ * @param bool $fromMaster Whether to use the DB_MASTER database
* @return Block|null (null if no relevant block could be found). The target and type
* of the returned Block will refer to the actual block which was found, which might
* not be the same as the target you gave if you used $vagueTarget!
@@ -1068,7 +1018,10 @@ class Block {
# passed by some callers (bug 29116)
return null;
- } elseif ( in_array( $type, array( Block::TYPE_USER, Block::TYPE_IP, Block::TYPE_RANGE, null ) ) ) {
+ } elseif ( in_array(
+ $type,
+ array( Block::TYPE_USER, Block::TYPE_IP, Block::TYPE_RANGE, null ) )
+ ) {
$block = new Block();
$block->fromMaster( $fromMaster );
@@ -1083,15 +1036,14 @@ class Block {
return null;
}
-
/**
* Get all blocks that match any IP from an array of IP addresses
*
- * @param Array $ipChain list of IPs (strings), usually retrieved from the
+ * @param array $ipChain List of IPs (strings), usually retrieved from the
* X-Forwarded-For header of the request
- * @param Bool $isAnon Exclude anonymous-only blocks if false
- * @param Bool $fromMaster Whether to query the master or slave database
- * @return Array of Blocks
+ * @param bool $isAnon Exclude anonymous-only blocks if false
+ * @param bool $fromMaster Whether to query the master or slave database
+ * @return array Array of Blocks
* @since 1.22
*/
public static function getBlocksForIPList( array $ipChain, $isAnon, $fromMaster = false ) {
@@ -1111,7 +1063,7 @@ class Block {
continue;
}
# Don't check trusted IPs (includes local squids which will be in every request)
- if ( wfIsTrustedProxy( $ipaddr ) ) {
+ if ( IP::isTrustedProxy( $ipaddr ) ) {
continue;
}
# Check both the original IP (to check against single blocks), as well as build
@@ -1165,13 +1117,13 @@ class Block {
* - Other softblocks are chosen over autoblocks
* - If there are multiple exact or range blocks at the same level, the one chosen
* is random
-
- * @param Array $ipChain list of IPs (strings). This is used to determine how "close"
+ *
+ * @param array $blocks Array of blocks
+ * @param array $ipChain List of IPs (strings). This is used to determine how "close"
* a block is to the server, and if a block matches exactly, or is in a range.
* The order is furthest from the server to nearest e.g., (Browser, proxy1, proxy2,
* local-squid, ...)
- * @param Array $block Array of blocks
- * @return Block|null the "best" block from the list
+ * @return Block|null The "best" block from the list
*/
public static function chooseBlock( array $blocks, array $ipChain ) {
if ( !count( $blocks ) ) {
@@ -1184,7 +1136,7 @@ class Block {
// Sort hard blocks before soft ones and secondarily sort blocks
// that disable account creation before those that don't.
- usort( $blocks, function( Block $a, Block $b ) {
+ usort( $blocks, function ( Block $a, Block $b ) {
$aWeight = (int)$a->isHardblock() . (int)$a->prevents( 'createaccount' );
$bWeight = (int)$b->isHardblock() . (int)$b->prevents( 'createaccount' );
return strcmp( $bWeight, $aWeight ); // highest weight first
@@ -1275,7 +1227,7 @@ class Block {
* as a string; for User objects this will return User::__toString()
* which in turn gives User::getName().
*
- * @param $target String|Int|User|null
+ * @param string|int|User|null $target
* @return array( User|String|null, Block::TYPE_ constant|null )
*/
public static function parseTarget( $target ) {
@@ -1332,7 +1284,7 @@ class Block {
/**
* Get the type of target for this particular block
- * @return Block::TYPE_ constant, will never be TYPE_ID
+ * @return int Block::TYPE_ constant, will never be TYPE_ID
*/
public function getType() {
return $this->mAuto
@@ -1355,7 +1307,7 @@ class Block {
* Get the target for this particular Block. Note that for autoblocks,
* this returns the unredacted name; frontend functions need to call $block->getRedactedName()
* in this situation.
- * @return User|String
+ * @return User|string
*/
public function getTarget() {
return $this->target;
@@ -1364,7 +1316,7 @@ class Block {
/**
* @since 1.19
*
- * @return Mixed|string
+ * @return mixed|string
*/
public function getExpiry() {
return $this->mExpiry;
@@ -1372,7 +1324,7 @@ class Block {
/**
* Set the target for this block, and update $this->type accordingly
- * @param $target Mixed
+ * @param mixed $target
*/
public function setTarget( $target ) {
list( $this->target, $this->type ) = self::parseTarget( $target );
@@ -1388,7 +1340,7 @@ class Block {
/**
* Set the user who implemented (or will implement) this block
- * @param $user User|string Local User object or username string for foreign users
+ * @param User|string $user Local User object or username string for foreign users
*/
public function setBlocker( $user ) {
$this->blocker = $user;
@@ -1429,7 +1381,7 @@ class Block {
$this->getId(),
$lang->formatExpiry( $this->mExpiry ),
(string)$intended,
- $lang->timeanddate( wfTimestamp( TS_MW, $this->mTimestamp ), true ),
+ $lang->userTimeAndDate( $this->mTimestamp, $context->getUser() ),
);
}
}
diff --git a/includes/Category.php b/includes/Category.php
index 126b8fee..322b0530 100644
--- a/includes/Category.php
+++ b/includes/Category.php
@@ -26,7 +26,7 @@
* 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.
+ * @todo Move some stuff from CategoryPage.php to here, and use that.
*/
class Category {
/** Name of the category, normalized to DB-key form */
@@ -75,7 +75,8 @@ class Category {
if ( !$row ) {
# Okay, there were no contents. Nothing to initialize.
if ( $this->mTitle ) {
- # If there is a title object but no record in the category table, treat this as an empty category
+ # If there is a title object but no record in the category table,
+ # treat this as an empty category.
$this->mID = false;
$this->mName = $this->mTitle->getDBkey();
$this->mPages = 0;
@@ -128,8 +129,8 @@ class Category {
/**
* Factory function.
*
- * @param $title Title for the category page
- * @return Category|bool on a totally invalid name
+ * @param Title $title Title for the category page
+ * @return Category|bool On a totally invalid name
*/
public static function newFromTitle( $title ) {
$cat = new self();
@@ -143,7 +144,7 @@ class Category {
/**
* Factory function.
*
- * @param $id Integer: a category id
+ * @param int $id A category id
* @return Category
*/
public static function newFromID( $id ) {
@@ -155,11 +156,13 @@ class Category {
/**
* Factory function, for constructing a Category object from a result set
*
- * @param $row result set row, must contain the cat_xxx fields. If the fields are null,
- * the resulting Category object will represent an empty category if a title object
- * was given. If the fields are null and no title was given, this method fails and returns false.
- * @param Title $title optional title object for the category represented by the given row.
- * May be provided if it is already known, to avoid having to re-create a title object later.
+ * @param object $row Result set row, must contain the cat_xxx fields. If the
+ * fields are null, the resulting Category object will represent an empty
+ * category if a title object was given. If the fields are null and no
+ * title was given, this method fails and returns false.
+ * @param Title $title Optional title object for the category represented by
+ * the given row. May be provided if it is already known, to avoid having
+ * to re-create a title object later.
* @return Category
*/
public static function newFromRow( $row, $title = null ) {
@@ -177,7 +180,8 @@ class Category {
# but we can't know that here...
return false;
} else {
- $cat->mName = $title->getDBkey(); # if we have a title object, fetch the category name from there
+ # if we have a title object, fetch the category name from there
+ $cat->mName = $title->getDBkey();
}
$cat->mID = false;
@@ -195,27 +199,37 @@ class Category {
return $cat;
}
- /** @return mixed DB key name, or false on failure */
+ /**
+ * @return mixed DB key name, or false on failure
+ */
public function getName() {
return $this->getX( 'mName' );
}
- /** @return mixed Category ID, or false on failure */
+ /**
+ * @return mixed Category ID, or false on failure
+ */
public function getID() {
return $this->getX( 'mID' );
}
- /** @return mixed Total number of member pages, or false on failure */
+ /**
+ * @return mixed Total number of member pages, or false on failure
+ */
public function getPageCount() {
return $this->getX( 'mPages' );
}
- /** @return mixed Number of subcategories, or false on failure */
+ /**
+ * @return mixed Number of subcategories, or false on failure
+ */
public function getSubcatCount() {
return $this->getX( 'mSubcats' );
}
- /** @return mixed Number of member files, or false on failure */
+ /**
+ * @return mixed Number of member files, or false on failure
+ */
public function getFileCount() {
return $this->getX( 'mFiles' );
}
@@ -239,9 +253,9 @@ class Category {
/**
* Fetch a TitleArray of up to $limit category members, beginning after the
* category sort key $offset.
- * @param $limit integer
- * @param $offset string
- * @return TitleArray object for category members.
+ * @param int $limit
+ * @param string $offset
+ * @return TitleArray TitleArray object for category members.
*/
public function getMembers( $limit = false, $offset = '' ) {
wfProfileIn( __METHOD__ );
@@ -277,6 +291,7 @@ class Category {
/**
* Generic accessor
+ * @param string $key
* @return bool
*/
private function getX( $key ) {
@@ -306,7 +321,7 @@ class Category {
wfProfileIn( __METHOD__ );
$dbw = wfGetDB( DB_MASTER );
- $dbw->begin( __METHOD__ );
+ $dbw->startAtomic( __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
@@ -346,7 +361,7 @@ class Category {
array( 'cat_title' => $this->mName ),
__METHOD__
);
- $dbw->commit( __METHOD__ );
+ $dbw->endAtomic( __METHOD__ );
wfProfileOut( __METHOD__ );
diff --git a/includes/Categoryfinder.php b/includes/CategoryFinder.php
index 6ef224b6..cf537e15 100644
--- a/includes/Categoryfinder.php
+++ b/includes/CategoryFinder.php
@@ -21,7 +21,7 @@
*/
/**
- * The "Categoryfinder" class takes a list of articles, creates an internal
+ * 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
* articles are in one or all of a given subset of categories.
@@ -31,7 +31,7 @@
* # Determines whether the article with the page_id 12345 is in both
* # "Category 1" and "Category 2" or their subcategories, respectively
*
- * $cf = new Categoryfinder;
+ * $cf = new CategoryFinder;
* $cf->seed(
* array( 12345 ),
* array( 'Category 1', 'Category 2' ),
@@ -42,36 +42,41 @@
* </code>
*
*/
-class Categoryfinder {
- var $articles = array(); # The original article IDs passed to the seed function
- var $deadend = array(); # Array of DBKEY category names for categories that don't have a page
- var $parents = array(); # Array of [ID => array()]
- var $next = array(); # Array of article/category IDs
- var $targets = array(); # Array of DBKEY category names
- var $name2id = array();
- var $mode; # "AND" or "OR"
+class CategoryFinder {
+ /** @var int[] The original article IDs passed to the seed function */
+ protected $articles = array();
- /**
- * @var DatabaseBase
- */
- var $dbr; # Read-DB slave
+ /** @var array Array of DBKEY category names for categories that don't have a page */
+ protected $deadend = array();
- /**
- * Constructor (currently empty).
- */
- function __construct() {
- }
+ /** @var array Array of [ID => array()] */
+ protected $parents = array();
+
+ /** @var array Array of article/category IDs */
+ protected $next = array();
+
+ /** @var array Array of DBKEY category names */
+ protected $targets = array();
+
+ /** @var array */
+ protected $name2id = array();
+
+ /** @var string "AND" or "OR" */
+ protected $mode;
+
+ /** @var DatabaseBase Read-DB slave */
+ protected $dbr;
/**
* Initializes the instance. Do this prior to calling run().
- * @param $article_ids Array of article IDs
- * @param $categories FIXME
+ * @param array $articleIds Array of article IDs
+ * @param array $categories FIXME
* @param string $mode FIXME, default 'AND'.
* @todo FIXME: $categories/$mode
*/
- function seed( $article_ids, $categories, $mode = 'AND' ) {
- $this->articles = $article_ids;
- $this->next = $article_ids;
+ public function seed( $articleIds, $categories, $mode = 'AND' ) {
+ $this->articles = $articleIds;
+ $this->next = $articleIds;
$this->mode = $mode;
# Set the list of target categories; convert them to DBKEY form first
@@ -88,12 +93,12 @@ class Categoryfinder {
/**
* Iterates through the parent tree starting with the seed values,
* then checks the articles if they match the conditions
- * @return array of page_ids (those given to seed() that match the conditions)
+ * @return array Array of page_ids (those given to seed() that match the conditions)
*/
- function run() {
+ public function run() {
$this->dbr = wfGetDB( DB_SLAVE );
while ( count( $this->next ) > 0 ) {
- $this->scan_next_layer();
+ $this->scanNextLayer();
}
# Now check if this applies to the individual articles
@@ -110,13 +115,21 @@ class Categoryfinder {
}
/**
+ * Get the parents. Only really useful if run() has been called already
+ * @return array
+ */
+ public function getParents() {
+ return $this->parents;
+ }
+
+ /**
* This functions recurses through the parent representation, trying to match the conditions
* @param int $id The article/category to check
* @param array $conds The array of categories to match
- * @param array $path used to check for recursion loops
+ * @param array $path Used to check for recursion loops
* @return bool Does this match the conditions?
*/
- function check( $id, &$conds, $path = array() ) {
+ private function check( $id, &$conds, $path = array() ) {
// Check for loops and stop!
if ( in_array( $id, $path ) ) {
return false;
@@ -171,8 +184,8 @@ class Categoryfinder {
/**
* Scans a "parent layer" of the articles/categories in $this->next
*/
- function scan_next_layer() {
- wfProfileIn( __METHOD__ );
+ private function scanNextLayer() {
+ $profiler = new ProfileSection( __METHOD__ );
# Find all parents of the article currently in $this->next
$layer = array();
@@ -227,7 +240,5 @@ class Categoryfinder {
foreach ( $layer as $v ) {
$this->deadend[$v] = $v;
}
-
- wfProfileOut( __METHOD__ );
}
}
diff --git a/includes/CategoryViewer.php b/includes/CategoryViewer.php
index 55d9c1e5..7581ae40 100644
--- a/includes/CategoryViewer.php
+++ b/includes/CategoryViewer.php
@@ -21,68 +21,77 @@
*/
class CategoryViewer extends ContextSource {
- var $limit, $from, $until,
- $articles, $articles_start_char,
- $children, $children_start_char,
- $showGallery, $imgsNoGalley,
- $imgsNoGallery_start_char,
- $imgsNoGallery;
+ /** @var int */
+ public $limit;
- /**
- * @var Array
- */
- var $nextPage;
+ /** @var array */
+ public $from;
- /**
- * @var Array
- */
- var $flip;
+ /** @var array */
+ public $until;
- /**
- * @var Title
- */
- var $title;
+ /** @var string[] */
+ public $articles;
- /**
- * @var Collation
- */
- var $collation;
+ /** @var array */
+ public $articles_start_char;
- /**
- * @var ImageGallery
- */
- var $gallery;
+ /** @var array */
+ public $children;
- /**
- * Category object for this page
- * @var Category
- */
+ /** @var array */
+ public $children_start_char;
+
+ /** @var bool */
+ public $showGallery;
+
+ /** @var array */
+ public $imgsNoGallery_start_char;
+
+ /** @var array */
+ public $imgsNoGallery;
+
+ /** @var array */
+ public $nextPage;
+
+ /** @var array */
+ protected $prevPage;
+
+ /** @var array */
+ public $flip;
+
+ /** @var Title */
+ public $title;
+
+ /** @var Collation */
+ public $collation;
+
+ /** @var ImageGallery */
+ public $gallery;
+
+ /** @var Category Category object for this page. */
private $cat;
- /**
- * The original query array, to be used in generating paging links.
- * @var array
- */
+ /** @var array The original query array, to be used in generating paging links. */
private $query;
/**
- * Constructor
- *
* @since 1.19 $context is a second, required parameter
- * @param $title Title
- * @param $context IContextSource
+ * @param Title $title
+ * @param IContextSource $context
* @param array $from An array with keys page, subcat,
* and file for offset of results of each section (since 1.17)
* @param array $until An array with 3 keys for until of each section (since 1.17)
- * @param $query Array
+ * @param array $query
*/
- function __construct( $title, IContextSource $context, $from = array(), $until = array(), $query = array() ) {
- global $wgCategoryPagingLimit;
+ function __construct( $title, IContextSource $context, $from = array(),
+ $until = array(), $query = array()
+ ) {
$this->title = $title;
$this->setContext( $context );
$this->from = $from;
$this->until = $until;
- $this->limit = $wgCategoryPagingLimit;
+ $this->limit = $context->getConfig()->get( 'CategoryPagingLimit' );
$this->cat = Category::newFromTitle( $title );
$this->query = $query;
$this->collation = Collation::singleton();
@@ -95,10 +104,10 @@ class CategoryViewer extends ContextSource {
* @return string HTML output
*/
public function getHTML() {
- global $wgCategoryMagicGallery;
wfProfileIn( __METHOD__ );
- $this->showGallery = $wgCategoryMagicGallery && !$this->getOutput()->mNoGallery;
+ $this->showGallery = $this->getConfig()->get( 'CategoryMagicGallery' )
+ && !$this->getOutput()->mNoGallery;
$this->clearCategoryState();
$this->doCategoryQuery();
@@ -144,14 +153,13 @@ class CategoryViewer extends ContextSource {
// Note that null for mode is taken to mean use default.
$mode = $this->getRequest()->getVal( 'gallerymode', null );
try {
- $this->gallery = ImageGalleryBase::factory( $mode );
+ $this->gallery = ImageGalleryBase::factory( $mode, $this->getContext() );
} catch ( MWException $e ) {
// User specified something invalid, fallback to default.
- $this->gallery = ImageGalleryBase::factory();
+ $this->gallery = ImageGalleryBase::factory( false, $this->getContext() );
}
$this->gallery->setHideBadImages();
- $this->gallery->setContext( $this->getContext() );
} else {
$this->imgsNoGallery = array();
$this->imgsNoGallery_start_char = array();
@@ -160,9 +168,9 @@ class CategoryViewer extends ContextSource {
/**
* Add a subcategory to the internal lists, using a Category object
- * @param $cat Category
- * @param $sortkey
- * @param $pageLength
+ * @param Category $cat
+ * @param string $sortkey
+ * @param int $pageLength
*/
function addSubcategoryObject( Category $cat, $sortkey, $pageLength ) {
// Subcategory; strip the 'Category' namespace from the link text.
@@ -182,15 +190,6 @@ class CategoryViewer extends ContextSource {
}
/**
- * Add a subcategory to the internal lists, using a title object
- * @deprecated since 1.17 kept for compatibility, use addSubcategoryObject instead
- */
- function addSubcategory( Title $title, $sortkey, $pageLength ) {
- wfDeprecated( __METHOD__, '1.17' );
- $this->addSubcategoryObject( Category::newFromTitle( $title ), $sortkey, $pageLength );
- }
-
- /**
* Get the character to be used for sorting subcategories.
* If there's a link from Category:A to Category:B, the sortkey of the resulting
* entry in the categorylinks table is Category:A, not A, which it SHOULD be.
@@ -217,10 +216,10 @@ class CategoryViewer extends ContextSource {
/**
* Add a page in the image namespace
- * @param $title Title
- * @param $sortkey
- * @param $pageLength
- * @param $isRedirect bool
+ * @param Title $title
+ * @param string $sortkey
+ * @param int $pageLength
+ * @param bool $isRedirect
*/
function addImage( Title $title, $sortkey, $pageLength, $isRedirect = false ) {
global $wgContLang;
@@ -247,10 +246,10 @@ class CategoryViewer extends ContextSource {
/**
* Add a miscellaneous page
- * @param $title
- * @param $sortkey
- * @param $pageLength
- * @param $isRedirect bool
+ * @param Title $title
+ * @param string $sortkey
+ * @param int $pageLength
+ * @param bool $isRedirect
*/
function addPage( $title, $sortkey, $pageLength, $isRedirect = false ) {
global $wgContLang;
@@ -290,6 +289,12 @@ class CategoryViewer extends ContextSource {
'subcat' => null,
'file' => null,
);
+ $this->prevPage = array(
+ 'page' => null,
+ 'subcat' => null,
+ 'file' => null,
+ );
+
$this->flip = array( 'page' => false, 'subcat' => false, 'file' => false );
foreach ( array( 'page', 'subcat', 'file' ) as $type ) {
@@ -346,6 +351,9 @@ class CategoryViewer extends ContextSource {
$this->nextPage[$type] = $humanSortkey;
break;
}
+ if ( $count == $this->limit ) {
+ $this->prevPage[$type] = $humanSortkey;
+ }
if ( $title->getNamespace() == NS_CATEGORY ) {
$cat = Category::newFromRow( $row, $title );
@@ -432,7 +440,12 @@ class CategoryViewer extends ContextSource {
$countmsg = $this->getCountMessage( $rescnt, $dbcnt, 'file' );
$r .= "<div id=\"mw-category-media\">\n";
- $r .= '<h2>' . $this->msg( 'category-media-header', wfEscapeWikiText( $this->title->getText() ) )->text() . "</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 ) {
@@ -451,12 +464,24 @@ class CategoryViewer extends ContextSource {
* of the output.
*
* @param string $type 'page', 'subcat', or 'file'
- * @return String: HTML output, possibly empty if there are no other pages
+ * @return string HTML output, possibly empty if there are no other pages
*/
private function getSectionPagingLinks( $type ) {
if ( isset( $this->until[$type] ) && $this->until[$type] !== null ) {
- return $this->pagingLinks( $this->nextPage[$type], $this->until[$type], $type );
- } elseif ( $this->nextPage[$type] !== null || ( isset( $this->from[$type] ) && $this->from[$type] !== null ) ) {
+ // The new value for the until parameter should be pointing to the first
+ // result displayed on the page which is the second last result retrieved
+ // from the database.The next link should have a from parameter pointing
+ // to the until parameter of the current page.
+ if ( $this->nextPage[$type] !== null ) {
+ return $this->pagingLinks( $this->prevPage[$type], $this->until[$type], $type );
+ } else {
+ // If the nextPage variable is null, it means that we have reached the first page
+ // and therefore the previous link should be disabled.
+ return $this->pagingLinks( null, $this->until[$type], $type );
+ }
+ } elseif ( $this->nextPage[$type] !== null
+ || ( isset( $this->from[$type] ) && $this->from[$type] !== null )
+ ) {
return $this->pagingLinks( $this->from[$type], $this->nextPage[$type], $type );
} else {
return '';
@@ -474,10 +499,10 @@ class CategoryViewer extends ContextSource {
* Format a list of articles chunked by letter, either as a
* bullet list or a columnar format, depending on the length.
*
- * @param $articles Array
- * @param $articles_start_char Array
- * @param $cutoff Int
- * @return String
+ * @param array $articles
+ * @param array $articles_start_char
+ * @param int $cutoff
+ * @return string
* @private
*/
function formatList( $articles, $articles_start_char, $cutoff = 6 ) {
@@ -507,9 +532,9 @@ class CategoryViewer extends ContextSource {
* More distant TODO: Scrap this and use CSS columns, whenever IE finally
* supports those.
*
- * @param $articles Array
- * @param $articles_start_char Array
- * @return String
+ * @param array $articles
+ * @param string[] $articles_start_char
+ * @return string
* @private
*/
static function columnList( $articles, $articles_start_char ) {
@@ -563,15 +588,16 @@ class CategoryViewer extends ContextSource {
/**
* Format a list of articles chunked by letter in a bullet list.
- * @param $articles Array
- * @param $articles_start_char Array
- * @return String
+ * @param array $articles
+ * @param string[] $articles_start_char
+ * @return string
* @private
*/
static function shortList( $articles, $articles_start_char ) {
$r = '<h3>' . htmlspecialchars( $articles_start_char[0] ) . "</h3>\n";
$r .= '<ul><li>' . $articles[0] . '</li>';
- for ( $index = 1; $index < count( $articles ); $index++ ) {
+ $articleCount = count( $articles );
+ for ( $index = 1; $index < $articleCount; $index++ ) {
if ( $articles_start_char[$index] != $articles_start_char[$index - 1] ) {
$r .= "</ul><h3>" . htmlspecialchars( $articles_start_char[$index] ) . "</h3>\n<ul>";
}
@@ -589,7 +615,7 @@ class CategoryViewer extends ContextSource {
* @param string $last The 'from' parameter for the generated URL
* @param string $type A prefix for parameters, 'page' or 'subcat' or
* 'file'
- * @return String HTML
+ * @return string HTML
*/
private function pagingLinks( $first, $last, $type = '' ) {
$prevLink = $this->msg( 'prevn' )->numParams( $this->limit )->escaped();
@@ -627,8 +653,8 @@ class CategoryViewer extends ContextSource {
* Takes a title, and adds the fragment identifier that
* corresponds to the correct segment of the category.
*
- * @param Title $title: The title (usually $this->title)
- * @param string $section: Which section
+ * @param Title $title The title (usually $this->title)
+ * @param string $section Which section
* @throws MWException
* @return Title
*/
@@ -660,7 +686,7 @@ class CategoryViewer extends ContextSource {
* @param int $rescnt The number of items returned by our database query.
* @param int $dbcnt The number of items according to the category table.
* @param string $type 'subcat', 'article', or 'file'
- * @return string: A message giving the number of items, to output to HTML.
+ * @return string A message giving the number of items, to output to HTML.
*/
private function getCountMessage( $rescnt, $dbcnt, $type ) {
// There are three cases:
@@ -701,7 +727,10 @@ class CategoryViewer extends ContextSource {
// to refresh the incorrect category table entry -- which should be
// quick due to the small number of entries.
$totalcnt = $rescnt;
- $this->cat->refreshCounts();
+ $category = $this->cat;
+ wfGetDB( DB_MASTER )->onTransactionIdle( function () use ( $category ) {
+ $category->refreshCounts();
+ } );
} else {
// Case 3: hopeless. Don't give a total count at all.
// Messages: category-subcat-count-limited, category-article-count-limited,
diff --git a/includes/ChangeTags.php b/includes/ChangeTags.php
index 3fc27f9a..94b7b7a9 100644
--- a/includes/ChangeTags.php
+++ b/includes/ChangeTags.php
@@ -21,18 +21,15 @@
*/
class ChangeTags {
-
/**
* Creates HTML for the given tags
*
* @param string $tags Comma-separated list of tags
* @param string $page A label for the type of action which is being displayed,
- * for example: 'history', 'contributions' or 'newpages'
- *
- * @return Array with two items: (html, classes)
- * - html: String: HTML for displaying the tags (empty string when param $tags is empty)
- * - classes: Array of strings: CSS classes used in the generated html, one class for each tag
- *
+ * for example: 'history', 'contributions' or 'newpages'
+ * @return array Array with two items: (html, classes)
+ * - html: String: HTML for displaying the tags (empty string when param $tags is empty)
+ * - classes: Array of strings: CSS classes used in the generated html, one class for each tag
*/
public static function formatSummaryRow( $tags, $page ) {
global $wgLang;
@@ -66,10 +63,10 @@ class ChangeTags {
/**
* Get a short description for a tag
*
- * @param string $tag tag
+ * @param string $tag Tag
*
- * @return String: Short description of the tag from "mediawiki:tag-$tag" if this message exists,
- * html-escaped version of $tag otherwise
+ * @return string Short description of the tag from "mediawiki:tag-$tag" if this message exists,
+ * html-escaped version of $tag otherwise
*/
public static function tagDescription( $tag ) {
$msg = wfMessage( "tag-$tag" );
@@ -80,17 +77,19 @@ class ChangeTags {
* Add tags to a change given its rc_id, rev_id and/or log_id
*
* @param string|array $tags Tags to add to the change
- * @param $rc_id int: rc_id of the change to add the tags to
- * @param $rev_id int: rev_id of the change to add the tags to
- * @param $log_id int: log_id of the change to add the tags to
- * @param string $params params to put in the ct_params field of table 'change_tag'
+ * @param int|null $rc_id The rc_id of the change to add the tags to
+ * @param int|null $rev_id The rev_id of the change to add the tags to
+ * @param int|null $log_id The log_id of the change to add the tags to
+ * @param string $params Params to put in the ct_params field of table 'change_tag'
*
* @throws MWException
- * @return bool: false if no changes are made, otherwise true
+ * @return bool False if no changes are made, otherwise true
*
- * @exception MWException when $rc_id, $rev_id and $log_id are all null
+ * @exception MWException When $rc_id, $rev_id and $log_id are all null
*/
- public static function addTags( $tags, $rc_id = null, $rev_id = null, $log_id = null, $params = null ) {
+ public static function addTags( $tags, $rc_id = null, $rev_id = null,
+ $log_id = null, $params = null
+ ) {
if ( !is_array( $tags ) ) {
$tags = array( $tags );
}
@@ -102,26 +101,52 @@ class ChangeTags {
'specified when adding a tag to a change!' );
}
- $dbr = wfGetDB( DB_SLAVE );
+ $dbw = wfGetDB( DB_MASTER );
// Might as well look for rcids and so on.
if ( !$rc_id ) {
- $dbr = wfGetDB( DB_MASTER ); // Info might be out of date, somewhat fractionally, on slave.
+ // Info might be out of date, somewhat fractionally, on slave.
if ( $log_id ) {
- $rc_id = $dbr->selectField( 'recentchanges', 'rc_id', array( 'rc_logid' => $log_id ), __METHOD__ );
+ $rc_id = $dbw->selectField(
+ 'recentchanges',
+ 'rc_id',
+ array( 'rc_logid' => $log_id ),
+ __METHOD__
+ );
} elseif ( $rev_id ) {
- $rc_id = $dbr->selectField( 'recentchanges', 'rc_id', array( 'rc_this_oldid' => $rev_id ), __METHOD__ );
+ $rc_id = $dbw->selectField(
+ 'recentchanges',
+ 'rc_id',
+ array( 'rc_this_oldid' => $rev_id ),
+ __METHOD__
+ );
}
} elseif ( !$log_id && !$rev_id ) {
- $dbr = wfGetDB( DB_MASTER ); // Info might be out of date, somewhat fractionally, on slave.
- $log_id = $dbr->selectField( 'recentchanges', 'rc_logid', array( 'rc_id' => $rc_id ), __METHOD__ );
- $rev_id = $dbr->selectField( 'recentchanges', 'rc_this_oldid', array( 'rc_id' => $rc_id ), __METHOD__ );
+ // Info might be out of date, somewhat fractionally, on slave.
+ $log_id = $dbw->selectField(
+ 'recentchanges',
+ 'rc_logid',
+ array( 'rc_id' => $rc_id ),
+ __METHOD__
+ );
+ $rev_id = $dbw->selectField(
+ 'recentchanges',
+ 'rc_this_oldid',
+ array( 'rc_id' => $rc_id ),
+ __METHOD__
+ );
}
- $tsConds = array_filter( array( 'ts_rc_id' => $rc_id, 'ts_rev_id' => $rev_id, 'ts_log_id' => $log_id ) );
+ $tsConds = array_filter( array(
+ 'ts_rc_id' => $rc_id,
+ 'ts_rev_id' => $rev_id,
+ 'ts_log_id' => $log_id )
+ );
- ## Update the summary row.
- $prevTags = $dbr->selectField( 'tag_summary', 'ts_tags', $tsConds, __METHOD__ );
+ // Update the summary row.
+ // $prevTags can be out of date on slaves, especially when addTags is called consecutively,
+ // causing loss of tags added recently in tag_summary table.
+ $prevTags = $dbw->selectField( 'tag_summary', 'ts_tags', $tsConds, __METHOD__ );
$prevTags = $prevTags ? $prevTags : '';
$prevTags = array_filter( explode( ',', $prevTags ) );
$newTags = array_unique( array_merge( $prevTags, $tags ) );
@@ -133,7 +158,6 @@ class ChangeTags {
return false;
}
- $dbw = wfGetDB( DB_MASTER );
$dbw->replace(
'tag_summary',
array( 'ts_rev_id', 'ts_rc_id', 'ts_log_id' ),
@@ -167,9 +191,9 @@ class ChangeTags {
*
* @param string|array $tables Table names, see DatabaseBase::select
* @param string|array $fields Fields used in query, see DatabaseBase::select
- * @param string|array $conds conditions used in query, see DatabaseBase::select
- * @param $join_conds Array: join conditions, see DatabaseBase::select
- * @param array $options options, see Database::select
+ * @param string|array $conds Conditions used in query, see DatabaseBase::select
+ * @param array $join_conds Join conditions, see DatabaseBase::select
+ * @param array $options Options, see Database::select
* @param bool|string $filter_tag Tag to select on
*
* @throws MWException When unable to determine appropriate JOIN condition for tagging
@@ -184,29 +208,27 @@ class ChangeTags {
// Figure out which conditions can be done.
if ( in_array( 'recentchanges', $tables ) ) {
- $join_cond = 'rc_id';
+ $join_cond = 'ct_rc_id=rc_id';
} elseif ( in_array( 'logging', $tables ) ) {
- $join_cond = 'log_id';
+ $join_cond = 'ct_log_id=log_id';
} elseif ( in_array( 'revision', $tables ) ) {
- $join_cond = 'rev_id';
+ $join_cond = 'ct_rev_id=rev_id';
+ } elseif ( in_array( 'archive', $tables ) ) {
+ $join_cond = 'ct_rev_id=ar_rev_id';
} else {
throw new MWException( 'Unable to determine appropriate JOIN condition for tagging.' );
}
- // JOIN on tag_summary
- $tables[] = 'tag_summary';
- $join_conds['tag_summary'] = array( 'LEFT JOIN', "ts_$join_cond=$join_cond" );
- $fields[] = 'ts_tags';
+ $fields['ts_tags'] = wfGetDB( DB_SLAVE )->buildGroupConcatField(
+ ',', 'change_tag', 'ct_tag', $join_cond
+ );
if ( $wgUseTagFilter && $filter_tag ) {
// Somebody wants to filter on a tag.
// Add an INNER JOIN on change_tag
- // FORCE INDEX -- change_tags will almost ALWAYS be the correct query plan.
- $options['USE INDEX'] = array( 'change_tag' => 'change_tag_tag_id' );
- unset( $options['FORCE INDEX'] );
$tables[] = 'change_tag';
- $join_conds['change_tag'] = array( 'INNER JOIN', "ct_$join_cond=$join_cond" );
+ $join_conds['change_tag'] = array( 'INNER JOIN', $join_cond );
$conds['ct_tag'] = $filter_tag;
}
}
@@ -214,34 +236,55 @@ class ChangeTags {
/**
* Build a text box to select a change tag
*
- * @param string $selected tag to select by default
- * @param $fullForm Boolean:
+ * @param string $selected Tag to select by default
+ * @param bool $fullForm
* - if false, then it returns an array of (label, form).
* - if true, it returns an entire form around the selector.
- * @param $title Title object to send the form to.
+ * @param Title $title Title object to send the form to.
* Used when, and only when $fullForm is true.
- * @return String or array:
+ * @return string|array
* - if $fullForm is false: Array with
* - if $fullForm is true: String, html fragment
*/
- public static function buildTagFilterSelector( $selected = '', $fullForm = false, Title $title = null ) {
+ public static function buildTagFilterSelector( $selected = '',
+ $fullForm = false, Title $title = null
+ ) {
global $wgUseTagFilter;
if ( !$wgUseTagFilter || !count( self::listDefinedTags() ) ) {
return $fullForm ? '' : array();
}
- $data = array( Html::rawElement( 'label', array( 'for' => 'tagfilter' ), wfMessage( 'tag-filter' )->parse() ),
- Xml::input( 'tagfilter', 20, $selected, array( 'class' => 'mw-tagfilter-input' ) ) );
+ $data = array(
+ Html::rawElement(
+ 'label',
+ array( 'for' => 'tagfilter' ),
+ wfMessage( 'tag-filter' )->parse()
+ ),
+ Xml::input(
+ 'tagfilter',
+ 20,
+ $selected,
+ array( 'class' => 'mw-tagfilter-input', 'id' => 'tagfilter' )
+ )
+ );
if ( !$fullForm ) {
return $data;
}
$html = implode( '&#160;', $data );
- $html .= "\n" . Xml::element( 'input', array( 'type' => 'submit', 'value' => wfMessage( 'tag-filter-submit' )->text() ) );
+ $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(), 'class' => 'mw-tagfilter-form', 'method' => 'get' ), $html );
+ $html = Xml::tags(
+ 'form',
+ array( 'action' => $title->getLocalURL(), 'class' => 'mw-tagfilter-form', 'method' => 'get' ),
+ $html
+ );
return $html;
}
@@ -253,7 +296,7 @@ class ChangeTags {
*
* Tries memcached first.
*
- * @return Array of strings: tags
+ * @return string[] Array of strings: tags
*/
public static function listDefinedTags() {
// Caching...
diff --git a/includes/Collation.php b/includes/Collation.php
index b0252c70..1c2c2db3 100644
--- a/includes/Collation.php
+++ b/includes/Collation.php
@@ -21,7 +21,7 @@
*/
abstract class Collation {
- static $instance;
+ private static $instance;
/**
* @return Collation
@@ -36,7 +36,7 @@ abstract class Collation {
/**
* @throws MWException
- * @param $collationName string
+ * @param string $collationName
* @return Collation
*/
static function factory( $collationName ) {
@@ -47,6 +47,10 @@ abstract class Collation {
return new IdentityCollation;
case 'uca-default':
return new IcuCollation( 'root' );
+ case 'xx-uca-ckb':
+ return new CollationCkb;
+ case 'xx-uca-et':
+ return new CollationEt;
default:
$match = array();
if ( preg_match( '/^uca-([a-z@=-]+)$/', $collationName, $match ) ) {
@@ -106,7 +110,8 @@ abstract class Collation {
}
class UppercaseCollation extends Collation {
- var $lang;
+ private $lang;
+
function __construct() {
// Get a language object so that we can use the generic UTF-8 uppercase
// function there
@@ -149,10 +154,22 @@ class IdentityCollation extends Collation {
}
class IcuCollation extends Collation {
- const FIRST_LETTER_VERSION = 1;
+ const FIRST_LETTER_VERSION = 2;
+
+ /** @var Collator */
+ private $primaryCollator;
+
+ /** @var Collator */
+ private $mainCollator;
+
+ /** @var string */
+ private $locale;
- var $primaryCollator, $mainCollator, $locale;
- var $firstLetterData;
+ /** @var Language */
+ protected $digitTransformLanguage;
+
+ /** @var array */
+ private $firstLetterData;
/**
* Unified CJK blocks.
@@ -163,7 +180,7 @@ class IcuCollation extends Collation {
* is pretty useless for sorting Chinese text anyway. Japanese and Korean
* blocks are not included here, because they are smaller and more useful.
*/
- static $cjkBlocks = array(
+ private static $cjkBlocks = array(
array( 0x2E80, 0x2EFF ), // CJK Radicals Supplement
array( 0x2F00, 0x2FDF ), // Kangxi Radicals
array( 0x2FF0, 0x2FFF ), // Ideographic Description Characters
@@ -202,14 +219,19 @@ class IcuCollation extends Collation {
* Empty arrays are intended; this signifies that the data for the language is
* available and that there are, in fact, no additional letters to consider.
*/
- static $tailoringFirstLetters = array(
+ private static $tailoringFirstLetters = array(
// Verified by native speakers
'be' => array( "Ё" ),
'be-tarask' => array( "Ё" ),
+ 'cy' => array( "Ch", "Dd", "Ff", "Ng", "Ll", "Ph", "Rh", "Th" ),
'en' => array(),
+ 'fa' => array( "آ", "ء", "ه" ),
'fi' => array( "Å", "Ä", "Ö" ),
+ 'fr' => array(),
'hu' => array( "Cs", "Dz", "Dzs", "Gy", "Ly", "Ny", "Ö", "Sz", "Ty", "Ü", "Zs" ),
+ 'is' => array( "Á", "Ð", "É", "Í", "Ó", "Ú", "Ý", "Þ", "Æ", "Ö", "Å" ),
'it' => array(),
+ 'lv' => array( "Č", "Ģ", "Ķ", "Ļ", "Ņ", "Š", "Ž" ),
'pl' => array( "Ą", "Ć", "Ę", "Ł", "Ń", "Ó", "Ś", "Ź", "Ż" ),
'pt' => array(),
'ru' => array(),
@@ -227,18 +249,15 @@ class IcuCollation extends Collation {
'ca' => array(),
'co' => array(),
'cs' => array( "Č", "Ch", "Ř", "Š", "Ž" ),
- 'cy' => array( "Ch", "Dd", "Ff", "Ng", "Ll", "Ph", "Rh", "Th" ),
'da' => array( "Æ", "Ø", "Å" ),
'de' => array(),
'dsb' => array( "Č", "Ć", "Dź", "Ě", "Ch", "Ł", "Ń", "Ŕ", "Š", "Ś", "Ž", "Ź" ),
'el' => array(),
'eo' => array( "Ĉ", "Ĝ", "Ĥ", "Ĵ", "Ŝ", "Ŭ" ),
'es' => array( "Ñ" ),
- 'et' => array( "Š", "Ž", "Õ", "Ä", "Ö", "Ü" ),
+ 'et' => array( "Š", "Ž", "Õ", "Ä", "Ö", "Ü", "W" ), // added W for CollationEt (xx-uca-et)
'eu' => array( "Ñ" ),
- 'fa' => array( "آ", "ء", "ه" ),
'fo' => array( "Á", "Ð", "Í", "Ó", "Ú", "Ý", "Æ", "Ø", "Å" ),
- 'fr' => array(),
'fur' => array( "À", "Á", "Â", "È", "Ì", "Ò", "Ù" ),
'fy' => array(),
'ga' => array(),
@@ -246,7 +265,6 @@ class IcuCollation extends Collation {
'gl' => array( "Ch", "Ll", "Ñ" ),
'hr' => array( "Č", "Ć", "Dž", "Đ", "Lj", "Nj", "Š", "Ž" ),
'hsb' => array( "Č", "Dź", "Ě", "Ch", "Ł", "Ń", "Ř", "Š", "Ć", "Ž" ),
- 'is' => array( "Á", "Ð", "É", "Í", "Ó", "Ú", "Ý", "Þ", "Æ", "Ö", "Å" ),
'kk' => array( "Ү", "І" ),
'kl' => array( "Æ", "Ø", "Å" ),
'ku' => array( "Ç", "Ê", "Î", "Ş", "Û" ),
@@ -254,7 +272,6 @@ class IcuCollation extends Collation {
'la' => array(),
'lb' => array(),
'lt' => array( "Č", "Š", "Ž" ),
- 'lv' => array( "Č", "Ģ", "Ķ", "Ļ", "Ņ", "Š", "Ž" ),
'mk' => array(),
'mo' => array( "Ă", "Â", "Î", "Ş", "Ţ" ),
'mt' => array( "Ċ", "Ġ", "Għ", "Ħ", "Ż" ),
@@ -284,7 +301,12 @@ class IcuCollation extends Collation {
throw new MWException( 'An ICU collation was requested, ' .
'but the intl extension is not available.' );
}
+
$this->locale = $locale;
+ // Drop everything after the '@' in locale's name
+ $localeParts = explode( '@', $locale );
+ $this->digitTransformLanguage = Language::factory( $locale === 'root' ? 'en' : $localeParts[0] );
+
$this->mainCollator = Collator::create( $locale );
if ( !$this->mainCollator ) {
throw new MWException( "Invalid ICU locale specified for collation: $locale" );
@@ -319,16 +341,14 @@ class IcuCollation extends Collation {
// Check for CJK
$firstChar = mb_substr( $string, 0, 1, 'UTF-8' );
- if ( ord( $firstChar ) > 0x7f
- && self::isCjk( utf8ToCodepoint( $firstChar ) ) )
- {
+ if ( ord( $firstChar ) > 0x7f && self::isCjk( utf8ToCodepoint( $firstChar ) ) ) {
return $firstChar;
}
$sortKey = $this->getPrimarySortKey( $string );
// Do a binary search to find the correct letter to sort under
- $min = $this->findLowerBound(
+ $min = ArrayUtils::findLowerBound(
array( $this, 'getSortKeyByLetterIndex' ),
$this->getFirstLetterCount(),
'strcmp',
@@ -347,7 +367,12 @@ class IcuCollation extends Collation {
}
$cache = wfGetCache( CACHE_ANYTHING );
- $cacheKey = wfMemcKey( 'first-letters', $this->locale );
+ $cacheKey = wfMemcKey(
+ 'first-letters',
+ $this->locale,
+ $this->digitTransformLanguage->getCode(),
+ self::getICUVersion()
+ );
$cacheEntry = $cache->get( $cacheKey );
if ( $cacheEntry && isset( $cacheEntry['version'] )
@@ -367,6 +392,12 @@ class IcuCollation extends Collation {
if ( isset( self::$tailoringFirstLetters['-' . $this->locale] ) ) {
$letters = array_diff( $letters, self::$tailoringFirstLetters['-' . $this->locale] );
}
+ // Apply digit transforms
+ $digits = array( '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' );
+ $letters = array_diff( $letters, $digits );
+ foreach ( $digits as $digit ) {
+ $letters[] = $this->digitTransformLanguage->formatNum( $digit, true );
+ }
} else {
$letters = wfGetPrecompiledData( "first-letters-{$this->locale}.ser" );
if ( $letters === false ) {
@@ -459,7 +490,7 @@ class IcuCollation extends Collation {
$prev = $trimmedKey;
}
foreach ( $duplicatePrefixes as $badKey ) {
- wfDebug( "Removing '{$letterMap[$badKey]}' from first letters." );
+ wfDebug( "Removing '{$letterMap[$badKey]}' from first letters.\n" );
unset( $letterMap[$badKey] );
// This code assumes that unsetting does not change sort order.
}
@@ -499,53 +530,6 @@ class IcuCollation extends Collation {
return count( $this->firstLetterData['chars'] );
}
- /**
- * Do a binary search, and return the index of the largest item that sorts
- * less than or equal to the target value.
- *
- * @param array $valueCallback A function to call to get the value with
- * a given array index.
- * @param int $valueCount The number of items accessible via $valueCallback,
- * indexed from 0 to $valueCount - 1
- * @param array $comparisonCallback A callback to compare two values, returning
- * -1, 0 or 1 in the style of strcmp().
- * @param string $target The target value to find.
- *
- * @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 ) {
- if ( $valueCount === 0 ) {
- return false;
- }
-
- $min = 0;
- $max = $valueCount;
- do {
- $mid = $min + ( ( $max - $min ) >> 1 );
- $item = call_user_func( $valueCallback, $mid );
- $comparison = call_user_func( $comparisonCallback, $target, $item );
- if ( $comparison > 0 ) {
- $min = $mid;
- } elseif ( $comparison == 0 ) {
- $min = $mid;
- break;
- } else {
- $max = $mid;
- }
- } while ( $min < $max - 1 );
-
- if ( $min == 0 ) {
- $item = call_user_func( $valueCallback, $min );
- $comparison = call_user_func( $comparisonCallback, $target, $item );
- if ( $comparison < 0 ) {
- // Before the first item
- return false;
- }
- }
- return $min;
- }
-
static function isCjk( $codepoint ) {
foreach ( self::$cjkBlocks as $block ) {
if ( $codepoint >= $block[0] && $codepoint <= $block[1] ) {
@@ -565,7 +549,7 @@ class IcuCollation extends Collation {
* This function will return false on older PHPs.
*
* @since 1.21
- * @return string|false
+ * @return string|bool
*/
static function getICUVersion() {
return defined( 'INTL_ICU_VERSION' ) ? INTL_ICU_VERSION : false;
@@ -576,7 +560,7 @@ class IcuCollation extends Collation {
* currently in use, or false when it can't be determined.
*
* @since 1.21
- * @return string|false
+ * @return string|bool
*/
static function getUnicodeVersionForICU() {
$icuVersion = IcuCollation::getICUVersion();
@@ -606,3 +590,56 @@ class IcuCollation extends Collation {
}
}
}
+
+/**
+ * Workaround for the lack of support of Sorani Kurdish / Central Kurdish language ('ckb') in ICU.
+ *
+ * Uses the same collation rules as Persian / Farsi ('fa'), but different characters for digits.
+ */
+class CollationCkb extends IcuCollation {
+ function __construct() {
+ // This will set $locale and collators, which affect the actual sorting order
+ parent::__construct( 'fa' );
+ // Override the 'fa' language set by parent constructor, which affects #getFirstLetterData()
+ $this->digitTransformLanguage = Language::factory( 'ckb' );
+ }
+}
+
+/**
+ * Workaround for incorrect collation of Estonian language ('et') in ICU (bug 54168).
+ *
+ * 'W' and 'V' should not be considered the same letter for the purposes of collation in modern
+ * Estonian. We work around this by replacing 'W' and 'w' with 'ᴡ' U+1D21 'LATIN LETTER SMALL
+ * CAPITAL W' for sortkey generation, which is collated like 'W' and is not tailored to have the
+ * same primary weight as 'V' in Estonian.
+ */
+class CollationEt extends IcuCollation {
+ function __construct() {
+ parent::__construct( 'et' );
+ }
+
+ private static function mangle( $string ) {
+ return str_replace(
+ array( 'w', 'W' ),
+ 'ᴡ', // U+1D21 'LATIN LETTER SMALL CAPITAL W'
+ $string
+ );
+ }
+
+ private static function unmangle( $string ) {
+ // Casing data is lost…
+ return str_replace(
+ 'ᴡ', // U+1D21 'LATIN LETTER SMALL CAPITAL W'
+ 'W',
+ $string
+ );
+ }
+
+ function getSortKey( $string ) {
+ return parent::getSortKey( self::mangle( $string ) );
+ }
+
+ function getFirstLetter( $string ) {
+ return self::unmangle( parent::getFirstLetter( self::mangle( $string ) ) );
+ }
+}
diff --git a/includes/ConfEditor.php b/includes/ConfEditor.php
deleted file mode 100644
index 67cb87db..00000000
--- a/includes/ConfEditor.php
+++ /dev/null
@@ -1,1109 +0,0 @@
-<?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:
- * * A next state stack, which determines the state the machine will progress to next
- * * A path stack, which keeps track of the logical location in the file.
- *
- * Reference grammar:
- *
- * file = T_OPEN_TAG *statement
- * statement = T_VARIABLE "=" expression ";"
- * expression = array / scalar / T_VARIABLE
- * array = T_ARRAY "(" [ element *( "," element ) [ "," ] ] ")"
- * element = assoc-element / expression
- * assoc-element = scalar T_DOUBLE_ARROW expression
- * scalar = T_LNUMBER / T_DNUMBER / T_STRING / T_CONSTANT_ENCAPSED_STRING
- */
-class ConfEditor {
- /** The text to parse */
- var $text;
-
- /** The token array from token_get_all() */
- var $tokens;
-
- /** The current position in the token array */
- var $pos;
-
- /** The current 1-based line number */
- var $lineNum;
-
- /** The current 1-based column number */
- var $colNum;
-
- /** The current 0-based byte number */
- var $byteNum;
-
- /** The current ConfEditorToken object */
- var $currentToken;
-
- /** The previous ConfEditorToken object */
- var $prevToken;
-
- /**
- * The state machine stack. This is an array of strings where the topmost
- * element will be popped off and become the next parser state.
- */
- var $stateStack;
-
- /**
- * The path stack is a stack of associative arrays with the following elements:
- * name The name of top level of the path
- * level The level (number of elements) of the path
- * startByte The byte offset of the start of the path
- * startToken The token offset of the start
- * endByte The byte offset of thee
- * endToken The token offset of the end, plus one
- * valueStartToken The start token offset of the value part
- * valueStartByte The start byte offset of the value part
- * valueEndToken The end token offset of the value part, plus one
- * valueEndByte The end byte offset of the value part, plus one
- * nextArrayIndex The next numeric array index at this level
- * hasComma True if the array element ends with a comma
- * arrowByte The byte offset of the "=>", or false if there isn't one
- */
- var $pathStack;
-
- /**
- * The elements of the top of the pathStack for every path encountered, indexed
- * by slash-separated path.
- */
- var $pathInfo;
-
- /**
- * Next serial number for whitespace placeholder paths (\@extra-N)
- */
- var $serial;
-
- /**
- * Editor state. This consists of the internal copy/insert operations which
- * are applied to the source string to obtain the destination string.
- */
- var $edits;
-
- /**
- * Simple entry point for command-line testing
- *
- * @param $text string
- *
- * @return string
- */
- static function test( $text ) {
- try {
- $ce = new self( $text );
- $ce->parse();
- } catch ( ConfEditorParseError $e ) {
- return $e->getMessage() . "\n" . $e->highlight( $text );
- }
- return "OK";
- }
-
- /**
- * Construct a new parser
- */
- public function __construct( $text ) {
- $this->text = $text;
- }
-
- /**
- * Edit the text. Returns the edited text.
- * @param array $ops of operations.
- *
- * Operations are given as an associative array, with members:
- * type: One of delete, set, append or insert (required)
- * path: The path to operate on (required)
- * key: The array key to insert/append, with PHP quotes
- * value: The value, with PHP quotes
- *
- * delete
- * Deletes an array element or statement with the specified path.
- * e.g.
- * array('type' => 'delete', 'path' => '$foo/bar/baz' )
- * is equivalent to the runtime PHP code:
- * unset( $foo['bar']['baz'] );
- *
- * set
- * Sets the value of an array element. If the element doesn't exist, it
- * is appended to the array. If it does exist, the value is set, with
- * comments and indenting preserved.
- *
- * append
- * Appends a new element to the end of the array. Adds a trailing comma.
- * e.g.
- * array( 'type' => 'append', 'path', '$foo/bar',
- * 'key' => 'baz', 'value' => "'x'" )
- * is like the PHP code:
- * $foo['bar']['baz'] = 'x';
- *
- * insert
- * Insert a new element at the start of the array.
- *
- * @throws MWException
- * @return string
- */
- public function edit( $ops ) {
- $this->parse();
-
- $this->edits = array(
- array( 'copy', 0, strlen( $this->text ) )
- );
- foreach ( $ops as $op ) {
- $type = $op['type'];
- $path = $op['path'];
- $value = isset( $op['value'] ) ? $op['value'] : null;
- $key = isset( $op['key'] ) ? $op['key'] : null;
-
- switch ( $type ) {
- case 'delete':
- list( $start, $end ) = $this->findDeletionRegion( $path );
- $this->replaceSourceRegion( $start, $end, false );
- break;
- case 'set':
- if ( isset( $this->pathInfo[$path] ) ) {
- list( $start, $end ) = $this->findValueRegion( $path );
- $encValue = $value; // var_export( $value, true );
- $this->replaceSourceRegion( $start, $end, $encValue );
- break;
- }
- // No existing path, fall through to append
- $slashPos = strrpos( $path, '/' );
- $key = var_export( substr( $path, $slashPos + 1 ), true );
- $path = substr( $path, 0, $slashPos );
- // Fall through
- case 'append':
- // Find the last array element
- $lastEltPath = $this->findLastArrayElement( $path );
- if ( $lastEltPath === false ) {
- throw new MWException( "Can't find any element of array \"$path\"" );
- }
- $lastEltInfo = $this->pathInfo[$lastEltPath];
-
- // Has it got a comma already?
- if ( strpos( $lastEltPath, '@extra' ) === false && !$lastEltInfo['hasComma'] ) {
- // No comma, insert one after the value region
- list( , $end ) = $this->findValueRegion( $lastEltPath );
- $this->replaceSourceRegion( $end - 1, $end - 1, ',' );
- }
-
- // Make the text to insert
- list( $start, $end ) = $this->findDeletionRegion( $lastEltPath );
-
- if ( $key === null ) {
- list( $indent, ) = $this->getIndent( $start );
- $textToInsert = "$indent$value,";
- } else {
- list( $indent, $arrowIndent ) =
- $this->getIndent( $start, $key, $lastEltInfo['arrowByte'] );
- $textToInsert = "$indent$key$arrowIndent=> $value,";
- }
- $textToInsert .= ( $indent === false ? ' ' : "\n" );
-
- // Insert the item
- $this->replaceSourceRegion( $end, $end, $textToInsert );
- break;
- case 'insert':
- // Find first array element
- $firstEltPath = $this->findFirstArrayElement( $path );
- if ( $firstEltPath === false ) {
- throw new MWException( "Can't find array element of \"$path\"" );
- }
- list( $start, ) = $this->findDeletionRegion( $firstEltPath );
- $info = $this->pathInfo[$firstEltPath];
-
- // Make the text to insert
- if ( $key === null ) {
- list( $indent, ) = $this->getIndent( $start );
- $textToInsert = "$indent$value,";
- } else {
- list( $indent, $arrowIndent ) =
- $this->getIndent( $start, $key, $info['arrowByte'] );
- $textToInsert = "$indent$key$arrowIndent=> $value,";
- }
- $textToInsert .= ( $indent === false ? ' ' : "\n" );
-
- // Insert the item
- $this->replaceSourceRegion( $start, $start, $textToInsert );
- break;
- default:
- throw new MWException( "Unrecognised operation: \"$type\"" );
- }
- }
-
- // Do the edits
- $out = '';
- foreach ( $this->edits as $edit ) {
- if ( $edit[0] == 'copy' ) {
- $out .= substr( $this->text, $edit[1], $edit[2] - $edit[1] );
- } else { // if ( $edit[0] == 'insert' )
- $out .= $edit[1];
- }
- }
-
- // Do a second parse as a sanity check
- $this->text = $out;
- try {
- $this->parse();
- } catch ( ConfEditorParseError $e ) {
- throw new MWException(
- "Sorry, ConfEditor broke the file during editing and it won't parse anymore: " .
- $e->getMessage() );
- }
- return $out;
- }
-
- /**
- * Get the variables defined in the text
- * @return array( varname => value )
- */
- function getVars() {
- $vars = array();
- $this->parse();
- foreach ( $this->pathInfo as $path => $data ) {
- if ( $path[0] != '$' ) {
- continue;
- }
- $trimmedPath = substr( $path, 1 );
- $name = $data['name'];
- if ( $name[0] == '@' ) {
- continue;
- }
- if ( $name[0] == '$' ) {
- $name = substr( $name, 1 );
- }
- $parentPath = substr( $trimmedPath, 0,
- strlen( $trimmedPath ) - strlen( $name ) );
- if ( substr( $parentPath, -1 ) == '/' ) {
- $parentPath = substr( $parentPath, 0, -1 );
- }
-
- $value = substr( $this->text, $data['valueStartByte'],
- $data['valueEndByte'] - $data['valueStartByte']
- );
- $this->setVar( $vars, $parentPath, $name,
- $this->parseScalar( $value ) );
- }
- return $vars;
- }
-
- /**
- * Set a value in an array, unless it's set already. For instance,
- * setVar( $arr, 'foo/bar', 'baz', 3 ); will set
- * $arr['foo']['bar']['baz'] = 3;
- * @param $array array
- * @param string $path slash-delimited path
- * @param $key mixed Key
- * @param $value mixed Value
- */
- function setVar( &$array, $path, $key, $value ) {
- $pathArr = explode( '/', $path );
- $target =& $array;
- if ( $path !== '' ) {
- foreach ( $pathArr as $p ) {
- if ( !isset( $target[$p] ) ) {
- $target[$p] = array();
- }
- $target =& $target[$p];
- }
- }
- if ( !isset( $target[$key] ) ) {
- $target[$key] = $value;
- }
- }
-
- /**
- * Parse a scalar value in PHP
- * @return mixed Parsed value
- */
- function parseScalar( $str ) {
- if ( $str !== '' && $str[0] == '\'' ) {
- // Single-quoted string
- // @todo FIXME: trim() call is due to mystery bug where whitespace gets
- // appended to the token; without it we ended up reading in the
- // extra quote on the end!
- return strtr( substr( trim( $str ), 1, -1 ),
- array( '\\\'' => '\'', '\\\\' => '\\' ) );
- }
- if ( $str !== '' && $str[0] == '"' ) {
- // Double-quoted string
- // @todo FIXME: trim() call is due to mystery bug where whitespace gets
- // appended to the token; without it we ended up reading in the
- // extra quote on the end!
- return stripcslashes( substr( trim( $str ), 1, -1 ) );
- }
- if ( substr( $str, 0, 4 ) == 'true' ) {
- return true;
- }
- if ( substr( $str, 0, 5 ) == 'false' ) {
- return false;
- }
- if ( substr( $str, 0, 4 ) == 'null' ) {
- return null;
- }
- // Must be some kind of numeric value, so let PHP's weak typing
- // be useful for a change
- return $str;
- }
-
- /**
- * Replace the byte offset region of the source with $newText.
- * Works by adding elements to the $this->edits array.
- */
- function replaceSourceRegion( $start, $end, $newText = false ) {
- // Split all copy operations with a source corresponding to the region
- // in question.
- $newEdits = array();
- foreach ( $this->edits as $edit ) {
- if ( $edit[0] !== 'copy' ) {
- $newEdits[] = $edit;
- continue;
- }
- $copyStart = $edit[1];
- $copyEnd = $edit[2];
- if ( $start >= $copyEnd || $end <= $copyStart ) {
- // Outside this region
- $newEdits[] = $edit;
- continue;
- }
- if ( ( $start < $copyStart && $end > $copyStart )
- || ( $start < $copyEnd && $end > $copyEnd )
- ) {
- throw new MWException( "Overlapping regions found, can't do the edit" );
- }
- // Split the copy
- $newEdits[] = array( 'copy', $copyStart, $start );
- if ( $newText !== false ) {
- $newEdits[] = array( 'insert', $newText );
- }
- $newEdits[] = array( 'copy', $end, $copyEnd );
- }
- $this->edits = $newEdits;
- }
-
- /**
- * 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.
- * @param $pathName
- * @throws MWException
- * @return array
- */
- function findDeletionRegion( $pathName ) {
- if ( !isset( $this->pathInfo[$pathName] ) ) {
- throw new MWException( "Can't find path \"$pathName\"" );
- }
- $path = $this->pathInfo[$pathName];
- // Find the start
- $this->firstToken();
- while ( $this->pos != $path['startToken'] ) {
- $this->nextToken();
- }
- $regionStart = $path['startByte'];
- for ( $offset = -1; $offset >= -$this->pos; $offset-- ) {
- $token = $this->getTokenAhead( $offset );
- if ( !$token->isSkip() ) {
- // If there is other content on the same line, don't move the start point
- // back, because that will cause the regions to overlap.
- $regionStart = $path['startByte'];
- break;
- }
- $lfPos = strrpos( $token->text, "\n" );
- if ( $lfPos === false ) {
- $regionStart -= strlen( $token->text );
- } else {
- // The line start does not include the LF
- $regionStart -= strlen( $token->text ) - $lfPos - 1;
- break;
- }
- }
- // Find the end
- while ( $this->pos != $path['endToken'] ) {
- $this->nextToken();
- }
- $regionEnd = $path['endByte']; // past the end
- for ( $offset = 0; $offset < count( $this->tokens ) - $this->pos; $offset++ ) {
- $token = $this->getTokenAhead( $offset );
- if ( !$token->isSkip() ) {
- break;
- }
- $lfPos = strpos( $token->text, "\n" );
- if ( $lfPos === false ) {
- $regionEnd += strlen( $token->text );
- } else {
- // This should point past the LF
- $regionEnd += $lfPos + 1;
- break;
- }
- }
- return array( $regionStart, $regionEnd );
- }
-
- /**
- * Find the byte region in the source corresponding to the value part.
- * This includes the quotes, but does not include the trailing comma
- * or semicolon.
- *
- * The end position is the past-the-end (end + 1) value as per convention.
- * @param $pathName
- * @throws MWException
- * @return array
- */
- function findValueRegion( $pathName ) {
- if ( !isset( $this->pathInfo[$pathName] ) ) {
- throw new MWException( "Can't find path \"$pathName\"" );
- }
- $path = $this->pathInfo[$pathName];
- if ( $path['valueStartByte'] === false || $path['valueEndByte'] === false ) {
- throw new MWException( "Can't find value region for path \"$pathName\"" );
- }
- return array( $path['valueStartByte'], $path['valueEndByte'] );
- }
-
- /**
- * 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
- $lastEltPath = false;
- foreach ( $this->pathInfo as $candidatePath => $info ) {
- $part1 = substr( $candidatePath, 0, strlen( $path ) + 1 );
- $part2 = substr( $candidatePath, strlen( $path ) + 1, 1 );
- if ( $part2 == '@' ) {
- // Do nothing
- } elseif ( $part1 == "$path/" ) {
- $lastEltPath = $candidatePath;
- } elseif ( $lastEltPath !== false ) {
- break;
- }
- }
- if ( $lastEltPath !== false ) {
- return $lastEltPath;
- }
-
- // Try for an interstitial element
- $extraPath = false;
- foreach ( $this->pathInfo as $candidatePath => $info ) {
- $part1 = substr( $candidatePath, 0, strlen( $path ) + 1 );
- if ( $part1 == "$path/" ) {
- $extraPath = $candidatePath;
- } elseif ( $extraPath !== false ) {
- break;
- }
- }
- return $extraPath;
- }
-
- /**
- * 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
- foreach ( $this->pathInfo as $candidatePath => $info ) {
- $part1 = substr( $candidatePath, 0, strlen( $path ) + 1 );
- $part2 = substr( $candidatePath, strlen( $path ) + 1, 1 );
- if ( $part1 == "$path/" && $part2 != '@' ) {
- return $candidatePath;
- }
- }
-
- // Try for an interstitial element
- foreach ( $this->pathInfo as $candidatePath => $info ) {
- $part1 = substr( $candidatePath, 0, strlen( $path ) + 1 );
- if ( $part1 == "$path/" ) {
- return $candidatePath;
- }
- }
- return false;
- }
-
- /**
- * 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 = ' ';
- if ( $pos == 0 || $this->text[$pos - 1] == "\n" ) {
- $indentLength = strspn( $this->text, " \t", $pos );
- $indent = substr( $this->text, $pos, $indentLength );
- } else {
- $indent = false;
- }
- if ( $indent !== false && $arrowPos !== false ) {
- $arrowIndentLength = $arrowPos - $pos - $indentLength - strlen( $key );
- if ( $arrowIndentLength > 0 ) {
- $arrowIndent = str_repeat( ' ', $arrowIndentLength );
- }
- }
- return array( $indent, $arrowIndent );
- }
-
- /**
- * Run the parser on the text. Throws an exception if the string does not
- * match our defined subset of PHP syntax.
- */
- public function parse() {
- $this->initParse();
- $this->pushState( 'file' );
- $this->pushPath( '@extra-' . ( $this->serial++ ) );
- $token = $this->firstToken();
-
- while ( !$token->isEnd() ) {
- $state = $this->popState();
- if ( !$state ) {
- $this->error( 'internal error: empty state stack' );
- }
-
- switch ( $state ) {
- case 'file':
- $this->expect( T_OPEN_TAG );
- $token = $this->skipSpace();
- if ( $token->isEnd() ) {
- break 2;
- }
- $this->pushState( 'statement', 'file 2' );
- break;
- case 'file 2':
- $token = $this->skipSpace();
- if ( $token->isEnd() ) {
- break 2;
- }
- $this->pushState( 'statement', 'file 2' );
- break;
- case 'statement':
- $token = $this->skipSpace();
- if ( !$this->validatePath( $token->text ) ) {
- $this->error( "Invalid variable name \"{$token->text}\"" );
- }
- $this->nextPath( $token->text );
- $this->expect( T_VARIABLE );
- $this->skipSpace();
- $arrayAssign = false;
- if ( $this->currentToken()->type == '[' ) {
- $this->nextToken();
- $token = $this->skipSpace();
- if ( !$token->isScalar() ) {
- $this->error( "expected a string or number for the array key" );
- }
- if ( $token->type == T_CONSTANT_ENCAPSED_STRING ) {
- $text = $this->parseScalar( $token->text );
- } else {
- $text = $token->text;
- }
- if ( !$this->validatePath( $text ) ) {
- $this->error( "Invalid associative array name \"$text\"" );
- }
- $this->pushPath( $text );
- $this->nextToken();
- $this->skipSpace();
- $this->expect( ']' );
- $this->skipSpace();
- $arrayAssign = true;
- }
- $this->expect( '=' );
- $this->skipSpace();
- $this->startPathValue();
- if ( $arrayAssign ) {
- $this->pushState( 'expression', 'array assign end' );
- } else {
- $this->pushState( 'expression', 'statement end' );
- }
- break;
- case 'array assign end':
- case 'statement end':
- $this->endPathValue();
- if ( $state == 'array assign end' ) {
- $this->popPath();
- }
- $this->skipSpace();
- $this->expect( ';' );
- $this->nextPath( '@extra-' . ( $this->serial++ ) );
- break;
- case 'expression':
- $token = $this->skipSpace();
- if ( $token->type == T_ARRAY ) {
- $this->pushState( 'array' );
- } elseif ( $token->isScalar() ) {
- $this->nextToken();
- } elseif ( $token->type == T_VARIABLE ) {
- $this->nextToken();
- } else {
- $this->error( "expected simple expression" );
- }
- break;
- case 'array':
- $this->skipSpace();
- $this->expect( T_ARRAY );
- $this->skipSpace();
- $this->expect( '(' );
- $this->skipSpace();
- $this->pushPath( '@extra-' . ( $this->serial++ ) );
- if ( $this->isAhead( ')' ) ) {
- // Empty array
- $this->pushState( 'array end' );
- } else {
- $this->pushState( 'element', 'array end' );
- }
- break;
- case 'array end':
- $this->skipSpace();
- $this->popPath();
- $this->expect( ')' );
- break;
- case 'element':
- $token = $this->skipSpace();
- // Look ahead to find the double arrow
- if ( $token->isScalar() && $this->isAhead( T_DOUBLE_ARROW, 1 ) ) {
- // Found associative element
- $this->pushState( 'assoc-element', 'element end' );
- } else {
- // Not associative
- $this->nextPath( '@next' );
- $this->startPathValue();
- $this->pushState( 'expression', 'element end' );
- }
- break;
- case 'element end':
- $token = $this->skipSpace();
- if ( $token->type == ',' ) {
- $this->endPathValue();
- $this->markComma();
- $this->nextToken();
- $this->nextPath( '@extra-' . ( $this->serial++ ) );
- // Look ahead to find ending bracket
- if ( $this->isAhead( ")" ) ) {
- // Found ending bracket, no continuation
- $this->skipSpace();
- } else {
- // No ending bracket, continue to next element
- $this->pushState( 'element' );
- }
- } elseif ( $token->type == ')' ) {
- // End array
- $this->endPathValue();
- } else {
- $this->error( "expected the next array element or the end of the array" );
- }
- break;
- case 'assoc-element':
- $token = $this->skipSpace();
- if ( !$token->isScalar() ) {
- $this->error( "expected a string or number for the array key" );
- }
- if ( $token->type == T_CONSTANT_ENCAPSED_STRING ) {
- $text = $this->parseScalar( $token->text );
- } else {
- $text = $token->text;
- }
- if ( !$this->validatePath( $text ) ) {
- $this->error( "Invalid associative array name \"$text\"" );
- }
- $this->nextPath( $text );
- $this->nextToken();
- $this->skipSpace();
- $this->markArrow();
- $this->expect( T_DOUBLE_ARROW );
- $this->skipSpace();
- $this->startPathValue();
- $this->pushState( 'expression' );
- break;
- }
- }
- if ( count( $this->stateStack ) ) {
- $this->error( 'unexpected end of file' );
- }
- $this->popPath();
- }
-
- /**
- * Initialise a parse.
- */
- protected function initParse() {
- $this->tokens = token_get_all( $this->text );
- $this->stateStack = array();
- $this->pathStack = array();
- $this->firstToken();
- $this->pathInfo = array();
- $this->serial = 1;
- }
-
- /**
- * Set the parse position. Do not call this except from firstToken() and
- * nextToken(), there is more to update than just the position.
- */
- protected function setPos( $pos ) {
- $this->pos = $pos;
- if ( $this->pos >= count( $this->tokens ) ) {
- $this->currentToken = ConfEditorToken::newEnd();
- } else {
- $this->currentToken = $this->newTokenObj( $this->tokens[$this->pos] );
- }
- return $this->currentToken;
- }
-
- /**
- * Create a ConfEditorToken from an element of token_get_all()
- * @return ConfEditorToken
- */
- function newTokenObj( $internalToken ) {
- if ( is_array( $internalToken ) ) {
- return new ConfEditorToken( $internalToken[0], $internalToken[1] );
- } else {
- return new ConfEditorToken( $internalToken, $internalToken );
- }
- }
-
- /**
- * Reset the parse position
- */
- function firstToken() {
- $this->setPos( 0 );
- $this->prevToken = ConfEditorToken::newEnd();
- $this->lineNum = 1;
- $this->colNum = 1;
- $this->byteNum = 0;
- return $this->currentToken;
- }
-
- /**
- * Get the current token
- */
- function currentToken() {
- return $this->currentToken;
- }
-
- /**
- * Advance the current position and return the resulting next token
- */
- function nextToken() {
- if ( $this->currentToken ) {
- $text = $this->currentToken->text;
- $lfCount = substr_count( $text, "\n" );
- if ( $lfCount ) {
- $this->lineNum += $lfCount;
- $this->colNum = strlen( $text ) - strrpos( $text, "\n" );
- } else {
- $this->colNum += strlen( $text );
- }
- $this->byteNum += strlen( $text );
- }
- $this->prevToken = $this->currentToken;
- $this->setPos( $this->pos + 1 );
- return $this->currentToken;
- }
-
- /**
- * 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;
- if ( $pos >= count( $this->tokens ) || $pos < 0 ) {
- return ConfEditorToken::newEnd();
- } else {
- return $this->newTokenObj( $this->tokens[$pos] );
- }
- }
-
- /**
- * Advances the current position past any whitespace or comments
- */
- function skipSpace() {
- while ( $this->currentToken && $this->currentToken->isSkip() ) {
- $this->nextToken();
- }
- return $this->currentToken;
- }
-
- /**
- * Throws an error if the current token is not of the given type, and
- * then advances to the next position.
- */
- function expect( $type ) {
- if ( $this->currentToken && $this->currentToken->type == $type ) {
- return $this->nextToken();
- } else {
- $this->error( "expected " . $this->getTypeName( $type ) .
- ", got " . $this->getTypeName( $this->currentToken->type ) );
- }
- }
-
- /**
- * Push a state or two on to the state stack.
- */
- function pushState( $nextState, $stateAfterThat = null ) {
- if ( $stateAfterThat !== null ) {
- $this->stateStack[] = $stateAfterThat;
- }
- $this->stateStack[] = $nextState;
- }
-
- /**
- * Pop a state from the state stack.
- * @return mixed
- */
- function popState() {
- return array_pop( $this->stateStack );
- }
-
- /**
- * 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 ) != '@';
- }
-
- /**
- * Internal function to update some things at the end of a path region. Do
- * not call except from popPath() or nextPath().
- */
- function endPath() {
- $key = '';
- foreach ( $this->pathStack as $pathInfo ) {
- if ( $key !== '' ) {
- $key .= '/';
- }
- $key .= $pathInfo['name'];
- }
- $pathInfo['endByte'] = $this->byteNum;
- $pathInfo['endToken'] = $this->pos;
- $this->pathInfo[$key] = $pathInfo;
- }
-
- /**
- * Go up to a new path level, for example at the start of an array.
- */
- function pushPath( $path ) {
- $this->pathStack[] = array(
- 'name' => $path,
- 'level' => count( $this->pathStack ) + 1,
- 'startByte' => $this->byteNum,
- 'startToken' => $this->pos,
- 'valueStartToken' => false,
- 'valueStartByte' => false,
- 'valueEndToken' => false,
- 'valueEndByte' => false,
- 'nextArrayIndex' => 0,
- 'hasComma' => false,
- 'arrowByte' => false
- );
- }
-
- /**
- * Go down a path level, for example at the end of an array.
- */
- function popPath() {
- $this->endPath();
- array_pop( $this->pathStack );
- }
-
- /**
- * Go to the next path on the same level. This ends the current path and
- * starts a new one. If $path is \@next, the new path is set to the next
- * numeric array element.
- */
- function nextPath( $path ) {
- $this->endPath();
- $i = count( $this->pathStack ) - 1;
- if ( $path == '@next' ) {
- $nextArrayIndex =& $this->pathStack[$i]['nextArrayIndex'];
- $this->pathStack[$i]['name'] = $nextArrayIndex;
- $nextArrayIndex++;
- } else {
- $this->pathStack[$i]['name'] = $path;
- }
- $this->pathStack[$i] =
- array(
- 'startByte' => $this->byteNum,
- 'startToken' => $this->pos,
- 'valueStartToken' => false,
- 'valueStartByte' => false,
- 'valueEndToken' => false,
- 'valueEndByte' => false,
- 'hasComma' => false,
- 'arrowByte' => false,
- ) + $this->pathStack[$i];
- }
-
- /**
- * Mark the start of the value part of a path.
- */
- function startPathValue() {
- $path =& $this->pathStack[count( $this->pathStack ) - 1];
- $path['valueStartToken'] = $this->pos;
- $path['valueStartByte'] = $this->byteNum;
- }
-
- /**
- * Mark the end of the value part of a path.
- */
- function endPathValue() {
- $path =& $this->pathStack[count( $this->pathStack ) - 1];
- $path['valueEndToken'] = $this->pos;
- $path['valueEndByte'] = $this->byteNum;
- }
-
- /**
- * Mark the comma separator in an array element
- */
- function markComma() {
- $path =& $this->pathStack[count( $this->pathStack ) - 1];
- $path['hasComma'] = true;
- }
-
- /**
- * Mark the arrow separator in an associative array element
- */
- function markArrow() {
- $path =& $this->pathStack[count( $this->pathStack ) - 1];
- $path['arrowByte'] = $this->byteNum;
- }
-
- /**
- * Generate a parse error
- */
- function error( $msg ) {
- throw new ConfEditorParseError( $this, $msg );
- }
-
- /**
- * Get a readable name for the given token type.
- * @return string
- */
- function getTypeName( $type ) {
- if ( is_int( $type ) ) {
- return token_name( $type );
- } else {
- return "\"$type\"";
- }
- }
-
- /**
- * 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;
- $token = $this->getTokenAhead( $offset );
- while ( !$token->isEnd() ) {
- if ( $token->isSkip() ) {
- $ahead++;
- $token = $this->getTokenAhead( $ahead );
- continue;
- } elseif ( $token->type == $type ) {
- // Found the type
- return true;
- } else {
- // Not found
- return false;
- }
- }
- return false;
- }
-
- /**
- * Get the previous token object
- */
- function prevToken() {
- return $this->prevToken;
- }
-
- /**
- * Echo a reasonably readable representation of the tokenizer array.
- */
- function dumpTokens() {
- $out = '';
- foreach ( $this->tokens as $token ) {
- $obj = $this->newTokenObj( $token );
- $out .= sprintf( "%-28s %s\n",
- $this->getTypeName( $obj->type ),
- addcslashes( $obj->text, "\0..\37" ) );
- }
- echo "<pre>" . htmlspecialchars( $out ) . "</pre>";
- }
-}
-
-/**
- * Exception class for parse errors
- */
-class ConfEditorParseError extends MWException {
- var $lineNum, $colNum;
- function __construct( $editor, $msg ) {
- $this->lineNum = $editor->lineNum;
- $this->colNum = $editor->colNum;
- parent::__construct( "Parse error on line {$editor->lineNum} " .
- "col {$editor->colNum}: $msg" );
- }
-
- function highlight( $text ) {
- $lines = StringUtils::explode( "\n", $text );
- foreach ( $lines as $lineNum => $line ) {
- if ( $lineNum == $this->lineNum - 1 ) {
- return "$line\n" . str_repeat( ' ', $this->colNum - 1 ) . "^\n";
- }
- }
- return '';
- }
-
-}
-
-/**
- * Class to wrap a token from the tokenizer.
- */
-class ConfEditorToken {
- var $type, $text;
-
- static $scalarTypes = array( T_LNUMBER, T_DNUMBER, T_STRING, T_CONSTANT_ENCAPSED_STRING );
- static $skipTypes = array( T_WHITESPACE, T_COMMENT, T_DOC_COMMENT );
-
- static function newEnd() {
- return new self( 'END', '' );
- }
-
- function __construct( $type, $text ) {
- $this->type = $type;
- $this->text = $text;
- }
-
- function isSkip() {
- return in_array( $this->type, self::$skipTypes );
- }
-
- function isScalar() {
- return in_array( $this->type, self::$scalarTypes );
- }
-
- function isEnd() {
- return $this->type == 'END';
- }
-}
diff --git a/includes/Cookie.php b/includes/Cookie.php
index ecf4667d..cb041904 100644
--- a/includes/Cookie.php
+++ b/includes/Cookie.php
@@ -43,8 +43,8 @@ class Cookie {
* cookies. Used internally after a request to parse the
* Set-Cookie headers.
*
- * @param string $value the value of the cookie
- * @param array $attr possible key/values:
+ * @param string $value The value of the cookie
+ * @param array $attr Possible key/values:
* expires A date string
* path The path this cookie is used on
* domain Domain this cookie is used on
@@ -85,18 +85,21 @@ class Cookie {
* @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 string $domain the domain to validate
+ * @param string $domain The domain to validate
* @param string $originDomain (optional) the domain the cookie originates from
- * @return Boolean
+ * @return bool
*/
public static function validateCookieDomain( $domain, $originDomain = null ) {
- // Don't allow a trailing dot
- if ( substr( $domain, -1 ) == '.' ) {
+ $dc = explode( ".", $domain );
+
+ // Don't allow a trailing dot or addresses without a or just a leading dot
+ if ( substr( $domain, -1 ) == '.' ||
+ count( $dc ) <= 1 ||
+ count( $dc ) == 2 && $dc[0] === ''
+ ) {
return false;
}
- $dc = explode( ".", $domain );
-
// Only allow full, valid IP addresses
if ( preg_match( '/^[0-9.]+$/', $domain ) ) {
if ( count( $dc ) != 4 ) {
@@ -131,8 +134,14 @@ class Cookie {
}
if ( substr( $domain, 0, 1 ) == '.'
- && substr_compare( $originDomain, $domain, -strlen( $domain ),
- strlen( $domain ), true ) != 0 ) {
+ && substr_compare(
+ $originDomain,
+ $domain,
+ -strlen( $domain ),
+ strlen( $domain ),
+ true
+ ) != 0
+ ) {
return false;
}
}
@@ -143,9 +152,9 @@ class Cookie {
/**
* Serialize the cookie jar into a format useful for HTTP Request headers.
*
- * @param string $path the path that will be used. Required.
- * @param string $domain the domain that will be used. Required.
- * @return String
+ * @param string $path The path that will be used. Required.
+ * @param string $domain The domain that will be used. Required.
+ * @return string
*/
public function serializeToHttpRequest( $path, $domain ) {
$ret = '';
@@ -160,15 +169,22 @@ class Cookie {
}
/**
- * @param $domain
+ * @param string $domain
* @return bool
*/
protected function canServeDomain( $domain ) {
if ( $domain == $this->domain
|| ( strlen( $domain ) > strlen( $this->domain )
&& substr( $this->domain, 0, 1 ) == '.'
- && substr_compare( $domain, $this->domain, -strlen( $this->domain ),
- strlen( $this->domain ), true ) == 0 ) ) {
+ && substr_compare(
+ $domain,
+ $this->domain,
+ -strlen( $this->domain ),
+ strlen( $this->domain ),
+ true
+ ) == 0
+ )
+ ) {
return true;
}
@@ -176,7 +192,7 @@ class Cookie {
}
/**
- * @param $path
+ * @param string $path
* @return bool
*/
protected function canServePath( $path ) {
@@ -197,6 +213,9 @@ class CookieJar {
/**
* Set a cookie in the cookie jar. Make sure only one cookie per-name exists.
* @see Cookie::set()
+ * @param string $name
+ * @param string $value
+ * @param array $attr
*/
public function setCookie( $name, $value, $attr ) {
/* cookies: case insensitive, so this should work.
@@ -213,6 +232,8 @@ class CookieJar {
/**
* @see Cookie::serializeToHttpRequest
+ * @param string $path
+ * @param string $domain
* @return string
*/
public function serializeToHttpRequest( $path, $domain ) {
@@ -232,8 +253,8 @@ class CookieJar {
/**
* Parse the content of an Set-Cookie HTTP Response header.
*
- * @param $cookie String
- * @param string $domain cookie's domain
+ * @param string $cookie
+ * @param string $domain Cookie's domain
* @return null
*/
public function parseCookieResponseHeader( $cookie, $domain ) {
diff --git a/includes/DefaultSettings.php b/includes/DefaultSettings.php
index 78568107..71268932 100644
--- a/includes/DefaultSettings.php
+++ b/includes/DefaultSettings.php
@@ -15,7 +15,7 @@
* performed in LocalSettings.php.
*
* Documentation is in the source and on:
- * http://www.mediawiki.org/wiki/Manual:Configuration_settings
+ * https://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.
@@ -60,10 +60,22 @@ if ( !defined( 'MEDIAWIKI' ) ) {
$wgConf = new SiteConfiguration;
/**
+ * Registry of factory functions to create config objects:
+ * The 'main' key must be set, and the value should be a valid
+ * callable.
+ * @since 1.23
+ */
+$wgConfigRegistry = array(
+ 'main' => 'GlobalVarConfig::newInstance'
+);
+
+/**
* MediaWiki version number
+ * Note that MediaWikiVersionFetcher::fetchVersion() uses a regex to check this.
+ * Using single quotes is, therefore, important here.
* @since 1.2
*/
-$wgVersion = '1.22.15';
+$wgVersion = '1.24.1';
/**
* Name of the site. It must be changed in LocalSettings.php
@@ -97,6 +109,13 @@ $wgServer = WebRequest::detectServer();
*/
$wgCanonicalServer = false;
+/**
+ * Server name. This is automatically computed by parsing the bare
+ * hostname out of $wgCanonicalServer. It should not be customized.
+ * @since 1.24
+ */
+$wgServerName = false;
+
/************************************************************************//**
* @name Script path settings
* @{
@@ -236,7 +255,7 @@ $wgFileCacheDirectory = false;
/**
* The URL path of the wiki logo. The logo size should be 135x135 pixels.
- * Defaults to "{$wgStylePath}/common/images/wiki.png".
+ * Defaults to "$wgResourceBasePath/resources/assets/wiki.png".
*/
$wgLogo = false;
@@ -339,11 +358,6 @@ $wgEnableAsyncUploads = false;
$wgIllegalFileChars = ":";
/**
- * @deprecated since 1.17 use $wgDeletedDirectory
- */
-$wgFileStore = array();
-
-/**
* What directory to place deleted uploads in.
* Defaults to "{$wgUploadDirectory}/deleted".
*/
@@ -355,11 +369,20 @@ $wgDeletedDirectory = false;
$wgImgAuthDetails = false;
/**
- * If this is enabled, img_auth.php will not allow image access unless the wiki
- * is private. This improves security when image uploads are hosted on a
- * separate domain.
+ * Map of relative URL directories to match to internal mwstore:// base storage paths.
+ * For img_auth.php requests, everything after "img_auth.php/" is checked to see
+ * if starts with any of the prefixes defined here. The prefixes should not overlap.
+ * The prefix that matches has a corresponding storage path, which the rest of the URL
+ * is assumed to be relative to. The file at that path (or a 404) is send to the client.
+ *
+ * Example:
+ * $wgImgAuthUrlPathMap['/timeline/'] = 'mwstore://local-fs/timeline-render/';
+ * The above maps ".../img_auth.php/timeline/X" to "mwstore://local-fs/timeline-render/".
+ * The name "local-fs" should correspond by name to an entry in $wgFileBackends.
+ *
+ * @see $wgFileBackends
*/
-$wgImgAuthPublicTest = true;
+$wgImgAuthUrlPathMap = array();
/**
* File repository structures
@@ -384,8 +407,6 @@ $wgImgAuthPublicTest = true;
* url : base URL to the root of the zone
* urlsByExt : map of file extension types to base URLs
* (useful for using a different cache for videos)
- * 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.
@@ -574,7 +595,7 @@ $wgCacheSharedUploads = true;
/**
* Allow for upload to be copied from an URL.
- * The timeout for copy uploads is set by $wgHTTPTimeout.
+ * The timeout for copy uploads is set by $wgCopyUploadTimeout.
* You have to assign the user right 'upload_by_url' to a user group, to use this.
*/
$wgAllowCopyUploads = false;
@@ -739,7 +760,7 @@ $wgFileBlacklist = array(
'exe', 'scr', 'dll', 'msi', 'vbs', 'bat', 'com', 'pif', 'cmd', 'vxd', 'cpl' );
/**
- * Files with these mime types will never be allowed as uploads
+ * Files with these MIME types will never be allowed as uploads
* if $wgVerifyMimeType is enabled.
*/
$wgMimeTypeBlacklist = array(
@@ -791,7 +812,7 @@ $wgDisableUploadScriptChecks = false;
$wgUploadSizeWarning = false;
/**
- * list of trusted media-types and mime types.
+ * list of trusted media-types and MIME types.
* Use the MEDIATYPE_xxx constants to represent media types.
* This list is used by File::isSafeFile
*
@@ -839,13 +860,22 @@ $wgContentHandlers = array(
CONTENT_MODEL_WIKITEXT => 'WikitextContentHandler',
// dumb version, no syntax highlighting
CONTENT_MODEL_JAVASCRIPT => 'JavaScriptContentHandler',
+ // simple implementation, for use by extensions, etc.
+ CONTENT_MODEL_JSON => 'JsonContentHandler',
// dumb version, no syntax highlighting
CONTENT_MODEL_CSS => 'CssContentHandler',
- // plain text, for use by extensions etc
+ // plain text, for use by extensions, etc.
CONTENT_MODEL_TEXT => 'TextContentHandler',
);
/**
+ * Whether to enable server-side image thumbnailing. If false, images will
+ * always be sent to the client in full resolution, with appropriate width= and
+ * height= attributes on the <img> tag for the client to do its own scaling.
+ */
+$wgUseImageResize = true;
+
+/**
* Resizing can be done using PHP's internal image libraries or using
* ImageMagick or another third-party converter, e.g. GraphicMagick.
* These support more file formats than PHP, which only supports PNG,
@@ -861,11 +891,6 @@ $wgUseImageMagick = false;
$wgImageMagickConvertCommand = '/usr/bin/convert';
/**
- * The identify command shipped with ImageMagick
- */
-$wgImageMagickIdentifyCommand = '/usr/bin/identify';
-
-/**
* Sharpening parameter to ImageMagick
*/
$wgSharpenParameter = '0x0.4';
@@ -921,7 +946,8 @@ $wgSVGConverters = array(
'ImageMagick' => '$path/convert -background white -thumbnail $widthx$height\! $input PNG:$output',
'sodipodi' => '$path/sodipodi -z -w $width -f $input -e $output',
'inkscape' => '$path/inkscape -z -w $width -f $input -e $output',
- 'batik' => 'java -Djava.awt.headless=true -jar $path/batik-rasterizer.jar -w $width -d $output $input',
+ 'batik' => 'java -Djava.awt.headless=true -jar $path/batik-rasterizer.jar -w $width -d '
+ . '$output $input',
'rsvg' => '$path/rsvg -w $width -h $height $input $output',
'imgserv' => '$path/imgserv-wrapper -i svg -o png -w$width $input $output',
'ImagickExt' => array( 'SvgHandler::rasterizeImagickExt' ),
@@ -1008,6 +1034,14 @@ $wgTiffThumbnailType = false;
$wgThumbnailEpoch = '20030516000000';
/**
+ * Certain operations are avoided if there were too many recent failures,
+ * for example, thumbnail generation. Bump this value to invalidate all
+ * memory of failed operations and thus allow further attempts to resume.
+ * This is useful when a cause for the failures has been found and fixed.
+ */
+$wgAttemptFailureEpoch = 1;
+
+/**
* If set, inline scaled images will still produce "<img>" tags ready for
* output instead of showing an error message.
*
@@ -1035,11 +1069,6 @@ $wgGenerateThumbnailOnParse = true;
$wgShowArchiveThumbnails = true;
/**
- * Obsolete, always true, kept for compatibility with extensions
- */
-$wgUseImageResize = true;
-
-/**
* If set to true, images that contain certain the exif orientation tag will
* be rotated accordingly. If set to null, try to auto-detect whether a scaler
* is available that can rotate.
@@ -1108,45 +1137,45 @@ $wgAntivirusSetup = array(
$wgAntivirusRequired = true;
/**
- * Determines if the mime type of uploaded files should be checked
+ * Determines if the MIME type of uploaded files should be checked
*/
$wgVerifyMimeType = true;
/**
- * Sets the mime type definition file to use by MimeMagic.php.
+ * Sets the MIME type definition file to use by MimeMagic.php.
* Set to null, to use built-in defaults only.
* example: $wgMimeTypeFile = '/etc/mime.types';
*/
$wgMimeTypeFile = 'includes/mime.types';
/**
- * Sets the mime type info file to use by MimeMagic.php.
+ * Sets the MIME type info file to use by MimeMagic.php.
* Set to null, to use built-in defaults only.
*/
$wgMimeInfoFile = 'includes/mime.info';
/**
- * Sets an external mime detector program. The command must print only
- * the mime type to standard output.
+ * Sets an external MIME detector program. The command must print only
+ * 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.
+ * If not set or NULL, PHP's fileinfo extension will be used if available.
*
* @par Example:
* @code
- * #$wgMimeDetectorCommand = "file -bi"; # use external mime detector (Linux)
+ * #$wgMimeDetectorCommand = "file -bi"; # use external MIME detector (Linux)
* @endcode
*/
$wgMimeDetectorCommand = null;
/**
- * Switch for trivial mime detection. Used by thumb.php to disable all fancy
+ * Switch for trivial MIME detection. Used by thumb.php to disable all fancy
* things, because only a few types of images are needed and file extensions
* can be trusted.
*/
$wgTrivialMimeDetection = false;
/**
- * Additional XML types we can allow via mime-detection.
+ * Additional XML types we can allow via MIME-detection.
* array = ( 'rootElement' => 'associatedMimeType' )
*/
$wgXMLMimeTypes = array(
@@ -1188,6 +1217,34 @@ $wgThumbLimits = array(
);
/**
+ * When defined, is an array of image widths used as buckets for thumbnail generation.
+ * The goal is to save resources by generating thumbnails based on reference buckets instead of
+ * always using the original. This will incur a speed gain but cause a quality loss.
+ *
+ * The buckets generation is chained, with each bucket generated based on the above bucket
+ * when possible. File handlers have to opt into using that feature. For now only BitmapHandler
+ * supports it.
+ */
+$wgThumbnailBuckets = null;
+
+/**
+ * When using thumbnail buckets as defined above, this sets the minimum distance to the bucket
+ * above the requested size. The distance represents how many extra pixels of width the bucket
+ * needs in order to be used as the reference for a given thumbnail. For example, with the
+ * following buckets:
+ *
+ * $wgThumbnailBuckets = array ( 128, 256, 512 );
+ *
+ * and a distance of 50:
+ *
+ * $wgThumbnailMinimumBucketDistance = 50;
+ *
+ * If we want to render a thumbnail of width 220px, the 512px bucket will be used,
+ * because 220 + 50 = 270 and the closest bucket bigger than 270px is 512.
+ */
+$wgThumbnailMinimumBucketDistance = 50;
+
+/**
* Default parameters for the "<gallery>" tag
*/
$wgGalleryOptions = array(
@@ -1251,7 +1308,7 @@ $wgDjvuTxt = null;
* Path of the djvutoxml executable
* This works like djvudump except much, much slower as of version 3.5.
*
- * For now we 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
@@ -1265,7 +1322,7 @@ $wgDjvuToXML = null;
/**
* Shell command for the DJVU post processor
- * Default: pnmtopng, since ddjvu generates ppm output
+ * Default: pnmtojpeg, since ddjvu generates ppm output
* Set this to false to output the ppm file directly.
*/
$wgDjvuPostProcessor = 'pnmtojpeg';
@@ -1284,24 +1341,27 @@ $wgDjvuOutputExtension = 'jpg';
* @{
*/
-$serverName = substr( $wgServer, strrpos( $wgServer, '/' ) + 1 );
/**
* Site admin email address.
+ *
+ * Defaults to "wikiadmin@{$wgServerName}".
*/
-$wgEmergencyContact = 'wikiadmin@' . $serverName;
+$wgEmergencyContact = false;
/**
* Password reminder email address.
*
* The address we should use as sender when a user is requesting his password.
+ *
+ * Defaults to "apache@{$wgServerName}".
*/
-$wgPasswordSender = 'apache@' . $serverName;
-
-unset( $serverName ); # Don't leak local variables to global scope
+$wgPasswordSender = false;
/**
* Password reminder name
+ *
+ * @deprecated since 1.23; use the system message 'emailsender' instead.
*/
$wgPasswordSenderName = 'MediaWiki Mail';
@@ -1352,6 +1412,18 @@ $wgNewPasswordExpiry = 3600 * 24 * 7;
$wgUserEmailConfirmationTokenExpiry = 7 * 24 * 60 * 60;
/**
+ * The number of days that a user's password is good for. After this number of days, the
+ * user will be asked to reset their password. Set to false to disable password expiration.
+ */
+$wgPasswordExpirationDays = false;
+
+/**
+ * If a user's password is expired, the number of seconds when they can still login,
+ * and cancel their password change, but are sent to the password change form on each login.
+ */
+$wgPasswordExpireGrace = 3600 * 24 * 7; // 7 days
+
+/**
* SMTP Mode.
*
* For using a direct (authenticated) SMTP server connection.
@@ -1469,7 +1541,7 @@ $wgUsersNotifiedOnAllChanges = array();
$wgDBserver = 'localhost';
/**
- * Database port number (for PostgreSQL)
+ * Database port number (for PostgreSQL and Microsoft SQL Server).
*/
$wgDBport = 5432;
@@ -1495,11 +1567,21 @@ $wgDBtype = 'mysql';
/**
* Whether to use SSL in DB connection.
+ *
+ * This setting is only used $wgLBFactoryConf['class'] is set to
+ * 'LBFactorySimple' and $wgDBservers is an empty array; otherwise
+ * the DBO_SSL flag must be set in the 'flags' option of the database
+ * connection to achieve the same functionality.
*/
$wgDBssl = false;
/**
* Whether to use compression in DB connection.
+ *
+ * This setting is only used $wgLBFactoryConf['class'] is set to
+ * 'LBFactorySimple' and $wgDBservers is an empty array; otherwise
+ * the DBO_COMPRESS flag must be set in the 'flags' option of the database
+ * connection to achieve the same functionality.
*/
$wgDBcompress = false;
@@ -1551,7 +1633,7 @@ $wgSQLMode = '';
/**
* Mediawiki schema
*/
-$wgDBmwschema = 'mediawiki';
+$wgDBmwschema = null;
/**
* To override default SQLite data directory ($docroot/../data)
@@ -1582,10 +1664,10 @@ $wgAllDBsAreLocalhost = false;
* $wgSharedPrefix is the table prefix for the shared database. It defaults to
* $wgDBprefix.
*
- * @deprecated In new code, use the $wiki parameter to wfGetLB() to access
- * remote databases. Using wfGetLB() allows the shared database to reside on
- * separate servers to the wiki's own database, with suitable configuration
- * of $wgLBFactoryConf.
+ * @deprecated since 1.21 In new code, use the $wiki parameter to wfGetLB() to
+ * access remote databases. Using wfGetLB() allows the shared database to
+ * reside on separate servers to the wiki's own database, with suitable
+ * configuration of $wgLBFactoryConf.
*/
$wgSharedDB = null;
@@ -1607,8 +1689,13 @@ $wgSharedTables = array( 'user', 'user_properties' );
* - dbname: Default database name
* - user: DB user
* - password: DB password
- * - type: "mysql" or "postgres"
- * - load: ratio of DB_SLAVE load, must be >=0, the sum of all loads must be >0
+ * - type: DB type
+ *
+ * - load: Ratio of DB_SLAVE load, must be >=0, the sum of all loads must be >0.
+ * If this is zero for any given server, no normal query traffic will be
+ * sent to it. It will be excluded from lag checks in maintenance scripts.
+ * The only way it can receive traffic is if groupLoads is used.
+ *
* - groupLoads: array of load ratios, the key is the query group name. A query may belong
* to several groups, the most specific group defined here is used.
*
@@ -1623,7 +1710,6 @@ $wgSharedTables = array( 'user', 'user_properties' );
* if available
*
* - max lag: (optional) Maximum replication lag before a slave will taken out of rotation
- * - max threads: (optional) Maximum number of running threads
*
* These and any other user-defined properties will be assigned to the mLBInfo member
* variable of the Database object.
@@ -1654,13 +1740,14 @@ $wgDBservers = false;
* The class identified here is responsible for reading $wgDBservers,
* $wgDBserver, etc., so overriding it may cause those globals to be ignored.
*
- * The LBFactory_Multi class is provided for this purpose, please see
- * includes/db/LBFactory_Multi.php for configuration information.
+ * The LBFactoryMulti class is provided for this purpose, please see
+ * includes/db/LBFactoryMulti.php for configuration information.
*/
-$wgLBFactoryConf = array( 'class' => 'LBFactory_Simple' );
+$wgLBFactoryConf = array( 'class' => 'LBFactorySimple' );
/**
* How long to wait for a slave to catch up to the master
+ * @deprecated since 1.24
*/
$wgMasterWaitTimeout = 10;
@@ -1690,11 +1777,6 @@ $wgDBerrorLog = false;
$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
@@ -1767,6 +1849,11 @@ $wgSlaveLagWarning = 10;
*/
$wgSlaveLagCritical = 30;
+/**
+ * Use Windows Authentication instead of $wgDBuser / $wgDBpassword for MS SQL Server
+ */
+$wgDBWindowsAuthentication = false;
+
/**@}*/ # End of DB settings }
/************************************************************************//**
@@ -1793,7 +1880,7 @@ $wgCompressRevisions = false;
*
* CAUTION: Access to database might lead to code execution
*/
-$wgExternalStores = false;
+$wgExternalStores = array();
/**
* An array of external MySQL servers.
@@ -1806,7 +1893,7 @@ $wgExternalStores = false;
* );
* @endcode
*
- * Used by LBFactory_Simple, may be ignored if $wgLBFactoryConf is set to
+ * Used by LBFactorySimple, may be ignored if $wgLBFactoryConf is set to
* another class.
*/
$wgExternalServers = array();
@@ -1921,9 +2008,6 @@ $wgCacheDirectory = false;
* - CACHE_DB: Store cache objects in the DB
* - CACHE_MEMCACHED: MemCached, must specify servers in $wgMemCachedServers
* - CACHE_ACCEL: APC, XCache or WinCache
- * - CACHE_DBA: Use PHP's DBA extension to store in a DBM-style
- * database. This is slow, and is not recommended for
- * anything other than debugging.
* - (other): A string may be used which identifies a cache
* configuration in $wgObjectCaches.
*
@@ -1976,15 +2060,10 @@ $wgLanguageConverterCacheType = CACHE_ANYTHING;
* the value is an associative array of parameters. The "class" parameter is the
* class name which will be used. Alternatively, a "factory" parameter may be
* given, giving a callable function which will generate a suitable cache object.
- *
- * The other parameters are dependent on the class used.
- * - CACHE_DBA uses $wgTmpDirectory by default. The 'dir' parameter let you
- * overrides that.
*/
$wgObjectCaches = array(
CACHE_NONE => array( 'class' => 'EmptyBagOStuff' ),
CACHE_DB => array( 'class' => 'SqlBagOStuff', 'table' => 'objectcache' ),
- CACHE_DBA => array( 'class' => 'DBABagOStuff' ),
CACHE_ANYTHING => array( 'factory' => 'ObjectCache::newAnything' ),
CACHE_ACCEL => array( 'factory' => 'ObjectCache::newAccelerator' ),
@@ -1999,16 +2078,32 @@ $wgObjectCaches = array(
);
/**
- * The expiry time for the parser cache, in seconds.
- * The default is 86400 (one day).
+ * Map of bloom filter store names to configuration arrays.
+ *
+ * Example:
+ * $wgBloomFilterStores['main'] = array(
+ * 'cacheId' => 'main-v1',
+ * 'class' => 'BloomCacheRedis',
+ * 'redisServers' => array( '127.0.0.1:6379' ),
+ * 'redisConfig' => array( 'connectTimeout' => 2 )
+ * );
+ *
+ * A primary bloom filter must be created manually.
+ * Example in eval.php:
+ * <code>
+ * BloomCache::get( 'main' )->init( 'shared', 1000000000, .001 );
+ * </code>
+ * The size should be as large as practical given wiki size and resources.
+ *
+ * @since 1.24
*/
-$wgParserCacheExpireTime = 86400;
+$wgBloomFilterStores = array();
/**
- * Select which DBA handler <http://www.php.net/manual/en/dba.requirements.php>
- * to use as CACHE_DBA backend.
+ * The expiry time for the parser cache, in seconds.
+ * The default is 86400 (one day).
*/
-$wgDBAhandler = 'db3';
+$wgParserCacheExpireTime = 86400;
/**
* Deprecated alias for $wgSessionsInObjectCache.
@@ -2118,6 +2213,12 @@ $wgCachePages = true;
$wgCacheEpoch = '20030516000000';
/**
+ * Directory where GitInfo will look for pre-computed cache files. If false,
+ * $wgCacheDirectory/gitinfo will be used.
+ */
+$wgGitInfoCacheDirectory = false;
+
+/**
* 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,
@@ -2129,7 +2230,7 @@ $wgStyleVersion = '303';
/**
* This will cache static pages for non-logged-in users to reduce
* database traffic on public sites.
- * Must set $wgShowIPinHeader = false
+ * Automatically sets $wgShowIPinHeader = false
* ResourceLoader requests to default language and skins are cached
* as well as single module requests.
*/
@@ -2218,7 +2319,7 @@ $wgInvalidateCacheOnLocalSettingsChange = true;
* although they are referred to as Squid settings for historical reasons.
*
* Achieving a high hit ratio with an HTTP proxy requires special
- * configuration. See http://www.mediawiki.org/wiki/Manual:Squid_caching for
+ * configuration. See https://www.mediawiki.org/wiki/Manual:Squid_caching for
* more details.
*
* @{
@@ -2226,7 +2327,7 @@ $wgInvalidateCacheOnLocalSettingsChange = true;
/**
* Enable/disable Squid.
- * See http://www.mediawiki.org/wiki/Manual:Squid_caching
+ * See https://www.mediawiki.org/wiki/Manual:Squid_caching
*/
$wgUseSquid = false;
@@ -2285,7 +2386,9 @@ $wgSquidServers = array();
/**
* As above, except these servers aren't purged on page changes; use to set a
- * list of trusted proxies, etc.
+ * list of trusted proxies, etc. Supports both individual IP addresses and
+ * CIDR blocks.
+ * @since 1.23 Supports CIDR ranges
*/
$wgSquidServersNoPurge = array();
@@ -2369,42 +2472,6 @@ $wgSquidPurgeUseHostHeader = true;
$wgHTCPRouting = array();
/**
- * @deprecated since 1.22, please use $wgHTCPRouting instead.
- *
- * Whenever this is set and $wgHTCPRouting evaluates to false, $wgHTCPRouting
- * will be set to this value.
- * This is merely for back compatibility.
- *
- * @since 1.20
- */
-$wgHTCPMulticastRouting = null;
-
-/**
- * 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 $wgHTCPRouting , and kept for
- * backwards compatibility only. If $wgHTCPRouting is set, this setting is
- * ignored. If $wgHTCPRouting is not set and this setting is, it is used to
- * populate $wgHTCPRouting.
- *
- * @deprecated since 1.20 in favor of $wgHTCPMulticastRouting and since 1.22 in
- * favor of $wgHTCPRouting.
- */
-$wgHTCPMulticastAddress = false;
-
-/**
- * HTCP multicast port.
- * @deprecated since 1.20 in favor of $wgHTCPMulticastRouting and since 1.22 in
- * favor of $wgHTCPRouting.
- *
- * @see $wgHTCPMulticastAddress
- */
-$wgHTCPPort = 4827;
-
-/**
* HTCP multicast TTL.
* @see $wgHTCPRouting
*/
@@ -2467,6 +2534,21 @@ $wgInterwikiMagic = true;
$wgHideInterlanguageLinks = false;
/**
+ * List of additional interwiki prefixes that should be treated as
+ * interlanguage links (i.e. placed in the sidebar).
+ * Notes:
+ * - This will not do anything unless the prefixes are defined in the interwiki
+ * map.
+ * - The display text for these custom interlanguage links will be fetched from
+ * the system message "interlanguage-link-xyz" where xyz is the prefix in
+ * this array.
+ * - A friendly name for each site, used for tooltip text, may optionally be
+ * placed in the system message "interlanguage-link-sitename-xyz" where xyz is
+ * the prefix in this array.
+ */
+$wgExtraInterlanguageLinkPrefixes = array();
+
+/**
* List of language names or overrides for default names in Names.php
*/
$wgExtraLanguageNames = array();
@@ -2642,11 +2724,6 @@ $wgDisableLangConversion = false;
$wgDisableTitleConversion = false;
/**
- * Whether to enable canonical language links in meta data.
- */
-$wgCanonicalLanguageLinks = true;
-
-/**
* Default variant code, if false, the default will be the language code
*/
$wgDefaultLanguageVariant = false;
@@ -2794,6 +2871,23 @@ $wgHtml5 = true;
$wgHtml5Version = null;
/**
+ * Temporary variable that allows HTMLForms to be rendered as tables.
+ * Table based layouts cause various issues when designing for mobile.
+ * This global allows skins or extensions a means to force non-table based rendering.
+ * Setting to false forces form components to always render as div elements.
+ * @since 1.24
+ */
+$wgHTMLFormAllowTableFormat = true;
+
+/**
+ * Temporary variable that applies MediaWiki UI wherever it can be supported.
+ * Temporary variable that should be removed when mediawiki ui is more
+ * stable and change has been communicated.
+ * @since 1.24
+ */
+$wgUseMediaWikiUIEverywhere = false;
+
+/**
* Enabled RDFa attributes for use in wikitext.
* NOTE: Interaction with HTML5 is somewhat underspecified.
*/
@@ -2834,7 +2928,7 @@ $wgWellFormedXml = true;
* 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 $wgMimeType is set to a non-XML mimetype.
+ * This is ignored if $wgMimeType is set to a non-XML MIME type.
*/
$wgXhtmlNamespaces = array();
@@ -2855,11 +2949,6 @@ $wgShowIPinHeader = true;
$wgSiteNotice = '';
/**
- * A subtitle to add to the tagline, for skins that have it/
- */
-$wgExtraSubtitle = '';
-
-/**
* If this is set, a "donate" link will appear in the sidebar. Set it to a URL.
*/
$wgSiteSupportPage = '';
@@ -2873,24 +2962,29 @@ $wgValidateAllHtml = false;
/**
* Default skin, for new users and anonymous visitors. Registered users may
* change this to any one of the other available skins in their preferences.
- * This has to be completely lowercase; see the "skins" directory for the list
- * of available skins.
*/
$wgDefaultSkin = 'vector';
/**
- * Specify the name of a skin that should not be presented in the list of
- * available skins. Use for blacklisting a skin which you do not want to
- * remove from the .../skins/ directory
+ * Fallback skin used when the skin defined by $wgDefaultSkin can't be found.
+ *
+ * @since 1.24
*/
-$wgSkipSkin = '';
+$wgFallbackSkin = 'fallback';
/**
- * Array for more like $wgSkipSkin.
+ * Specify the names of skins that should not be presented in the list of
+ * available skins in user preferences. If you want to remove a skin entirely,
+ * remove it from the skins/ directory and its entry from LocalSettings.php.
*/
$wgSkipSkins = array();
/**
+ * @deprecated since 1.23; use $wgSkipSkins instead
+ */
+$wgSkipSkin = '';
+
+/**
* Allow user Javascript page?
* This enables a lot of neat customizations, but may
* increase security risk to users and server load.
@@ -3010,7 +3104,8 @@ $wgFooterIcons = array(
),
"poweredby" => array(
"mediawiki" => array(
- "src" => null, // Defaults to "$wgStylePath/common/images/poweredby_mediawiki_88x31.png"
+ // src defaults to "$wgResourceBasePath/resources/assets/poweredby_mediawiki_88x31.png"
+ "src" => null,
"url" => "//www.mediawiki.org/",
"alt" => "Powered by MediaWiki",
)
@@ -3026,33 +3121,11 @@ $wgFooterIcons = array(
$wgUseCombinedLoginLink = false;
/**
- * Search form look for Vector skin only.
- * - true = use an icon search button
- * - false = use Go & Search buttons
- */
-$wgVectorUseSimpleSearch = true;
-
-/**
- * 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 = true;
-
-/**
* Display user edit counts in various prominent places.
*/
$wgEdititis = false;
/**
- * Better directionality support (bug 6100 and related).
- * Removed in 1.18, still kept here for LiquidThreads backwards compatibility.
- *
- * @deprecated since 1.18
- */
-$wgBetterDirectionality = true;
-
-/**
* Some web hosts attempt to rewrite all responses with a 404 (not found)
* status code, mangling or hiding MediaWiki's output. If you are using such a
* host, you should start looking for a better one. While you're doing that,
@@ -3083,6 +3156,14 @@ $wgShowRollbackEditCount = 10;
*/
$wgEnableCanonicalServerLink = false;
+/**
+ * When OutputHandler is used, mangle any output that contains
+ * <cross-domain-policy>. Without this, an attacker can send their own
+ * cross-domain policy unless it is prevented by the crossdomain.xml file at
+ * the domain root.
+ */
+$wgMangleFlashPolicy = true;
+
/** @} */ # End of output format settings }
/*************************************************************************//**
@@ -3110,16 +3191,118 @@ $wgEnableCanonicalServerLink = false;
$wgResourceModules = array();
/**
+ * Skin-specific styles for resource modules.
+ *
+ * These are later added to the 'skinStyles' list of the existing module. The 'styles' list can
+ * not be modified or disabled.
+ *
+ * For example, here is a module "bar" and how skin Foo would provide additional styles for it.
+ *
+ * @par Example:
+ * @code
+ * $wgResourceModules['bar'] = array(
+ * 'scripts' => 'resources/bar/bar.js',
+ * 'styles' => 'resources/bar/main.css',
+ * );
+ *
+ * $wgResourceModuleSkinStyles['foo'] = array(
+ * 'bar' => 'skins/Foo/bar.css',
+ * );
+ * @endcode
+ *
+ * This is mostly equivalent to:
+ *
+ * @par Equivalent:
+ * @code
+ * $wgResourceModules['bar'] = array(
+ * 'scripts' => 'resources/bar/bar.js',
+ * 'styles' => 'resources/bar/main.css',
+ * 'skinStyles' => array(
+ * 'foo' => skins/Foo/bar.css',
+ * ),
+ * );
+ * @endcode
+ *
+ * If the module already defines its own entry in `skinStyles` for a given skin, then
+ * $wgResourceModuleSkinStyles is ignored.
+ *
+ * If a module defines a `skinStyles['default']` the skin may want to extend that instead
+ * of replacing them. This can be done using the `+` prefix.
+ *
+ * @par Example:
+ * @code
+ * $wgResourceModules['bar'] = array(
+ * 'scripts' => 'resources/bar/bar.js',
+ * 'styles' => 'resources/bar/basic.css',
+ * 'skinStyles' => array(
+ * 'default' => 'resources/bar/additional.css',
+ * ),
+ * );
+ * // Note the '+' character:
+ * $wgResourceModuleSkinStyles['+foo'] = array(
+ * 'bar' => 'skins/Foo/bar.css',
+ * );
+ * @endcode
+ *
+ * This is mostly equivalent to:
+ *
+ * @par Equivalent:
+ * @code
+ * $wgResourceModules['bar'] = array(
+ * 'scripts' => 'resources/bar/bar.js',
+ * 'styles' => 'resources/bar/basic.css',
+ * 'skinStyles' => array(
+ * 'default' => 'resources/bar/additional.css',
+ * 'foo' => array(
+ * 'resources/bar/additional.css',
+ * 'skins/Foo/bar.css',
+ * ),
+ * ),
+ * );
+ * @endcode
+ *
+ * In other words, as a module author, use the `styles` list for stylesheets that may not be
+ * disabled by a skin. To provide default styles that may be extended or replaced,
+ * use `skinStyles['default']`.
+ *
+ * As with $wgResourceModules, paths default to being relative to the MediaWiki root.
+ * You should always provide a localBasePath and remoteBasePath (or remoteExtPath/remoteSkinPath).
+ * Either for all skin styles at once (first example below) or for each module separately (second
+ * example).
+ *
+ * @par Example:
+ * @code
+ * $wgResourceModuleSkinStyles['foo'] = array(
+ * 'bar' => 'bar.css',
+ * 'quux' => 'quux.css',
+ * 'remoteSkinPath' => 'Foo',
+ * 'localBasePath' => __DIR__,
+ * );
+ *
+ * $wgResourceModuleSkinStyles['foo'] = array(
+ * 'bar' => array(
+ * 'bar.css',
+ * 'remoteSkinPath' => 'Foo',
+ * 'localBasePath' => __DIR__,
+ * ),
+ * 'quux' => array(
+ * 'quux.css',
+ * 'remoteSkinPath' => 'Foo',
+ * 'localBasePath' => __DIR__,
+ * ),
+ * );
+ * @endcode
+ */
+$wgResourceModuleSkinStyles = array();
+
+/**
* Extensions should register foreign module sources here. 'local' is a
* built-in source that is not in this array, but defined by
* ResourceLoader::__construct() so that it cannot be unset.
*
* @par Example:
* @code
- * $wgResourceLoaderSources['foo'] = array(
- * 'loadScript' => 'http://example.org/w/load.php',
- * 'apiScript' => 'http://example.org/w/api.php'
- * );
+ * $wgResourceLoaderSources['foo'] = 'http://example.org/w/load.php';
* @endcode
*/
$wgResourceLoaderSources = array();
@@ -3132,14 +3315,23 @@ $wgResourceBasePath = null;
/**
* Maximum time in seconds to cache resources served by the resource loader.
+ * Used to set last modified headers (max-age/s-maxage).
+ *
+ * Following options to distinguish:
+ * - versioned: Used for modules with a version, because changing version
+ * numbers causes cache misses. This normally has a long expiry time.
+ * - unversioned: Used for modules without a version to propagate changes
+ * quickly to clients. Also used for modules with errors to recover quickly.
+ * This normally has a short expiry time.
*
- * @todo Document array structure
+ * Expiry time for the options to distinguish:
+ * - server: Squid/Varnish but also any other public proxy cache between the
+ * client and MediaWiki.
+ * - client: On the client side (e.g. in the browser cache).
*/
$wgResourceLoaderMaxage = array(
'versioned' => array(
- // Squid/Varnish but also any other public proxy cache between the client and MediaWiki
'server' => 30 * 24 * 60 * 60, // 30 days
- // On the client side (e.g. in the browser cache).
'client' => 30 * 24 * 60 * 60, // 30 days
),
'unversioned' => array(
@@ -3182,6 +3374,15 @@ $wgResourceLoaderMinifierMaxLineLength = 1000;
$wgIncludeLegacyJavaScript = true;
/**
+ * Whether to include the jQuery Migrate library, which lets legacy JS that
+ * requires jQuery 1.8.x to work and breaks with 1.9.x+.
+ *
+ * @since 1.24
+ * @deprecated since 1.24, to be removed in 1.25
+ */
+$wgIncludejQueryMigrate = false;
+
+/**
* Whether to preload the mediawiki.util module as blocking module in the top
* queue.
*
@@ -3270,12 +3471,14 @@ $wgResourceLoaderValidateStaticJS = false;
$wgResourceLoaderExperimentalAsyncLoading = false;
/**
- * Global LESS variables. An associative array binding variable names to CSS
- * string values.
+ * Global LESS variables. An associative array binding variable names to
+ * LESS code snippets representing their values.
*
- * Because the hashed contents of this array are used to construct the cache key
- * that ResourceLoader uses to look up LESS compilation results, updating this
- * array can be used to deliberately invalidate the set of cached results.
+ * Adding an item here is equivalent to writing `@variable: value;`
+ * at the beginning of all your .less files, with all the consequences.
+ * In particular, string values must be escaped and quoted.
+ *
+ * Changes to LESS variables do not trigger cache invalidation.
*
* @par Example:
* @code
@@ -3293,17 +3496,13 @@ $wgResourceLoaderLESSVars = array();
* Custom LESS functions. An associative array mapping function name to PHP
* callable.
*
- * Changes to LESS functions do not trigger cache invalidation. If you update
- * the behavior of a LESS function and need to invalidate stale compilation
- * results, you can touch one of values in $wgResourceLoaderLESSVars, as
- * documented above.
+ * Changes to LESS functions do not trigger cache invalidation.
*
* @since 1.22
+ * @deprecated since 1.24 Questionable usefulness and problematic to support,
+ * will be removed in the future.
*/
-$wgResourceLoaderLESSFunctions = array(
- 'embeddable' => 'ResourceLoaderLESSFunctions::embeddable',
- 'embed' => 'ResourceLoaderLESSFunctions::embed',
-);
+$wgResourceLoaderLESSFunctions = array();
/**
* Default import paths for LESS modules. LESS files referenced in @import
@@ -3319,10 +3518,26 @@ $wgResourceLoaderLESSFunctions = array(
* @since 1.22
*/
$wgResourceLoaderLESSImportPaths = array(
- "$IP/resources/mediawiki.less/",
+ "$IP/resources/src/mediawiki.less/",
);
/**
+ * Whether ResourceLoader should attempt to persist modules in localStorage on
+ * browsers that support the Web Storage API.
+ *
+ * @since 1.23 - Client-side module persistence is experimental. Exercise care.
+ */
+$wgResourceLoaderStorageEnabled = false;
+
+/**
+ * Cache version for client-side ResourceLoader module storage. You can trigger
+ * invalidation of the contents of the module store by incrementing this value.
+ *
+ * @since 1.23
+ */
+$wgResourceLoaderStorageVersion = 1;
+
+/**
* Whether to allow site-wide CSS (MediaWiki:Common.css and friends) on
* restricted pages like Special:UserLogin or Special:Preferences where
* JavaScript is disabled for security reasons. As it is possible to
@@ -3335,14 +3550,6 @@ $wgResourceLoaderLESSImportPaths = array(
*/
$wgAllowSiteCSSOnRestrictedPages = false;
-/**
- * When OutputHandler is used, mangle any output that contains
- * <cross-domain-policy>. Without this, an attacker can send their own
- * cross-domain policy unless it is prevented by the crossdomain.xml file at
- * the domain root.
- */
-$wgMangleFlashPolicy = true;
-
/** @} */ # End of resource loader settings }
/*************************************************************************//**
@@ -3452,10 +3659,22 @@ $wgLegalTitleChars = " %!\"$&'()*,\\-.\\/0-9:;=?@A-Z\\\\^_`a-z~\\x80-\\xFF+";
/**
* The interwiki prefix of the current wiki, or false if it doesn't have one.
+ *
+ * @deprecated since 1.23; use $wgLocalInterwikis instead
*/
$wgLocalInterwiki = false;
/**
+ * Array for multiple $wgLocalInterwiki values, in case there are several
+ * interwiki prefixes that point to the current wiki. If $wgLocalInterwiki is
+ * set, its value is prepended to this array, for backwards compatibility.
+ *
+ * Note, recent changes feeds use only the first entry in this array (or
+ * $wgLocalInterwiki, if it is set). See $wgRCFeeds
+ */
+$wgLocalInterwikis = array();
+
+/**
* Expiry time for cache of interwiki table
*/
$wgInterwikiExpiry = 10800;
@@ -3557,6 +3776,30 @@ $wgNamespacesWithSubpages = array(
);
/**
+ * Array holding default tracking category names.
+ *
+ * Array contains the system messages for each tracking category.
+ * Tracking categories allow pages with certain characteristics to be tracked.
+ * It works by adding any such page to a category automatically.
+ *
+ * A message with the suffix '-desc' should be added as a description message
+ * to have extra information on Special:TrackingCategories.
+ *
+ * @since 1.23
+ */
+$wgTrackingCategories = array(
+ 'index-category',
+ 'noindex-category',
+ 'expensive-parserfunction-category',
+ 'post-expand-template-argument-category',
+ 'post-expand-template-inclusion-category',
+ 'hidden-category-category',
+ 'broken-file-category',
+ 'node-count-exceeded-category',
+ 'expansion-depth-exceeded-category',
+);
+
+/**
* Array of namespaces which can be deemed to contain valid "content", as far
* as the site statistics are concerned. Useful if additional namespaces also
* contain "content" which should be considered when generating a count of the
@@ -3653,36 +3896,20 @@ $wgMaxTemplateDepth = 40;
$wgMaxPPExpandDepth = 40;
/**
- * The external URL protocols
+ * URL schemes that should be recognized as valid by wfParseUrl().
+ *
+ * WARNING: Do not add 'file:' to this or internal file links will be broken.
+ * Instead, if you want to support file links, add 'file://'. The same applies
+ * to any other protocols with the same name as a namespace. See bug #44011 for
+ * more information.
+ *
+ * @see wfParseUrl
*/
$wgUrlProtocols = array(
- 'http://',
- 'https://',
- 'ftp://',
- 'ftps://', // If we allow ftp:// we should allow the secure version.
- 'ssh://',
- 'sftp://', // SFTP > FTP
- 'irc://',
- 'ircs://', // @bug 28503
- 'xmpp:', // Another open communication protocol
- 'sip:',
- 'sips:',
- 'gopher://',
- 'telnet://', // Well if we're going to support the above.. -ævar
- 'nntp://', // @bug 3808 RFC 1738
- 'worldwind://',
- 'mailto:',
- 'tel:', // If we can make emails linkable, why not phone numbers?
- 'sms:', // Likewise this is standardized too
- 'news:',
- 'svn://',
- 'git://',
- 'mms://',
- 'bitcoin:', // Even registerProtocolHandler whitelists this along with mailto:
- 'magnet:', // No reason to reject torrents over magnet: when they're allowed over http://
- 'urn:', // Allow URNs to be used in Microdata/RDFa <link ... href="urn:...">s
- 'geo:', // urls define geo locations, they're useful in Microdata/RDFa and for coordinates
- '//', // for protocol-relative URLs
+ 'bitcoin:', 'ftp://', 'ftps://', 'geo:', 'git://', 'gopher://', 'http://',
+ 'https://', 'irc://', 'ircs://', 'magnet:', 'mailto:', 'mms://', 'news:',
+ 'nntp://', 'redis://', 'sftp://', 'sip:', 'sips:', 'sms:', 'ssh://',
+ 'svn://', 'tel:', 'telnet://', 'urn:', 'worldwind://', 'xmpp:', '//'
);
/**
@@ -3809,13 +4036,16 @@ $wgNoFollowNsExceptions = array();
* (or any subdomains) will not be set to rel="nofollow" regardless of the
* value of $wgNoFollowLinks. For instance:
*
- * $wgNoFollowDomainExceptions = array( 'en.wikipedia.org', 'wiktionary.org' );
+ * $wgNoFollowDomainExceptions = array( 'en.wikipedia.org', 'wiktionary.org',
+ * 'mediawiki.org' );
*
* This would add rel="nofollow" to links to de.wikipedia.org, but not
* en.wikipedia.org, wiktionary.org, en.wiktionary.org, us.en.wikipedia.org,
* etc.
+ *
+ * Defaults to mediawiki.org for the links included in the software by default.
*/
-$wgNoFollowDomainExceptions = array();
+$wgNoFollowDomainExceptions = array( 'mediawiki.org' );
/**
* Allow DISPLAYTITLE to change title display
@@ -3869,23 +4099,14 @@ $wgTranscludeCacheExpiry = 3600;
* - 'any': all pages as considered as valid articles
* - 'comma': the page must contain a comma to be considered valid
* - 'link': the page must contain a [[wiki link]] to be considered valid
- * - null: the value will be set at run time depending on $wgUseCommaCount:
- * if $wgUseCommaCount is false, it will be 'link', if it is true
- * it will be 'comma'
*
- * See also See http://www.mediawiki.org/wiki/Manual:Article_count
+ * See also See https://www.mediawiki.org/wiki/Manual:Article_count
*
* Retroactively changing this variable will not affect the existing count,
* to update it, you will need to run the maintenance/updateArticleCount.php
* script.
*/
-$wgArticleCountMethod = null;
-
-/**
- * Backward compatibility setting, will set $wgArticleCountMethod if it is null.
- * @deprecated since 1.18; use $wgArticleCountMethod instead
- */
-$wgUseCommaCount = false;
+$wgArticleCountMethod = 'link';
/**
* wgHitcounterUpdateFreq sets how often page counters should be updated, higher
@@ -3914,6 +4135,7 @@ $wgActiveUserDays = 30;
/**
* For compatibility with old installations set to false
+ * @deprecated since 1.24 will be removed in future
*/
$wgPasswordSalt = true;
@@ -3924,6 +4146,72 @@ $wgPasswordSalt = true;
$wgMinimalPasswordLength = 1;
/**
+ * Specifies if users should be sent to a password-reset form on login, if their
+ * password doesn't meet the requirements of User::isValidPassword().
+ * @since 1.23
+ */
+$wgInvalidPasswordReset = true;
+
+/**
+ * Default password type to use when hashing user passwords
+ *
+ * @since 1.24
+ */
+$wgPasswordDefault = 'pbkdf2';
+
+/**
+ * Configuration for built-in password types. Maps the password type
+ * to an array of options. The 'class' option is the Password class to
+ * use. All other options are class-dependent.
+ *
+ * An advanced example:
+ * @code
+ * $wgPasswordConfig['bcrypt-peppered'] = array(
+ * 'class' => 'EncryptedPassword',
+ * 'underlying' => 'bcrypt',
+ * 'secrets' => array(),
+ * 'cipher' => MCRYPT_RIJNDAEL_256,
+ * 'mode' => MCRYPT_MODE_CBC,
+ * 'cost' => 5,
+ * );
+ * @endcode
+ *
+ * @since 1.24
+ */
+$wgPasswordConfig = array(
+ 'A' => array(
+ 'class' => 'MWOldPassword',
+ ),
+ 'B' => array(
+ 'class' => 'MWSaltedPassword',
+ ),
+ 'pbkdf2-legacyA' => array(
+ 'class' => 'LayeredParameterizedPassword',
+ 'types' => array(
+ 'A',
+ 'pbkdf2',
+ ),
+ ),
+ 'pbkdf2-legacyB' => array(
+ 'class' => 'LayeredParameterizedPassword',
+ 'types' => array(
+ 'B',
+ 'pbkdf2',
+ ),
+ ),
+ 'bcrypt' => array(
+ 'class' => 'BcryptPassword',
+ 'cost' => 9,
+ ),
+ 'pbkdf2' => array(
+ 'class' => 'Pbkdf2Password',
+ 'algo' => 'sha256',
+ 'cost' => '10000',
+ 'length' => '128',
+ ),
+);
+
+/**
* Whether to allow password resets ("enter some identifying data, and we'll send an email
* with a temporary password you can use to get back into the account") identified by
* various bits of data. Setting all of these to false (or the whole variable to false)
@@ -3963,8 +4251,8 @@ $wgReservedUsernames = array(
/**
* Settings added to this array will override the default globals for the user
* preferences used by anonymous visitors and newly created accounts.
- * For instance, to disable section editing links:
- * $wgDefaultUserOptions ['editsection'] = 0;
+ * For instance, to disable editing on double clicks:
+ * $wgDefaultUserOptions ['editondblclick'] = 0;
*/
$wgDefaultUserOptions = array(
'ccmeonemails' => 0,
@@ -3972,15 +4260,13 @@ $wgDefaultUserOptions = array(
'date' => 'default',
'diffonly' => 0,
'disablemail' => 0,
- 'disablesuggest' => 0,
'editfont' => 'default',
'editondblclick' => 0,
- 'editsection' => 1,
'editsectiononrightclick' => 0,
'enotifminoredits' => 0,
'enotifrevealaddr' => 0,
'enotifusertalkpages' => 1,
- 'enotifwatchlistpages' => 0,
+ 'enotifwatchlistpages' => 1,
'extendwatchlist' => 0,
'fancysig' => 0,
'forceeditsummary' => 0,
@@ -3988,34 +4274,28 @@ $wgDefaultUserOptions = array(
'hideminor' => 0,
'hidepatrolled' => 0,
'imagesize' => 2,
- 'justify' => 0,
'math' => 1,
'minordefault' => 0,
'newpageshidepatrolled' => 0,
- 'nocache' => 0,
- 'noconvertlink' => 0,
+ 'nickname' => '',
'norollbackdiff' => 0,
'numberheadings' => 0,
'previewonfirst' => 0,
'previewontop' => 1,
'rcdays' => 7,
'rclimit' => 50,
- 'rememberpassword' => 0,
'rows' => 25,
- 'searchlimit' => 20,
'showhiddencats' => 0,
'shownumberswatching' => 1,
- 'showtoc' => 1,
'showtoolbar' => 1,
'skin' => false,
'stubthreshold' => 0,
- 'thumbsize' => 2,
+ 'thumbsize' => 5,
'underline' => 2,
'uselivepreview' => 0,
'usenewrc' => 0,
- 'vector-simplesearch' => 1,
- 'watchcreations' => 0,
- 'watchdefault' => 0,
+ 'watchcreations' => 1,
+ 'watchdefault' => 1,
'watchdeletion' => 0,
'watchlistdays' => 3.0,
'watchlisthideanons' => 0,
@@ -4025,6 +4305,7 @@ $wgDefaultUserOptions = array(
'watchlisthideown' => 0,
'watchlisthidepatrolled' => 0,
'watchmoves' => 0,
+ 'watchrollback' => 0,
'wllimit' => 250,
'useeditwarning' => 1,
'prefershttps' => 1,
@@ -4126,7 +4407,7 @@ $wgBlockDisablesLogin = false;
*
* @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
+ * see https://www.mediawiki.org/wiki/Manual:Image_Authorization
*/
$wgWhitelistRead = false;
@@ -4211,6 +4492,7 @@ $wgGroupPermissions['*']['editmyoptions'] = true;
$wgGroupPermissions['user']['move'] = true;
$wgGroupPermissions['user']['move-subpages'] = true;
$wgGroupPermissions['user']['move-rootuserpages'] = true; // can move root userpages
+$wgGroupPermissions['user']['move-categorypages'] = true;
$wgGroupPermissions['user']['movefile'] = true;
$wgGroupPermissions['user']['read'] = true;
$wgGroupPermissions['user']['edit'] = true;
@@ -4258,6 +4540,7 @@ $wgGroupPermissions['sysop']['importupload'] = true;
$wgGroupPermissions['sysop']['move'] = true;
$wgGroupPermissions['sysop']['move-subpages'] = true;
$wgGroupPermissions['sysop']['move-rootuserpages'] = true;
+$wgGroupPermissions['sysop']['move-categorypages'] = true;
$wgGroupPermissions['sysop']['patrol'] = true;
$wgGroupPermissions['sysop']['autopatrol'] = true;
$wgGroupPermissions['sysop']['protect'] = true;
@@ -4279,8 +4562,9 @@ $wgGroupPermissions['sysop']['noratelimit'] = true;
$wgGroupPermissions['sysop']['movefile'] = true;
$wgGroupPermissions['sysop']['unblockself'] = true;
$wgGroupPermissions['sysop']['suppressredirect'] = true;
+#$wgGroupPermissions['sysop']['pagelang'] = true;
#$wgGroupPermissions['sysop']['upload_by_url'] = true;
-#$wgGroupPermissions['sysop']['mergehistory'] = true;
+$wgGroupPermissions['sysop']['mergehistory'] = true;
// Permission to change users' group assignments
$wgGroupPermissions['bureaucrat']['userrights'] = true;
@@ -4296,6 +4580,8 @@ $wgGroupPermissions['bureaucrat']['noratelimit'] = true;
#$wgGroupPermissions['suppress']['hideuser'] = true;
// To hide revisions/log items from users and Sysops
#$wgGroupPermissions['suppress']['suppressrevision'] = true;
+// To view revisions/log items hidden from users and Sysops
+#$wgGroupPermissions['suppress']['viewsuppressed'] = true;
// For private suppression log access
#$wgGroupPermissions['suppress']['suppressionlog'] = true;
@@ -4555,6 +4841,15 @@ $wgAvailableRights = array();
$wgDeleteRevisionsLimit = 0;
/**
+ * The maximum number of edits a user can have and
+ * can still be hidden by users with the hideuser permission.
+ * This is limited for performance reason.
+ * Set to false to disable the limit.
+ * @since 1.23
+ */
+$wgHideUserContribLimit = 1000;
+
+/**
* Number of accounts each IP address may create, 0 to disable.
*
* @warning Requires memcached
@@ -4587,12 +4882,6 @@ $wgSummarySpamRegex = array();
$wgEnableDnsBlacklist = false;
/**
- * @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
@@ -4618,12 +4907,6 @@ $wgEnableSorbs = false;
$wgDnsBlacklistUrls = array( 'http.dnsbl.sorbs.net.' );
/**
- * @deprecated since 1.17 Use $wgDnsBlacklistUrls instead, only kept for
- * backward compatibility.
- */
-$wgSorbsUrl = array();
-
-/**
* Proxy whitelist, list of addresses that are assumed to be non-proxy despite
* what the other methods might say.
*/
@@ -4690,10 +4973,19 @@ $wgRateLimits = array(
'ip' => null,
'subnet' => null,
),
+ 'renderfile-nonstandard' => array( // same as above but for non-standard thumbnails
+ 'anon' => null,
+ 'user' => null,
+ 'newbie' => null,
+ 'ip' => null,
+ 'subnet' => null,
+ ),
);
/**
* Set to a filename to log rate limiter hits.
+ *
+ * @deprecated since 1.23, use $wgDebugLogGroups['ratelimit'] instead
*/
$wgRateLimitLog = null;
@@ -4746,11 +5038,6 @@ $wgSecretKey = false;
*/
$wgProxyList = array();
-/**
- * @deprecated since 1.14
- */
-$wgProxyKey = false;
-
/** @} */ # end of proxy scanner settings
/************************************************************************//**
@@ -4759,7 +5046,7 @@ $wgProxyKey = false;
*/
/**
- * Default cookie expiration time. Setting to 0 makes all cookies session-only.
+ * Default cookie lifetime, in seconds. Setting to 0 makes all cookies session-only.
*/
$wgCookieExpiration = 180 * 86400;
@@ -4806,17 +5093,6 @@ $wgCookiePrefix = false;
$wgCookieHttpOnly = true;
/**
- * If the requesting browser matches a regex in this blacklist, we won't
- * send it cookies with HttpOnly mode, even if $wgCookieHttpOnly is on.
- */
-$wgHttpOnlyBlacklist = array(
- // Internet Explorer for Mac; sometimes the cookies work, sometimes
- // they don't. It's difficult to predict, as combinations of path
- // and expiration options affect its parsing.
- '/^Mozilla\/4\.0 \(compatible; MSIE \d+\.\d+; Mac_PowerPC\)/',
-);
-
-/**
* A list of cookies that vary the cache (for use by extensions)
*/
$wgCacheVaryCookies = array();
@@ -4852,7 +5128,7 @@ $wgUseTeX = false;
*/
/**
- * Filename for debug logging. See http://www.mediawiki.org/wiki/How_to_debug
+ * Filename for debug logging. See https://www.mediawiki.org/wiki/How_to_debug
* The debug log file should be not be publicly accessible if it is used, as it
* may contain private data.
*/
@@ -4895,15 +5171,48 @@ $wgDebugComments = false;
$wgDebugDBTransactions = false;
/**
- * Write SQL queries to the debug log
+ * Write SQL queries to the debug log.
+ *
+ * This setting is only used $wgLBFactoryConf['class'] is set to
+ * 'LBFactorySimple' and $wgDBservers is an empty array; otherwise
+ * the DBO_DEBUG flag must be set in the 'flags' option of the database
+ * connection to achieve the same functionality.
*/
$wgDebugDumpSql = false;
/**
- * Set to an array of log group keys to filenames.
+ * Trim logged SQL queries to this many bytes. Set 0/false/null to do no
+ * trimming.
+ * @since 1.24
+ */
+$wgDebugDumpSqlLength = 500;
+
+/**
+ * Map of string log group names to log destinations.
+ *
* If set, wfDebugLog() output for that group will go to that file instead
* of the regular $wgDebugLogFile. Useful for enabling selective logging
* in production.
+ *
+ * Log destinations may be one of the following:
+ * - false to completely remove from the output, including from $wgDebugLogFile.
+ * - string values specifying a filename or URI.
+ * - associative array mapping 'destination' key to the desired filename or URI.
+ * The associative array may also contain a 'sample' key with an integer value,
+ * specifying a sampling factor.
+ *
+ * @par Example:
+ * @code
+ * $wgDebugLogGroups['redis'] = '/var/log/mediawiki/redis.log';
+ * @endcode
+ *
+ * @par Advanced example:
+ * @code
+ * $wgDebugLogGroups['memcached'] = (
+ * 'destination' => '/var/log/mediawiki/memcached.log',
+ * 'sample' => 1000, // log 1 message out of every 1,000.
+ * );
+ * @endcode
*/
$wgDebugLogGroups = array();
@@ -4947,6 +5256,11 @@ $wgShowExceptionDetails = false;
/**
* If true, show a backtrace for database errors
+ *
+ * @note This setting only applies when connection errors and query errors are
+ * reported in the normal manner. $wgShowExceptionDetails applies in other cases,
+ * including those in which an uncaught exception is thrown from within the
+ * exception handler.
*/
$wgShowDBErrorBacktrace = false;
@@ -4987,20 +5301,11 @@ $wgProfileLimit = 0.0;
/**
* Don't put non-profiling info into log file
- */
-$wgProfileOnly = false;
-
-/**
- * Log sums from profiling into "profiling" table in db.
*
- * You have to create a 'profiling' table in your database before using
- * this feature. Run set $wgProfileToDatabase to true in
- * LocalSettings.php and run maintenance/update.php or otherwise
- * manually add patch-profiling.sql to your database.
- *
- * To enable profiling, edit StartProfiler.php
+ * @deprecated since 1.23, set the log file in
+ * $wgDebugLogGroups['profileoutput'] instead.
*/
-$wgProfileToDatabase = false;
+$wgProfileOnly = false;
/**
* If true, print a raw call tree instead of per-function report
@@ -5016,7 +5321,8 @@ $wgProfilePerHost = false;
* Host for UDP profiler.
*
* The host should be running a daemon which can be obtained from MediaWiki
- * Subversion at: http://svn.wikimedia.org/svnroot/mediawiki/trunk/udpprofile
+ * Git at:
+ * http://git.wikimedia.org/tree/operations%2Fsoftware.git/master/udpprofile
*/
$wgUDPProfilerHost = '127.0.0.1';
@@ -5028,9 +5334,9 @@ $wgUDPProfilerPort = '3811';
/**
* Format string for the UDP profiler. The UDP profiler invokes sprintf() with
- * (profile id, count, cpu, cpu_sq, real, real_sq, entry name) as arguments.
- * You can use sprintf's argument numbering/swapping capability to repeat,
- * re-order or omit fields.
+ * (profile id, count, cpu, cpu_sq, real, real_sq, entry name, memory) as
+ * arguments. You can use sprintf's argument numbering/swapping capability to
+ * repeat, re-order or omit fields.
*
* @see $wgStatsFormatString
* @since 1.22
@@ -5038,11 +5344,6 @@ $wgUDPProfilerPort = '3811';
$wgUDPProfilerFormatString = "%s - %d %f %f %f %f %s\n";
/**
- * Detects non-matching wfProfileIn/wfProfileOut calls
- */
-$wgDebugProfiling = false;
-
-/**
* Output debug message on every wfProfileIn/wfProfileOut
*/
$wgDebugFunctionEntry = false;
@@ -5112,21 +5413,6 @@ $wgParserTestFiles = array(
);
/**
- * If configured, specifies target CodeReview installation to send test
- * result data from 'parserTests.php --upload'
- *
- * Something like this:
- * $wgParserTestRemote = array(
- * 'api-url' => 'http://www.mediawiki.org/w/api.php',
- * 'repo' => 'MediaWiki',
- * 'suite' => 'ParserTests',
- * 'path' => '/trunk/phase3', // not used client-side; for reference
- * 'secret' => 'qmoicj3mc4mcklmqw', // Shared secret used in HMAC validation
- * );
- */
-$wgParserTestRemote = false;
-
-/**
* Allow running of javascript test suites via [[Special:JavaScriptTest]] (such as QUnit).
*/
$wgEnableJavaScriptTest = false;
@@ -5190,18 +5476,6 @@ $wgAdvancedSearchHighlighting = false;
$wgSearchHighlightBoundaries = '[\p{Z}\p{P}\p{C}]';
/**
- * Set to true to have the search engine count total
- * search matches to present in the Special:Search UI.
- * Not supported by every search engine shipped with MW.
- *
- * This could however be slow on larger wikis, and is pretty flaky
- * with the current title vs content split. Recommend avoiding until
- * that's been worked out cleanly; but this may aid in testing the
- * search UI and API to confirm that the result count works.
- */
-$wgCountTotalSearchHits = false;
-
-/**
* Template for OpenSearch suggestions, defaults to API action=opensearch
*
* Sites with heavy load would typically have these point to a custom
@@ -5220,6 +5494,12 @@ $wgOpenSearchTemplate = false;
$wgEnableOpenSearchSuggest = true;
/**
+ * Integer defining default number of entries to show on
+ * OpenSearch call.
+ */
+$wgOpenSearchDefaultLimit = 10;
+
+/**
* Expiry time for search suggestion responses
*/
$wgSearchSuggestCacheExpiry = 1200;
@@ -5244,25 +5524,6 @@ $wgNamespacesToBeSearchedDefault = array(
);
/**
- * Namespaces to be searched when user clicks the "Help" tab
- * on Special:Search.
- *
- * Same format as $wgNamespacesToBeSearchedDefault.
- */
-$wgNamespacesToBeSearchedHelp = array(
- NS_PROJECT => true,
- NS_HELP => true,
-);
-
-/**
- * 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;
-
-/**
* Disable the internal MySQL-based search, to allow it to be
* implemented by an extension instead.
*/
@@ -5350,11 +5611,6 @@ $wgPreviewOnOpenNamespaces = array(
);
/**
- * Go button goes straight to the edit screen if the article doesn't exist.
- */
-$wgGoToEdit = false;
-
-/**
* Enable the UniversalEditButton for browsers that support it
* (currently only Firefox with an extension)
* See http://universaleditbutton.org for more background information
@@ -5391,13 +5647,6 @@ if ( !isset( $wgCommandLineMode ) ) {
$wgCommandLineDarkBg = false;
/**
- * Array for extensions to register their maintenance scripts with the
- * system. The key is the name of the class and the value is the full
- * path to the file
- */
-$wgMaintenanceScripts = array();
-
-/**
* Set this to a string to put the wiki into read-only mode. The text will be
* used as an explanation to users.
*
@@ -5445,9 +5694,10 @@ $wgGitBin = '/usr/bin/git';
* @since 1.20
*/
$wgGitRepositoryViewers = array(
- 'https://gerrit.wikimedia.org/r/p/(.*)' => 'https://git.wikimedia.org/commit/%r/%H',
- 'ssh://(?:[a-z0-9_]+@)?gerrit.wikimedia.org:29418/(.*)'
- => 'https://git.wikimedia.org/commit/%r/%H',
+ 'https://(?:[a-z0-9_]+@)?gerrit.wikimedia.org/r/(?:p/)?(.*)' =>
+ 'https://git.wikimedia.org/tree/%r/%H',
+ 'ssh://(?:[a-z0-9_]+@)?gerrit.wikimedia.org:29418/(.*)' =>
+ 'https://git.wikimedia.org/tree/%r/%H',
);
/** @} */ # End of maintenance }
@@ -5474,74 +5724,44 @@ $wgRCMaxAge = 13 * 7 * 24 * 3600;
$wgRCFilterByAge = false;
/**
- * List of Days and Limits options to list in the Special:Recentchanges and
+ * List of Limits options to list in the Special:Recentchanges and
* Special:Recentchangeslinked pages.
*/
$wgRCLinkLimits = array( 50, 100, 250, 500 );
-$wgRCLinkDays = array( 1, 3, 7, 14, 30 );
-
-/**
- * Send recent changes updates via UDP. The updates will be formatted for IRC.
- * Set this to the IP address of the receiver.
- *
- * @deprecated since 1.22, use $wgRCFeeds
- */
-$wgRC2UDPAddress = false;
-
-/**
- * Port number for RC updates
- *
- * @deprecated since 1.22, use $wgRCFeeds
- */
-$wgRC2UDPPort = false;
-
-/**
- * Prefix to prepend to each UDP packet.
- * This can be used to identify the wiki. A script is available called
- * mxircecho.py which listens on a UDP port, and uses a prefix ending in a
- * tab to identify the IRC channel to send the log line to.
- *
- * @deprecated since 1.22, use $wgRCFeeds
- */
-$wgRC2UDPPrefix = '';
-
-/**
- * If this is set to true, $wgLocalInterwiki will be prepended to links in the
- * IRC feed. If this is set to a string, that string will be used as the prefix.
- *
- * @deprecated since 1.22, use $wgRCFeeds
- */
-$wgRC2UDPInterwikiPrefix = false;
/**
- * Set to true to omit "bot" edits (by users with the bot permission) from the
- * UDP feed.
- *
- * @deprecated since 1.22, use $wgRCFeeds
+ * List of Days options to list in the Special:Recentchanges and
+ * Special:Recentchangeslinked pages.
*/
-$wgRC2UDPOmitBots = false;
+$wgRCLinkDays = array( 1, 3, 7, 14, 30 );
/**
* Destinations to which notifications about recent changes
* should be sent.
*
- * As of MediaWiki 1.22, the only supported 'engine' parameter option in core
- * is 'UDPRCFeedEngine', which is used to send recent changes over UDP to the
- * specified server.
+ * As of MediaWiki 1.22, there are 2 supported 'engine' parameter option in core:
+ * * 'UDPRCFeedEngine', which is used to send recent changes over UDP to the
+ * specified server.
+ * * 'RedisPubSubFeedEngine', which is used to send recent changes to Redis.
+ *
* The common options are:
* * 'uri' -- the address to which the notices are to be sent.
* * 'formatter' -- the class name (implementing RCFeedFormatter) which will
- * produce the text to send.
+ * produce the text to send. This can also be an object of the class.
* * 'omit_bots' -- whether the bot edits should be in the feed
+ * * 'omit_anon' -- whether anonymous edits should be in the feed
+ * * 'omit_user' -- whether edits by registered users should be in the feed
+ * * 'omit_minor' -- whether minor edits should be in the feed
+ * * 'omit_patrolled' -- whether patrolled edits should be in the feed
+ *
* The IRC-specific options are:
* * 'add_interwiki_prefix' -- whether the titles should be prefixed with
- * $wgLocalInterwiki.
+ * the first entry in the $wgLocalInterwikis array (or the value of
+ * $wgLocalInterwiki, if set)
+ *
* The JSON-specific options are:
* * 'channel' -- if set, the 'channel' parameter is also set in JSON values.
*
- * To ensure backwards-compatability, whenever $wgRC2UDPAddress is set, a
- * 'default' feed will be created reusing the deprecated $wgRC2UDP* variables.
- *
* @example $wgRCFeeds['example'] = array(
* 'formatter' => 'JSONRCFeedFormatter',
* 'uri' => "udp://localhost:1336",
@@ -5568,13 +5788,6 @@ $wgRCEngines = array(
);
/**
- * Enable user search in Special:Newpages
- * This is really a temporary hack around an index install bug on some Wikipedias.
- * Kill it once fixed.
- */
-$wgEnableNewpagesUserFilter = true;
-
-/**
* Use RC Patrolling to check for vandalism
*/
$wgUseRCPatrol = true;
@@ -5707,24 +5920,42 @@ $wgUnwatchedPageThreshold = false;
* To register a new one:
* @code
* $wgRecentChangesFlags['flag'] => array(
+ * // message for the letter displayed next to rows on changes lists
* 'letter' => 'letter-msg',
- * 'title' => 'tooltip-msg'
+ * // message for the tooltip of the letter
+ * 'title' => 'tooltip-msg',
+ * // optional (defaults to 'tooltip-msg'), message to use in the legend box
+ * 'legend' => 'legend-msg',
+ * // optional (defaults to 'flag'), CSS class to put on changes lists rows
+ * 'class' => 'css-class',
* );
* @endcode
*
- * Optional 'class' allows to set a css class different than the flag name.
- *
* @since 1.22
*/
$wgRecentChangesFlags = array(
- 'newpage' => array( 'letter' => 'newpageletter',
- 'title' => 'recentchanges-label-newpage' ),
- 'minor' => array( 'letter' => 'minoreditletter',
- 'title' => 'recentchanges-label-minor', 'class' => 'minoredit' ),
- 'bot' => array( 'letter' => 'boteditletter',
- 'title' => 'recentchanges-label-bot', 'class' => 'botedit' ),
- 'unpatrolled' => array( 'letter' => 'unpatrolledletter',
- 'title' => 'recentchanges-label-unpatrolled' ),
+ 'newpage' => array(
+ 'letter' => 'newpageletter',
+ 'title' => 'recentchanges-label-newpage',
+ 'legend' => 'recentchanges-legend-newpage',
+ ),
+ 'minor' => array(
+ 'letter' => 'minoreditletter',
+ 'title' => 'recentchanges-label-minor',
+ 'legend' => 'recentchanges-legend-minor',
+ 'class' => 'minoredit',
+ ),
+ 'bot' => array(
+ 'letter' => 'boteditletter',
+ 'title' => 'recentchanges-label-bot',
+ 'legend' => 'recentchanges-legend-bot',
+ 'class' => 'botedit',
+ ),
+ 'unpatrolled' => array(
+ 'letter' => 'unpatrolledletter',
+ 'title' => 'recentchanges-label-unpatrolled',
+ 'legend' => 'recentchanges-legend-unpatrolled',
+ ),
);
/** @} */ # end RC/watchlist }
@@ -5764,11 +5995,6 @@ $wgRightsText = null;
$wgRightsIcon = null;
/**
- * Set to an array of metadata terms. Else they will be loaded based on $wgRightsUrl
- */
-$wgLicenseTerms = false;
-
-/**
* Set this to some HTML to override the rights icon with an arbitrary logo
* @deprecated since 1.18 Use $wgFooterIcons['copyright']['copyright']
*/
@@ -5806,6 +6032,17 @@ $wgShowCreditsIfMax = true;
* Special:Import (for sysops). Since complete page history can be imported,
* these should be 'trusted'.
*
+ * This can either be a regular array, or an associative map specifying
+ * subprojects on the interwiki map of the target wiki, or a mix of the two,
+ * e.g.
+ * @code
+ * $wgImportSources = array(
+ * 'wikipedia' => array( 'cs', 'en', 'fr', 'zh' ),
+ * 'wikispecies',
+ * 'wikia' => array( 'animanga', 'brickipedia', 'desserts' ),
+ * );
+ * @endcode
+ *
* If a user has the 'import' permission but not the 'importupload' permission,
* they will only be able to run imports through this transwiki interface.
*/
@@ -5886,6 +6123,16 @@ $wgExtensionFunctions = array();
* Variables defined in extensions will override conflicting variables defined
* in the core.
*
+ * Since MediaWiki 1.23, use of this variable to define messages is discouraged; instead, store
+ * messages in JSON format and use $wgMessagesDirs. For setting other variables than
+ * $messages, $wgExtensionMessagesFiles should still be used. Use a DIFFERENT key because
+ * any entry having a key that also exists in $wgMessagesDirs will be ignored.
+ *
+ * Extensions using the JSON message format can preserve backward compatibility with
+ * earlier versions of MediaWiki by using a compatibility shim, such as one generated
+ * by the generateJsonI18n.php maintenance script, listing it under the SAME key
+ * as for the $wgMessagesDirs entry.
+ *
* @par Example:
* @code
* $wgExtensionMessagesFiles['ConfirmEdit'] = __DIR__.'/ConfirmEdit.i18n.php';
@@ -5894,6 +6141,34 @@ $wgExtensionFunctions = array();
$wgExtensionMessagesFiles = array();
/**
+ * Extension messages directories.
+ *
+ * Associative array mapping extension name to the path of the directory where message files can
+ * be found. The message files are expected to be JSON files named for their language code, e.g.
+ * en.json, de.json, etc. Extensions with messages in multiple places may specify an array of
+ * message directories.
+ *
+ * @par Simple example:
+ * @code
+ * $wgMessagesDirs['Example'] = __DIR__ . '/i18n';
+ * @endcode
+ *
+ * @par Complex example:
+ * @code
+ * $wgMessagesDirs['Example'] = array(
+ * __DIR__ . '/lib/ve/i18n',
+ * __DIR__ . '/lib/oojs-ui/i18n',
+ * __DIR__ . '/i18n',
+ * )
+ * @endcode
+ * @since 1.23
+ */
+$wgMessagesDirs = array(
+ 'core' => "$IP/languages/i18n",
+ 'oojs-ui' => "$IP/resources/lib/oojs-ui/i18n",
+);
+
+/**
* Array of files with list(s) of extension entry points to be used in
* maintenance/mergeMessageFileList.php
* @since 1.22
@@ -5922,19 +6197,20 @@ $wgParserOutputHooks = array();
$wgEnableParserLimitReporting = true;
/**
- * List of valid skin names.
+ * List of valid skin names
+ *
* The key should be the name in all lower case, the value should be a properly
- * cased name for the skin. This value will be prefixed with "Skin" to create the
- * class name of the skin to load, and if the skin's class cannot be found through
- * the autoloader it will be used to load a .php file by that name in the skins directory.
- * The default skins will be added later, by Skin::getSkinNames(). Use
- * Skin::getSkinNames() as an accessor if you wish to have access to the full list.
+ * cased name for the skin. This value will be prefixed with "Skin" to create
+ * the class name of the skin to load. Use Skin::getSkinNames() as an accessor
+ * if you wish to have access to the full list.
*/
$wgValidSkinNames = array();
/**
- * Special page list.
- * See the top of SpecialPage.php for documentation.
+ * Special page list. This is an associative array mapping the (canonical) names of
+ * special pages to either a class name to be instantiated, or a callback to use for
+ * creating the special page object. In both cases, the result must be an instance of
+ * SpecialPage.
*/
$wgSpecialPages = array();
@@ -5944,30 +6220,63 @@ $wgSpecialPages = array();
$wgAutoloadClasses = array();
/**
- * An array of extension types and inside that their names, versions, authors,
- * urls, descriptions and pointers to localized description msgs. Note that
- * the version, url, description and descriptionmsg key can be omitted.
+ * Switch controlling legacy case-insensitive classloading.
+ * Do not disable if your wiki must support data created by PHP4, or by
+ * MediaWiki 1.4 or earlier.
+ */
+$wgAutoloadAttemptLowercase = true;
+
+/**
+ * An array of information about installed extensions keyed by their type.
+ *
+ * All but 'name', 'path' and 'author' can be omitted.
*
* @code
* $wgExtensionCredits[$type][] = array(
- * 'name' => 'Example extension',
- * 'version' => 1.9,
* 'path' => __FILE__,
- * 'author' => 'Foo Barstein',
- * 'url' => 'http://www.example.com/Example%20Extension/',
- * 'description' => 'An example extension',
+ * 'name' => 'Example extension',
+ * 'namemsg' => 'exampleextension-name',
+ * 'author' => array(
+ * 'Foo Barstein',
+ * ),
+ * 'version' => '1.9.0',
+ * 'url' => 'http://example.org/example-extension/',
* 'descriptionmsg' => 'exampleextension-desc',
+ * 'license-name' => 'GPL-2.0',
* );
* @endcode
*
- * Where $type is 'specialpage', 'parserhook', 'variable', 'media' or 'other'.
- * Where 'descriptionmsg' can be an array with message key and parameters:
- * 'descriptionmsg' => array( 'exampleextension-desc', param1, param2, ... ),
+ * The extensions are listed on Special:Version. This page also looks for a file
+ * named COPYING or LICENSE (optional .txt extension) and provides a link to
+ * view said file. When the 'license-name' key is specified, this file is
+ * interpreted as wikitext.
+ *
+ * - $type: One of 'specialpage', 'parserhook', 'variable', 'media', 'antispam',
+ * 'skin', 'api', or 'other', or any additional types as specified through the
+ * ExtensionTypes hook as used in SpecialVersion::getExtensionTypes().
+ *
+ * - name: Name of extension as an inline string instead of localizable message.
+ * Do not omit this even if 'namemsg' is provided, as it is used to override
+ * the path Special:Version uses to find extension's license info, and is
+ * required for backwards-compatibility with MediaWiki 1.23 and older.
+ *
+ * - namemsg (since MW 1.24): A message key for a message containing the
+ * extension's name, if the name is localizable. (For example, skin names
+ * usually are.)
+ *
+ * - author: A string or an array of strings. Authors can be linked using
+ * the regular wikitext link syntax. To have an internationalized version of
+ * "and others" show, add an element "...". This element can also be linked,
+ * for instance "[http://example ...]".
+ *
+ * - descriptionmsg: A message key or an an array with message key and parameters:
+ * `'descriptionmsg' => 'exampleextension-desc',`
+ *
+ * - description: Description of extension as an inline string instead of
+ * localizable message (omit in favour of 'descriptionmsg').
*
- * author can be a string or an array of strings. Authors can be linked using
- * the regular wikitext link syntax. To have an internationalized version of
- * "and others" show, add an element "...". This element can also be linked,
- * for instance "[http://example ...]".
+ * - license-name: Short name of the license (used as label for the link), such
+ * as "GPL-2.0" or "MIT" (https://spdx.org/licenses/ for a list of identifiers).
*/
$wgExtensionCredits = array();
@@ -6019,7 +6328,7 @@ $wgHooks = array();
*/
$wgJobClasses = array(
'refreshLinks' => 'RefreshLinksJob',
- 'refreshLinks2' => 'RefreshLinksJob2',
+ 'refreshLinks2' => 'RefreshLinksJob2', // b/c
'htmlCacheUpdate' => 'HTMLCacheUpdateJob',
'sendMail' => 'EmaillingJob',
'enotifNotify' => 'EnotifNotifyJob',
@@ -6039,10 +6348,22 @@ $wgJobClasses = array(
* - Jobs that you would never want to run as part of a page rendering request.
* - Jobs that you want to run on specialized machines ( like transcoding, or a particular
* machine on your cluster has 'outside' web access you could restrict uploadFromUrl )
+ * These settings should be global to all wikis.
*/
$wgJobTypesExcludedFromDefaultQueue = array( 'AssembleUploadChunks', 'PublishStashedFile' );
/**
+ * Map of job types to how many job "work items" should be run per second
+ * on each job runner process. The meaning of "work items" varies per job,
+ * but typically would be something like "pages to update". A single job
+ * may have a variable number of work items, as is the case with batch jobs.
+ * This is used by runJobs.php and not jobs run via $wgJobRunRate.
+ * These settings should be global to all wikis.
+ * @var float[]
+ */
+$wgJobBackoffThrottling = array();
+
+/**
* Map of job types to configuration arrays.
* This determines which queue class and storage system is used for each job type.
* Job types that do not have explicit configuration will use the 'default' config.
@@ -6065,7 +6386,8 @@ $wgJobQueueAggregator = array(
* Expensive Querypages are already updated.
*/
$wgSpecialPageCacheUpdates = array(
- 'Statistics' => array( 'SiteStatsUpdate', 'cacheUpdate' )
+ 'Statistics' => array( 'SiteStatsUpdate', 'cacheUpdate' ),
+ 'Activeusers' => array( 'SpecialActiveUsers', 'cacheUpdate' ),
);
/**
@@ -6262,9 +6584,6 @@ $wgLogActions = array(
'protect/modify' => 'modifiedarticleprotection',
'protect/unprotect' => 'unprotectedarticle',
'protect/move_prot' => 'movedarticleprotection',
- 'upload/upload' => 'uploadedimage',
- 'upload/overwrite' => 'overwroteimage',
- 'upload/revert' => 'uploadedimage',
'import/upload' => 'import-logentry-upload',
'import/interwiki' => 'import-logentry-interwiki',
'merge/merge' => 'pagemerge-logentry',
@@ -6291,6 +6610,9 @@ $wgLogActionsHandlers = array(
'patrol/patrol' => 'PatrolLogFormatter',
'rights/rights' => 'RightsLogFormatter',
'rights/autopromote' => 'RightsLogFormatter',
+ 'upload/upload' => 'LogFormatter',
+ 'upload/overwrite' => 'LogFormatter',
+ 'upload/revert' => 'LogFormatter',
);
/**
@@ -6325,11 +6647,6 @@ $wgDisableQueryPageUpdate = false;
$wgSpecialPageGroups = array();
/**
- * Whether or not to sort special pages in Special:Specialpages
- */
-$wgSortSpecialPages = true;
-
-/**
* On Special:Unusedimages, consider images "used", if they are put
* into a category. Default (false) is not to count those as used.
*/
@@ -6379,12 +6696,6 @@ $wgActions = array(
'watch' => true,
);
-/**
- * Array of disabled article actions, e.g. view, edit, delete, etc.
- * @deprecated since 1.18; just set $wgActions['action'] = false instead
- */
-$wgDisabledActions = array();
-
/** @} */ # end actions }
/*************************************************************************//**
@@ -6470,7 +6781,7 @@ $wgExemptFromUserRobotsControl = null;
* Enable the MediaWiki API for convenient access to
* machine-readable data via api.php
*
- * See http://www.mediawiki.org/wiki/API
+ * See https://www.mediawiki.org/wiki/API
*/
$wgEnableAPI = true;
@@ -6499,13 +6810,76 @@ $wgDebugAPI = false;
/**
* API module extensions.
- * Associative array mapping module name to class name.
+ *
+ * Associative array mapping module name to modules specs;
+ * Each module spec is an associative array containing at least
+ * the 'class' key for the module's class, and optionally a
+ * 'factory' key for the factory function to use for the module.
+ *
+ * That factory function will be called with two parameters,
+ * the parent module (an instance of ApiBase, usually ApiMain)
+ * and the name the module was registered under. The return
+ * value must be an instance of the class given in the 'class'
+ * field.
+ *
+ * For backward compatibility, the module spec may also be a
+ * simple string containing the module's class name. In that
+ * case, the class' constructor will be called with the parent
+ * module and module name as parameters, as described above.
+ *
+ * Examples for registering API modules:
+ *
+ * @code
+ * $wgAPIModules['foo'] = 'ApiFoo';
+ * $wgAPIModules['bar'] = array(
+ * 'class' => 'ApiBar',
+ * 'factory' => function( $main, $name ) { ... }
+ * );
+ * $wgAPIModules['xyzzy'] = array(
+ * 'class' => 'ApiXyzzy',
+ * 'factory' => array( 'XyzzyFactory', 'newApiModule' )
+ * );
+ * @endcode
+ *
* Extension modules may override the core modules.
- * @todo Describe each of the variables, group them and add examples
+ * See ApiMain::$Modules for a list of the core modules.
*/
$wgAPIModules = array();
+
+/**
+ * API format module extensions.
+ * Associative array mapping format module name to module specs (see $wgAPIModules).
+ * Extension modules may override the core modules.
+ *
+ * See ApiMain::$Formats for a list of the core format modules.
+ */
+$wgAPIFormatModules = array();
+
+/**
+ * API Query meta module extensions.
+ * Associative array mapping meta module name to module specs (see $wgAPIModules).
+ * Extension modules may override the core modules.
+ *
+ * See ApiQuery::$QueryMetaModules for a list of the core meta modules.
+ */
$wgAPIMetaModules = array();
+
+/**
+ * API Query prop module extensions.
+ * Associative array mapping prop module name to module specs (see $wgAPIModules).
+ * Extension modules may override the core modules.
+ *
+ * See ApiQuery::$QueryPropModules for a list of the core prop modules.
+ */
$wgAPIPropModules = array();
+
+/**
+ * API Query list module extensions.
+ * Associative array mapping list module name to module specs (see $wgAPIModules).
+ * Extension modules may override the core modules.
+ *
+ * See ApiQuery::$QueryListModules for a list of the core list modules.
+ */
$wgAPIListModules = array();
/**
@@ -6683,12 +7057,12 @@ $wgShellLocale = 'en_US.utf8';
*/
/**
- * Timeout for HTTP requests done internally
+ * Timeout for HTTP requests done internally, in seconds.
*/
$wgHTTPTimeout = 25;
/**
- * Timeout for Asynchronous (background) HTTP requests
+ * Timeout for Asynchronous (background) HTTP requests, in seconds.
*/
$wgAsyncHTTPTimeout = 25;
@@ -6720,6 +7094,14 @@ $wgHTTPConnectTimeout = 5e0;
$wgJobRunRate = 1;
/**
+ * When $wgJobRunRate > 0, try to run jobs asynchronously, spawning a new process
+ * to handle the job execution, instead of blocking the request until the job
+ * execution finishes.
+ * @since 1.23
+ */
+$wgRunJobsAsync = true;
+
+/**
* Number of rows to update per job
*/
$wgUpdateRowsPerJob = 500;
@@ -6729,15 +7111,6 @@ $wgUpdateRowsPerJob = 500;
*/
$wgUpdateRowsPerQuery = 100;
-/**
- * Do not purge all the pages that use a page when it is edited
- * if there are more than this many such pages. This is used to
- * avoid invalidating a large portion of the squid/parser cache.
- *
- * This setting should factor in any squid/parser cache expiry settings.
- */
-$wgMaxBacklinksInvalidate = false;
-
/** @} */ # End job queue }
/************************************************************************//**
@@ -6886,10 +7259,45 @@ $wgSiteTypes = array(
);
/**
- * Formerly a list of files for HipHop compilation
- * @deprecated since 1.22
+ * Whether the page_props table has a pp_sortkey column. Set to false in case
+ * the respective database schema change was not applied.
+ * @since 1.23
+ */
+$wgPagePropsHaveSortkey = true;
+
+/**
+ * Port where you have HTTPS running
+ * Supports HTTPS on non-standard ports
+ * @see bug 65184
+ * @since 1.24
+ */
+$wgHttpsPort = 443;
+
+/**
+ * Secret and algorithm for hmac-based key derivation function (fast,
+ * cryptographically secure random numbers).
+ * This should be set in LocalSettings.php, otherwise wgSecretKey will
+ * be used.
+ * @since 1.24
+ */
+$wgHKDFSecret = false;
+$wgHKDFAlgorithm = 'sha256';
+
+/**
+ * Enable page language feature
+ * Allows setting page language in database
+ * @var bool
+ * @since 1.24
+ */
+$wgPageLanguageUseDB = false;
+
+/**
+ * Enable use of the *_namespace fields of the pagelinks, redirect, and templatelinks tables.
+ * Set this only if the fields are fully populated. This may be removed in 1.25.
+ * @var bool
+ * @since 1.24
*/
-$wgCompiledFiles = array();
+$wgUseLinkNamespaceDBFields = true;
/**
* For really cool vim folding this needs to be at the end:
diff --git a/includes/Defines.php b/includes/Defines.php
index 86c5520b..017e9ea4 100644
--- a/includes/Defines.php
+++ b/includes/Defines.php
@@ -59,7 +59,6 @@ define( 'DB_MASTER', -2 ); # Write to master (or only server)
# Obsolete aliases
define( 'DB_READ', -1 );
define( 'DB_WRITE', -2 );
-define( 'DB_LAST', -3 ); # deprecated since 2008, usage throws exception
/**@{
* Virtual namespaces; don't appear in the page database
@@ -113,23 +112,33 @@ define( 'CACHE_NONE', 0 ); // Do not cache
define( 'CACHE_DB', 1 ); // Store cache objects in the DB
define( 'CACHE_MEMCACHED', 2 ); // MemCached, must specify servers in $wgMemCacheServers
define( 'CACHE_ACCEL', 3 ); // APC, XCache or WinCache
-define( 'CACHE_DBA', 4 ); // Use PHP's DBA extension to store in a DBM-style database
/**@}*/
/**@{
* Media types.
* This defines constants for the value returned by File::getMediaType()
*/
-define( 'MEDIATYPE_UNKNOWN', 'UNKNOWN' ); // unknown format
-define( 'MEDIATYPE_BITMAP', 'BITMAP' ); // some bitmap image or image source (like psd, etc). Can't scale up.
-define( 'MEDIATYPE_DRAWING', 'DRAWING' ); // some vector drawing (SVG, WMF, PS, ...) or image source (oo-draw, etc). Can scale up.
-define( 'MEDIATYPE_AUDIO', 'AUDIO' ); // simple audio file (ogg, mp3, wav, midi, whatever)
-define( 'MEDIATYPE_VIDEO', 'VIDEO' ); // simple video file (ogg, mpg, etc; no not include formats here that may contain executable sections or scripts!)
-define( 'MEDIATYPE_MULTIMEDIA', 'MULTIMEDIA' ); // Scriptable Multimedia (flash, advanced video container formats, etc)
-define( 'MEDIATYPE_OFFICE', 'OFFICE' ); // Office Documents, Spreadsheets (office formats possibly containing apples, scripts, etc)
-define( 'MEDIATYPE_TEXT', 'TEXT' ); // Plain text (possibly containing program code or scripts)
-define( 'MEDIATYPE_EXECUTABLE', 'EXECUTABLE' ); // binary executable
-define( 'MEDIATYPE_ARCHIVE', 'ARCHIVE' ); // archive file (zip, tar, etc)
+// unknown format
+define( 'MEDIATYPE_UNKNOWN', 'UNKNOWN' );
+// some bitmap image or image source (like psd, etc). Can't scale up.
+define( 'MEDIATYPE_BITMAP', 'BITMAP' );
+// some vector drawing (SVG, WMF, PS, ...) or image source (oo-draw, etc). Can scale up.
+define( 'MEDIATYPE_DRAWING', 'DRAWING' );
+// simple audio file (ogg, mp3, wav, midi, whatever)
+define( 'MEDIATYPE_AUDIO', 'AUDIO' );
+// simple video file (ogg, mpg, etc;
+// no not include formats here that may contain executable sections or scripts!)
+define( 'MEDIATYPE_VIDEO', 'VIDEO' );
+// Scriptable Multimedia (flash, advanced video container formats, etc)
+define( 'MEDIATYPE_MULTIMEDIA', 'MULTIMEDIA' );
+// Office Documents, Spreadsheets (office formats possibly containing apples, scripts, etc)
+define( 'MEDIATYPE_OFFICE', 'OFFICE' );
+// Plain text (possibly containing program code or scripts)
+define( 'MEDIATYPE_TEXT', 'TEXT' );
+// binary executable
+define( 'MEDIATYPE_EXECUTABLE', 'EXECUTABLE' );
+// archive file (zip, tar, etc)
+define( 'MEDIATYPE_ARCHIVE', 'ARCHIVE' );
/**@}*/
/**@{
@@ -155,11 +164,6 @@ define( 'ALF_NO_BLOCK_LOCK', 8 );
* Date format selectors; used in user preference storage and by
* Language::date() and co.
*/
-/*define( 'MW_DATE_DEFAULT', '0' );
-define( 'MW_DATE_MDY', '1' );
-define( 'MW_DATE_DMY', '2' );
-define( 'MW_DATE_YMD', '3' );
-define( 'MW_DATE_ISO', 'ISO 8601' );*/
define( 'MW_DATE_DEFAULT', 'default' );
define( 'MW_DATE_MDY', 'mdy' );
define( 'MW_DATE_DMY', 'dmy' );
@@ -172,9 +176,7 @@ define( 'MW_DATE_ISO', 'ISO 8601' );
*/
define( 'RC_EDIT', 0 );
define( 'RC_NEW', 1 );
-define( 'RC_MOVE', 2 ); // obsolete
define( 'RC_LOG', 3 );
-define( 'RC_MOVE_OVER_REDIRECT', 4 ); // obsolete
define( 'RC_EXTERNAL', 5 );
/**@}*/
@@ -279,6 +281,7 @@ define( 'CONTENT_MODEL_WIKITEXT', 'wikitext' );
define( 'CONTENT_MODEL_JAVASCRIPT', 'javascript' );
define( 'CONTENT_MODEL_CSS', 'css' );
define( 'CONTENT_MODEL_TEXT', 'text' );
+define( 'CONTENT_MODEL_JSON', 'json' );
/**@}*/
/**@{
@@ -288,12 +291,20 @@ define( 'CONTENT_MODEL_TEXT', 'text' );
* Extensions are free to use the below formats, or define their own.
* It is recommended to stick with the conventions for MIME types.
*/
-define( 'CONTENT_FORMAT_WIKITEXT', 'text/x-wiki' ); // wikitext
-define( 'CONTENT_FORMAT_JAVASCRIPT', 'text/javascript' ); // for js pages
-define( 'CONTENT_FORMAT_CSS', 'text/css' ); // for css pages
-define( 'CONTENT_FORMAT_TEXT', 'text/plain' ); // for future use, e.g. with some plain-html messages.
-define( 'CONTENT_FORMAT_HTML', 'text/html' ); // for future use, e.g. with some plain-html messages.
-define( 'CONTENT_FORMAT_SERIALIZED', 'application/vnd.php.serialized' ); // for future use with the api and for extensions
-define( 'CONTENT_FORMAT_JSON', 'application/json' ); // for future use with the api, and for use by extensions
-define( 'CONTENT_FORMAT_XML', 'application/xml' ); // for future use with the api, and for use by extensions
+// wikitext
+define( 'CONTENT_FORMAT_WIKITEXT', 'text/x-wiki' );
+// for js pages
+define( 'CONTENT_FORMAT_JAVASCRIPT', 'text/javascript' );
+// for css pages
+define( 'CONTENT_FORMAT_CSS', 'text/css' );
+// for future use, e.g. with some plain-html messages.
+define( 'CONTENT_FORMAT_TEXT', 'text/plain' );
+// for future use, e.g. with some plain-html messages.
+define( 'CONTENT_FORMAT_HTML', 'text/html' );
+// for future use with the api and for extensions
+define( 'CONTENT_FORMAT_SERIALIZED', 'application/vnd.php.serialized' );
+// for future use with the api, and for use by extensions
+define( 'CONTENT_FORMAT_JSON', 'application/json' );
+// for future use with the api, and for use by extensions
+define( 'CONTENT_FORMAT_XML', 'application/xml' );
/**@}*/
diff --git a/includes/DeprecatedGlobal.php b/includes/DeprecatedGlobal.php
index d48bd0b0..14329d32 100644
--- a/includes/DeprecatedGlobal.php
+++ b/includes/DeprecatedGlobal.php
@@ -23,20 +23,22 @@
/**
* 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;
+ protected $realValue, $version;
function __construct( $name, $realValue, $version = false ) {
parent::__construct( $name );
- $this->mRealValue = $realValue;
- $this->mVersion = $version;
+ $this->realValue = $realValue;
+ $this->version = $version;
}
+ // @codingStandardsIgnoreStart
+ // PSR2.Methods.MethodDeclaration.Underscore
+ // PSR2.Classes.PropertyDeclaration.ScopeMissing
function _newObject() {
+
/* Put the caller offset for wfDeprecated as 6, as
* that gives the function that uses this object, since:
* 1 = this function ( _newObject )
@@ -49,7 +51,8 @@ class DeprecatedGlobal extends StubObject {
* sequences for this method, but that seems to be
* rather unlikely.
*/
- wfDeprecated( '$' . $this->mGlobal, $this->mVersion, false, 6 );
- return $this->mRealValue;
+ wfDeprecated( '$' . $this->global, $this->version, false, 6 );
+ return $this->realValue;
}
+ // @codingStandardsIgnoreEnd
}
diff --git a/includes/EditPage.php b/includes/EditPage.php
index 4dd83845..128244a8 100644
--- a/includes/EditPage.php
+++ b/includes/EditPage.php
@@ -1,6 +1,6 @@
<?php
/**
- * Page edition user interface.
+ * User interface for page editing.
*
* 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
@@ -36,7 +36,6 @@
* headaches, which may be fatal.
*/
class EditPage {
-
/**
* Status: Article successfully updated
*/
@@ -68,11 +67,6 @@ class EditPage {
const AS_CONTENT_TOO_BIG = 216;
/**
- * Status: User cannot edit? (not used)
- */
- const AS_USER_CANNOT_EDIT = 217;
-
- /**
* Status: this anonymous user is not allowed to edit this page
*/
const AS_READ_ONLY_PAGE_ANON = 218;
@@ -105,7 +99,7 @@ class EditPage {
const AS_NO_CREATE_PERMISSION = 223;
/**
- * Status: user tried to create a blank page
+ * Status: user tried to create a blank page and wpIgnoreBlankArticle == false
*/
const AS_BLANK_ARTICLE = 224;
@@ -131,11 +125,6 @@ class EditPage {
const AS_MAX_ARTICLE_SIZE_EXCEEDED = 229;
/**
- * not used
- */
- const AS_OK = 230;
-
- /**
* Status: WikiPage::doEdit() was unsuccessful
*/
const AS_END = 231;
@@ -182,8 +171,9 @@ class EditPage {
* The cookie will be removed instantly if the JavaScript runs.
*
* Otherwise, though, we don't want the cookies to accumulate.
- * RFC 2109 ( https://www.ietf.org/rfc/rfc2109.txt ) specifies a possible limit of only 20 cookies per domain.
- * This still applies at least to some versions of IE without full updates:
+ * RFC 2109 ( https://www.ietf.org/rfc/rfc2109.txt ) specifies a possible
+ * limit of only 20 cookies per domain. This still applies at least to some
+ * versions of IE without full updates:
* https://blogs.msdn.com/b/ieinternals/archive/2009/08/20/wininet-ie-cookie-internals-faq.aspx
*
* A value of 20 minutes should be enough to take into account slow loads and minor
@@ -191,65 +181,166 @@ class EditPage {
*/
const POST_EDIT_COOKIE_DURATION = 1200;
- /**
- * @var Article
- */
- var $mArticle;
+ /** @var Article */
+ public $mArticle;
- /**
- * @var Title
- */
- var $mTitle;
+ /** @var Title */
+ public $mTitle;
+
+ /** @var null|Title */
private $mContextTitle = null;
- var $action = 'submit';
- var $isConflict = false;
- var $isCssJsSubpage = false;
- var $isCssSubpage = false;
- var $isJsSubpage = false;
- var $isWrongCaseCssJsPage = false;
- var $isNew = false; // new page or new section
- var $deletedSinceEdit;
- var $formtype;
- var $firsttime;
- var $lastDelete;
- var $mTokenOk = false;
- var $mTokenOkExceptSuffix = false;
- var $mTriedSave = false;
- var $incompleteForm = false;
- var $tooBig = false;
- var $kblength = false;
- var $missingComment = false;
- var $missingSummary = false;
- var $allowBlankSummary = false;
- var $autoSumm = '';
- var $hookError = '';
- #var $mPreviewTemplates;
-
- /**
- * @var ParserOutput
- */
- var $mParserOutput;
-
- /**
- * Has a summary been preset using GET parameter &summary= ?
- * @var Bool
- */
- var $hasPresetSummary = false;
-
- var $mBaseRevision = false;
- var $mShowSummaryField = true;
+
+ /** @var string */
+ public $action = 'submit';
+
+ /** @var bool */
+ public $isConflict = false;
+
+ /** @var bool */
+ public $isCssJsSubpage = false;
+
+ /** @var bool */
+ public $isCssSubpage = false;
+
+ /** @var bool */
+ public $isJsSubpage = false;
+
+ /** @var bool */
+ public $isWrongCaseCssJsPage = false;
+
+ /** @var bool New page or new section */
+ public $isNew = false;
+
+ /** @var bool */
+ public $deletedSinceEdit;
+
+ /** @var string */
+ public $formtype;
+
+ /** @var bool */
+ public $firsttime;
+
+ /** @var bool|stdClass */
+ public $lastDelete;
+
+ /** @var bool */
+ public $mTokenOk = false;
+
+ /** @var bool */
+ public $mTokenOkExceptSuffix = false;
+
+ /** @var bool */
+ public $mTriedSave = false;
+
+ /** @var bool */
+ public $incompleteForm = false;
+
+ /** @var bool */
+ public $tooBig = false;
+
+ /** @var bool */
+ public $kblength = false;
+
+ /** @var bool */
+ public $missingComment = false;
+
+ /** @var bool */
+ public $missingSummary = false;
+
+ /** @var bool */
+ public $allowBlankSummary = false;
+
+ /** @var bool */
+ protected $blankArticle = false;
+
+ /** @var bool */
+ protected $allowBlankArticle = false;
+
+ /** @var string */
+ public $autoSumm = '';
+
+ /** @var string */
+ public $hookError = '';
+
+ /** @var ParserOutput */
+ public $mParserOutput;
+
+ /** @var bool Has a summary been preset using GET parameter &summary= ? */
+ public $hasPresetSummary = false;
+
+ /** @var bool */
+ public $mBaseRevision = false;
+
+ /** @var bool */
+ public $mShowSummaryField = true;
# Form values
- var $save = false, $preview = false, $diff = false;
- var $minoredit = false, $watchthis = false, $recreate = false;
- var $textbox1 = '', $textbox2 = '', $summary = '', $nosummary = false;
- var $edittime = '', $section = '', $sectiontitle = '', $starttime = '';
- var $oldid = 0, $editintro = '', $scrolltop = null, $bot = true;
- var $contentModel = null, $contentFormat = null;
+
+ /** @var bool */
+ public $save = false;
+
+ /** @var bool */
+ public $preview = false;
+
+ /** @var bool */
+ public $diff = false;
+
+ /** @var bool */
+ public $minoredit = false;
+
+ /** @var bool */
+ public $watchthis = false;
+
+ /** @var bool */
+ public $recreate = false;
+
+ /** @var string */
+ public $textbox1 = '';
+
+ /** @var string */
+ public $textbox2 = '';
+
+ /** @var string */
+ public $summary = '';
+
+ /** @var bool */
+ public $nosummary = false;
+
+ /** @var string */
+ public $edittime = '';
+
+ /** @var string */
+ public $section = '';
+
+ /** @var string */
+ public $sectiontitle = '';
+
+ /** @var string */
+ public $starttime = '';
+
+ /** @var int */
+ public $oldid = 0;
+
+ /** @var string */
+ public $editintro = '';
+
+ /** @var null */
+ public $scrolltop = null;
+
+ /** @var bool */
+ public $bot = true;
+
+ /** @var null|string */
+ public $contentModel = null;
+
+ /** @var null|string */
+ public $contentFormat = null;
# Placeholders for text injection by hooks (must be HTML)
# extensions should take care to _append_ to the present value
- public $editFormPageTop = ''; // Before even the preview
+
+ /** @var string Before even the preview */
+ public $editFormPageTop = '';
public $editFormTextTop = '';
public $editFormTextBeforeContent = '';
public $editFormTextAfterWarn = '';
@@ -265,15 +356,17 @@ class EditPage {
public $suppressIntro = false;
- /**
- * Set to true to allow editing of non-text content types.
- *
- * @var bool
- */
+ /** @var bool Set to true to allow editing of non-text content types. */
public $allowNonTextContent = false;
+ /** @var bool */
+ protected $edit;
+
+ /** @var bool */
+ public $live;
+
/**
- * @param $article Article
+ * @param Article $article
*/
public function __construct( Article $article ) {
$this->mArticle = $article;
@@ -303,7 +396,7 @@ class EditPage {
/**
* Set the context Title object
*
- * @param $title Title object or null
+ * @param Title|null $title Title object or null
*/
public function setContextTitle( $title ) {
$this->mContextTitle = $title;
@@ -314,7 +407,7 @@ class EditPage {
* If not set, $wgTitle will be returned. This behavior might change in
* the future to return $this->mTitle instead.
*
- * @return Title object
+ * @return Title
*/
public function getContextTitle() {
if ( is_null( $this->mContextTitle ) ) {
@@ -325,6 +418,18 @@ class EditPage {
}
}
+ /**
+ * Returns if the given content model is editable.
+ *
+ * @param string $modelId The ID of the content model to test. Use CONTENT_MODEL_XXX constants.
+ * @return bool
+ * @throws MWException If $modelId has no known handler
+ */
+ public function isSupportedContentModel( $modelId ) {
+ return $this->allowNonTextContent ||
+ ContentHandler::getForModelID( $modelId ) instanceof TextContentHandler;
+ }
+
function submit() {
$this->edit();
}
@@ -406,6 +511,7 @@ class EditPage {
$this->isCssJsSubpage = $this->mTitle->isCssJsSubpage();
$this->isCssSubpage = $this->mTitle->isCssSubpage();
$this->isJsSubpage = $this->mTitle->isJsSubpage();
+ // @todo FIXME: Silly assignment.
$this->isWrongCaseCssJsPage = $this->isWrongCaseCssJsPage();
# Show applicable editing introductions
@@ -463,9 +569,9 @@ class EditPage {
# Ignore some permissions errors when a user is just previewing/viewing diffs
$remove = array();
foreach ( $permErrors as $error ) {
- if ( ( $this->preview || $this->diff ) &&
- ( $error[0] == 'blockedtext' || $error[0] == 'autoblockedtext' ) )
- {
+ if ( ( $this->preview || $this->diff )
+ && ( $error[0] == 'blockedtext' || $error[0] == 'autoblockedtext' )
+ ) {
$remove[] = $error;
}
}
@@ -482,8 +588,8 @@ class EditPage {
* "View source for ..." page displaying the source code after the error message.
*
* @since 1.19
- * @param array $permErrors of permissions errors, as returned by
- * Title::getUserPermissionsErrors().
+ * @param array $permErrors Array of permissions errors, as returned by
+ * Title::getUserPermissionsErrors().
* @throws PermissionsError
*/
protected function displayPermissionsError( array $permErrors ) {
@@ -506,8 +612,13 @@ class EditPage {
throw new PermissionsError( $action, $permErrors );
}
+ wfRunHooks( 'EditPage::showReadOnlyForm:initial', array( $this, &$wgOut ) );
+
$wgOut->setRobotPolicy( 'noindex,nofollow' );
- $wgOut->setPageTitle( wfMessage( 'viewsource-title', $this->getContextTitle()->getPrefixedText() ) );
+ $wgOut->setPageTitle( wfMessage(
+ 'viewsource-title',
+ $this->getContextTitle()->getPrefixedText()
+ ) );
$wgOut->addBacklinkSubtitle( $this->getContextTitle() );
$wgOut->addWikiText( $wgOut->formatPermissionsErrorMessage( $permErrors, 'edit' ) );
$wgOut->addHTML( "<hr />\n" );
@@ -535,26 +646,6 @@ class EditPage {
}
/**
- * Show a read-only error
- * Parameters are the same as OutputPage:readOnlyPage()
- * Redirect to the article page if redlink=1
- * @deprecated in 1.19; use displayPermissionsError() instead
- */
- 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.
- // Redirect to the article page and let them click the edit tab if
- // they really want a permission error.
- $wgOut->redirect( $this->mTitle->getFullURL() );
- } else {
- $wgOut->readOnlyPage( $source, $protected, $reasons, $action );
- }
- }
-
- /**
* Should we show a preview when the edit form is first shown?
*
* @return bool
@@ -570,13 +661,15 @@ class EditPage {
} elseif ( $this->section == 'new' ) {
// Nothing *to* preview for new sections
return false;
- } elseif ( ( $wgRequest->getVal( 'preload' ) !== null || $this->mTitle->exists() ) && $wgUser->getOption( 'previewonfirst' ) ) {
+ } elseif ( ( $wgRequest->getVal( 'preload' ) !== null || $this->mTitle->exists() )
+ && $wgUser->getOption( 'previewonfirst' )
+ ) {
// Standard preference behavior
return true;
- } elseif ( !$this->mTitle->exists() &&
- isset( $wgPreviewOnOpenNamespaces[$this->mTitle->getNamespace()] ) &&
- $wgPreviewOnOpenNamespaces[$this->mTitle->getNamespace()] )
- {
+ } elseif ( !$this->mTitle->exists()
+ && isset( $wgPreviewOnOpenNamespaces[$this->mTitle->getNamespace()] )
+ && $wgPreviewOnOpenNamespaces[$this->mTitle->getNamespace()]
+ ) {
// Categories are special
return true;
} else {
@@ -609,7 +702,7 @@ class EditPage {
* Subclasses may override this to replace the default behavior, which is
* to check ContentHandler::supportsSections.
*
- * @return bool true if this edit page supports sections, false otherwise.
+ * @return bool True if this edit page supports sections, false otherwise.
*/
protected function isSectionEditSupported() {
$contentHandler = ContentHandler::getForTitle( $this->mTitle );
@@ -618,7 +711,8 @@ class EditPage {
/**
* This function collects the form data and uses it to populate various member variables.
- * @param $request WebRequest
+ * @param WebRequest $request
+ * @throws ErrorPageError
*/
function importFormData( &$request ) {
global $wgContLang, $wgUser;
@@ -685,9 +779,13 @@ class EditPage {
// suhosin.request.max_value_length (d'oh)
$this->incompleteForm = true;
} else {
- // edittime should be one of our last fields; if it's missing,
- // the submission probably broke somewhere in the middle.
- $this->incompleteForm = is_null( $this->edittime );
+ // If we receive the last parameter of the request, we can fairly
+ // claim the POST request has not been truncated.
+
+ // TODO: softened the check for cutover. Once we determine
+ // that it is safe, we should complete the transition by
+ // removing the "edittime" clause.
+ $this->incompleteForm = ( !$request->getVal( 'wpUltimateParam' ) && is_null( $this->edittime ) );
}
if ( $this->incompleteForm ) {
# If the form is incomplete, force to preview.
@@ -734,15 +832,18 @@ class EditPage {
$this->watchthis = $request->getCheck( 'wpWatchthis' );
# Don't force edit summaries when a user is editing their own user or talk page
- if ( ( $this->mTitle->mNamespace == NS_USER || $this->mTitle->mNamespace == NS_USER_TALK ) &&
- $this->mTitle->getText() == $wgUser->getName() )
- {
+ if ( ( $this->mTitle->mNamespace == NS_USER || $this->mTitle->mNamespace == NS_USER_TALK )
+ && $this->mTitle->getText() == $wgUser->getName()
+ ) {
$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' );
+
+ $this->allowBlankArticle = $request->getBool( 'wpIgnoreBlankArticle' );
} else {
# Not a posted form? Start with nothing.
wfDebug( __METHOD__ . ": Not a posted form.\n" );
@@ -756,7 +857,8 @@ class EditPage {
$this->save = false;
$this->diff = false;
$this->minoredit = false;
- $this->watchthis = $request->getBool( 'watchthis', false ); // Watch may be overridden by request parameters
+ // Watch may be overridden by request parameters
+ $this->watchthis = $request->getBool( 'watchthis', false );
$this->recreate = false;
// When creating a new section, we can preload a section title by passing it as the
@@ -765,8 +867,7 @@ class EditPage {
$this->sectiontitle = $request->getVal( 'preloadtitle' );
// Once wpSummary isn't being use for setting section titles, we should delete this.
$this->summary = $request->getVal( 'preloadtitle' );
- }
- elseif ( $this->section != 'new' && $request->getVal( 'summary' ) ) {
+ } elseif ( $this->section != 'new' && $request->getVal( 'summary' ) ) {
$this->summary = $request->getText( 'summary' );
if ( $this->summary !== '' ) {
$this->hasPresetSummary = true;
@@ -783,12 +884,26 @@ class EditPage {
$this->bot = $request->getBool( 'bot', true );
$this->nosummary = $request->getBool( 'nosummary' );
- $content_handler = ContentHandler::getForTitle( $this->mTitle );
- $this->contentModel = $request->getText( 'model', $content_handler->getModelID() ); #may be overridden by revision
- $this->contentFormat = $request->getText( 'format', $content_handler->getDefaultFormat() ); #may be overridden by revision
+ // May be overridden by revision.
+ $this->contentModel = $request->getText( 'model', $this->contentModel );
+ // May be overridden by revision.
+ $this->contentFormat = $request->getText( 'format', $this->contentFormat );
- #TODO: check if the desired model is allowed in this namespace, and if a transition from the page's current model to the new model is allowed
- #TODO: check if the desired content model supports the given content format!
+ if ( !ContentHandler::getForModelID( $this->contentModel )
+ ->isSupportedFormat( $this->contentFormat )
+ ) {
+ throw new ErrorPageError(
+ 'editpage-notsupportedcontentformat-title',
+ 'editpage-notsupportedcontentformat-text',
+ array( $this->contentFormat, ContentHandler::getLocalizedName( $this->contentModel ) )
+ );
+ }
+
+ /**
+ * @todo Check if the desired model is allowed in this namespace, and if
+ * a transition from the page's current model to the new model is
+ * allowed.
+ */
$this->live = $request->getCheck( 'live' );
$this->editintro = $request->getText( 'editintro',
@@ -807,7 +922,7 @@ class EditPage {
* this method should be overridden and return the page text that will be used
* for saving, preview parsing and so on...
*
- * @param $request WebRequest
+ * @param WebRequest $request
*/
protected function importContentFormData( &$request ) {
return; // Don't do anything, EditPage already extracted wpTextbox1
@@ -816,7 +931,7 @@ class EditPage {
/**
* Initialise form fields in the object
* Called on the first invocation, e.g. when a user clicks an edit link
- * @return bool -- if the requested section is valid
+ * @return bool If the requested section is valid
*/
function initialiseForm() {
global $wgUser;
@@ -850,37 +965,14 @@ class EditPage {
}
/**
- * Fetch initial editing page content.
- *
- * @param $def_text string|bool
- * @return mixed string on success, $def_text for invalid sections
- * @private
- * @deprecated since 1.21, get WikiPage::getContent() instead.
- */
- function getContent( $def_text = false ) {
- ContentHandler::deprecated( __METHOD__, '1.21' );
-
- if ( $def_text !== null && $def_text !== false && $def_text !== '' ) {
- $def_content = $this->toEditContent( $def_text );
- } else {
- $def_content = false;
- }
-
- $content = $this->getContentObject( $def_content );
-
- // Note: EditPage should only be used with text based content anyway.
- return $this->toEditText( $content );
- }
-
- /**
* @param Content|null $def_content The default value to return
*
- * @return mixed Content on success, $def_content for invalid sections
+ * @return Content|null Content on success, $def_content for invalid sections
*
* @since 1.21
*/
protected function getContentObject( $def_content = null ) {
- global $wgOut, $wgRequest;
+ global $wgOut, $wgRequest, $wgUser, $wgContLang;
wfProfileIn( __METHOD__ );
@@ -900,14 +992,15 @@ class EditPage {
$preload = $wgRequest->getVal( 'preload',
// Custom preload text for new sections
$this->section === 'new' ? 'MediaWiki:addsection-preload' : '' );
+ $params = $wgRequest->getArray( 'preloadparams', array() );
- $content = $this->getPreloadedContent( $preload );
+ $content = $this->getPreloadedContent( $preload, $params );
}
// For existing pages, get text based on "undo" or section parameters.
} else {
if ( $this->section != '' ) {
// Get section edit text (returns $def_text for invalid sections)
- $orig = $this->getOriginalContent();
+ $orig = $this->getOriginalContent( $wgUser );
$content = $orig ? $orig->getSection( $this->section ) : null;
if ( !$content ) {
@@ -918,10 +1011,6 @@ class EditPage {
$undo = $wgRequest->getInt( 'undo' );
if ( $undo > 0 && $undoafter > 0 ) {
- if ( $undo < $undoafter ) {
- # If they got undoafter and undo round the wrong way, switch them
- list( $undo, $undoafter ) = array( $undoafter, $undo );
- }
$undorev = Revision::newFromId( $undo );
$oldrev = Revision::newFromId( $undoafter );
@@ -930,8 +1019,6 @@ class EditPage {
# the revisions exist and they were not deleted.
# Otherwise, $content will be left as-is.
if ( !is_null( $undorev ) && !is_null( $oldrev ) &&
- $undorev->getPage() == $oldrev->getPage() &&
- $undorev->getPage() == $this->mTitle->getArticleID() &&
!$undorev->isDeleted( Revision::DELETED_TEXT ) &&
!$oldrev->isDeleted( Revision::DELETED_TEXT ) ) {
@@ -941,34 +1028,45 @@ class EditPage {
# Warn the user that something went wrong
$undoMsg = 'failure';
} else {
- # Inform the user of our success and set an automatic edit summary
- $undoMsg = 'success';
-
- # If we just undid one rev, use an autosummary
- $firstrev = $oldrev->getNext();
- if ( $firstrev && $firstrev->getId() == $undo ) {
- $userText = $undorev->getUserText();
- if ( $userText === '' ) {
- $undoSummary = wfMessage(
- 'undo-summary-username-hidden',
- $undo
- )->inContentLanguage()->text();
- } else {
- $undoSummary = wfMessage(
- 'undo-summary',
- $undo,
- $userText
- )->inContentLanguage()->text();
- }
- if ( $this->summary === '' ) {
- $this->summary = $undoSummary;
- } else {
- $this->summary = $undoSummary . wfMessage( 'colon-separator' )
- ->inContentLanguage()->text() . $this->summary;
+ $oldContent = $this->mArticle->getPage()->getContent( Revision::RAW );
+ $popts = ParserOptions::newFromUserAndLang( $wgUser, $wgContLang );
+ $newContent = $content->preSaveTransform( $this->mTitle, $wgUser, $popts );
+
+ if ( $newContent->equals( $oldContent ) ) {
+ # Tell the user that the undo results in no change,
+ # i.e. the revisions were already undone.
+ $undoMsg = 'nochange';
+ $content = false;
+ } else {
+ # Inform the user of our success and set an automatic edit summary
+ $undoMsg = 'success';
+
+ # If we just undid one rev, use an autosummary
+ $firstrev = $oldrev->getNext();
+ if ( $firstrev && $firstrev->getId() == $undo ) {
+ $userText = $undorev->getUserText();
+ if ( $userText === '' ) {
+ $undoSummary = wfMessage(
+ 'undo-summary-username-hidden',
+ $undo
+ )->inContentLanguage()->text();
+ } else {
+ $undoSummary = wfMessage(
+ 'undo-summary',
+ $undo,
+ $userText
+ )->inContentLanguage()->text();
+ }
+ if ( $this->summary === '' ) {
+ $this->summary = $undoSummary;
+ } else {
+ $this->summary = $undoSummary . wfMessage( 'colon-separator' )
+ ->inContentLanguage()->text() . $this->summary;
+ }
+ $this->undidRev = $undo;
}
- $this->undidRev = $undo;
+ $this->formtype = 'diff';
}
- $this->formtype = 'diff';
}
} else {
// Failed basic sanity checks.
@@ -977,14 +1075,14 @@ class EditPage {
$undoMsg = 'norev';
}
- // Messages: undo-success, undo-failure, undo-norev
+ // Messages: undo-success, undo-failure, undo-norev, undo-nochange
$class = ( $undoMsg == 'success' ? '' : 'error ' ) . "mw-undo-{$undoMsg}";
$this->editFormPageTop .= $wgOut->parse( "<div class=\"{$class}\">" .
wfMessage( 'undo-' . $undoMsg )->plain() . '</div>', true, /* interface */true );
}
if ( $content === false ) {
- $content = $this->getOriginalContent();
+ $content = $this->getOriginalContent( $wgUser );
}
}
}
@@ -1005,9 +1103,10 @@ class EditPage {
* 'missing-revision' message.
*
* @since 1.19
+ * @param User $user The user to get the revision for
* @return Content|null
*/
- private function getOriginalContent() {
+ private function getOriginalContent( User $user ) {
if ( $this->section == 'new' ) {
return $this->getCurrentContent();
}
@@ -1020,7 +1119,7 @@ class EditPage {
return $handler->makeEmptyContent();
}
- $content = $revision->getContent();
+ $content = $revision->getContent( Revision::FOR_THIS_USER, $user );
return $content;
}
@@ -1053,23 +1152,9 @@ class EditPage {
}
/**
- * Use this method before edit() to preload some text into the edit box
- *
- * @param $text string
- * @deprecated since 1.21, use setPreloadedContent() instead.
- */
- public function setPreloadedText( $text ) {
- ContentHandler::deprecated( __METHOD__, "1.21" );
-
- $content = $this->toEditContent( $text );
-
- $this->setPreloadedContent( $content );
- }
-
- /**
* Use this method before edit() to preload some content into the edit box
*
- * @param $content Content
+ * @param Content $content
*
* @since 1.21
*/
@@ -1081,32 +1166,14 @@ class EditPage {
* Get the contents to be preloaded into the box, either set by
* an earlier setPreloadText() or by loading the given page.
*
- * @param string $preload representing the title to preload from.
- *
- * @return String
- *
- * @deprecated since 1.21, use getPreloadedContent() instead
- */
- protected function getPreloadedText( $preload ) {
- ContentHandler::deprecated( __METHOD__, "1.21" );
-
- $content = $this->getPreloadedContent( $preload );
- $text = $this->toEditText( $content );
-
- return $text;
- }
-
- /**
- * Get the contents to be preloaded into the box, either set by
- * an earlier setPreloadText() or by loading the given page.
- *
- * @param string $preload representing the title to preload from.
+ * @param string $preload Representing the title to preload from.
+ * @param array $params Parameters to use (interface-message style) in the preloaded text
*
* @return Content
*
* @since 1.21
*/
- protected function getPreloadedContent( $preload ) {
+ protected function getPreloadedContent( $preload, $params = array() ) {
global $wgUser;
if ( !empty( $this->mPreloadContent ) ) {
@@ -1160,13 +1227,13 @@ class EditPage {
$content = $converted;
}
- return $content->preloadTransform( $title, $parserOptions );
+ return $content->preloadTransform( $title, $parserOptions, $params );
}
/**
* Make sure the form isn't faking a user's credentials.
*
- * @param $request WebRequest
+ * @param WebRequest $request
* @return bool
* @private
*/
@@ -1189,18 +1256,24 @@ class EditPage {
* marked HttpOnly. The JavaScript code converts the cookie to a wgPostEdit config
* variable.
*
- * We use a path of '/' since wgCookiePath is not exposed to JS
- *
* If the variable were set on the server, it would be cached, which is unwanted
* since the post-edit state should only apply to the load right after the save.
+ *
+ * @param int $statusValue The status value (to check for new article status)
*/
- protected function setPostEditCookie() {
+ protected function setPostEditCookie( $statusValue ) {
$revisionId = $this->mArticle->getLatest();
$postEditKey = self::POST_EDIT_COOKIE_KEY_PREFIX . $revisionId;
+ $val = 'saved';
+ if ( $statusValue == self::AS_SUCCESS_NEW_ARTICLE ) {
+ $val = 'created';
+ } elseif ( $this->oldid ) {
+ $val = 'restored';
+ }
+
$response = RequestContext::getMain()->getRequest()->response();
- $response->setcookie( $postEditKey, '1', time() + self::POST_EDIT_COOKIE_DURATION, array(
- 'path' => '/',
+ $response->setcookie( $postEditKey, $val, time() + self::POST_EDIT_COOKIE_DURATION, array(
'httpOnly' => false,
) );
}
@@ -1208,20 +1281,41 @@ class EditPage {
/**
* Attempt submission
* @throws UserBlockedError|ReadOnlyError|ThrottledError|PermissionsError
- * @return bool false if output is done, true if the rest of the form should be displayed
+ * @return bool False if output is done, true if the rest of the form should be displayed
*/
- function attemptSave() {
- global $wgUser, $wgOut;
+ public function attemptSave() {
+ global $wgUser;
$resultDetails = false;
# Allow bots to exempt some edits from bot flagging
$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 ) {
+
+ return $this->handleStatus( $status, $resultDetails );
+ }
+
+ /**
+ * Handle status, such as after attempt save
+ *
+ * @param Status $status
+ * @param array|bool $resultDetails
+ *
+ * @throws ErrorPageError
+ * @return bool False, if output is done, true if rest of the form should be displayed
+ */
+ private function handleStatus( Status $status, $resultDetails ) {
+ global $wgUser, $wgOut;
+
+ /**
+ * @todo 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;
if ( !$resultDetails['nullEdit'] ) {
- $this->setPostEditCookie();
+ $this->setPostEditCookie( $status->value );
}
}
@@ -1234,6 +1328,7 @@ class EditPage {
case self::AS_TEXTBOX_EMPTY:
case self::AS_MAX_ARTICLE_SIZE_EXCEEDED:
case self::AS_END:
+ case self::AS_BLANK_ARTICLE:
return true;
case self::AS_HOOK_ERROR:
@@ -1254,7 +1349,10 @@ class EditPage {
$sectionanchor = $resultDetails['sectionanchor'];
// Give extensions a chance to modify URL query on update
- wfRunHooks( 'ArticleUpdateBeforeRedirect', array( $this->mArticle, &$sectionanchor, &$extraQuery ) );
+ wfRunHooks(
+ 'ArticleUpdateBeforeRedirect',
+ array( $this->mArticle, &$sectionanchor, &$extraQuery )
+ );
if ( $resultDetails['redirect'] ) {
if ( $extraQuery == '' ) {
@@ -1266,10 +1364,6 @@ class EditPage {
$wgOut->redirect( $this->mTitle->getFullURL( $extraQuery ) . $sectionanchor );
return false;
- case self::AS_BLANK_ARTICLE:
- $wgOut->redirect( $this->getContextTitle()->getFullURL() );
- return false;
-
case self::AS_SPAM_ERROR:
$this->spamPageWithContent( $resultDetails['spam'] );
return false;
@@ -1312,9 +1406,9 @@ class EditPage {
/**
* Run hooks that can filter edits just before they get saved.
*
- * @param Content $content the Content to filter.
- * @param Status $status for reporting the outcome to the caller
- * @param User $user the user performing the edit
+ * @param Content $content The Content to filter.
+ * @param Status $status For reporting the outcome to the caller
+ * @param User $user The user performing the edit
*
* @return bool
*/
@@ -1358,20 +1452,58 @@ class EditPage {
}
/**
+ * Return the summary to be used for a new section.
+ *
+ * @param string $sectionanchor Set to the section anchor text
+ * @return string
+ */
+ private function newSectionSummary( &$sectionanchor = null ) {
+ global $wgParser;
+
+ if ( $this->sectiontitle !== '' ) {
+ $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 );
+ return 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 );
+ return wfMessage( 'newsectionsummary' )
+ ->rawParams( $cleanSummary )->inContentLanguage()->text();
+ }
+ return $this->summary;
+ }
+
+ /**
* Attempt submission (no UI)
*
- * @param array $result array to add statuses to, currently with the possible keys:
- * spam - string - Spam string from content if any spam is detected by matchSpamRegex
- * sectionanchor - string - Section anchor for a section save
- * nullEdit - boolean - Set if doEditContent is OK. True if null edit, false otherwise.
- * redirect - boolean - Set if doEditContent is OK. True if resulting revision is a redirect
+ * @param array $result Array to add statuses to, currently with the
+ * possible keys:
+ * - spam (string): Spam string from content if any spam is detected by
+ * matchSpamRegex.
+ * - sectionanchor (string): Section anchor for a section save.
+ * - nullEdit (boolean): Set if doEditContent is OK. True if null edit,
+ * false otherwise.
+ * - redirect (bool): Set if doEditContent is OK. True if resulting
+ * revision is a redirect.
* @param bool $bot True if edit is being made under the bot right.
*
- * @return Status object, possibly with a message, but always with one of the AS_* constants in $status->value,
+ * @return Status Status object, possibly with a message, but always with
+ * one of the AS_* constants in $status->value,
*
- * FIXME: This interface is TERRIBLE, but hard to get rid of due to various error display idiosyncrasies. There are
- * also lots of cases where error metadata is set in the object and retrieved later instead of being returned, e.g.
- * AS_CONTENT_TOO_BIG and AS_BLOCKED_PAGE_FOR_USER. All that stuff needs to be cleaned up some time.
+ * @todo FIXME: This interface is TERRIBLE, but hard to get rid of due to
+ * various error display idiosyncrasies. There are also lots of cases
+ * where error metadata is set in the object and retrieved later instead
+ * of being returned, e.g. 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 $wgUser, $wgRequest, $wgParser, $wgMaxArticleSize;
@@ -1412,7 +1544,12 @@ class EditPage {
# Construct Content object
$textbox_content = $this->toEditContent( $this->textbox1 );
} catch ( MWContentSerializationException $ex ) {
- $status->fatal( 'content-failed-to-parse', $this->contentModel, $this->contentFormat, $ex->getMessage() );
+ $status->fatal(
+ 'content-failed-to-parse',
+ $this->contentModel,
+ $this->contentFormat,
+ $ex->getMessage()
+ );
$status->value = self::AS_PARSE_ERROR;
wfProfileOut( __METHOD__ . '-checks' );
wfProfileOut( __METHOD__ );
@@ -1422,7 +1559,8 @@ class EditPage {
# Check image redirect
if ( $this->mTitle->getNamespace() == NS_FILE &&
$textbox_content->isRedirect() &&
- !$wgUser->isAllowed( 'upload' ) ) {
+ !$wgUser->isAllowed( 'upload' )
+ ) {
$code = $wgUser->isAnon() ? self::AS_IMAGE_REDIRECT_ANON : self::AS_IMAGE_REDIRECT_LOGGED;
$status->setResult( false, $code );
@@ -1461,7 +1599,10 @@ class EditPage {
wfProfileOut( __METHOD__ );
return $status;
}
- if ( !wfRunHooks( 'EditFilter', array( $this, $this->textbox1, $this->section, &$this->hookError, $this->summary ) ) ) {
+ 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' );
$status->value = self::AS_HOOK_ERROR;
@@ -1572,7 +1713,9 @@ class EditPage {
$defaultText = '';
}
- if ( $this->textbox1 === $defaultText ) {
+ if ( !$this->allowBlankArticle && $this->textbox1 === $defaultText ) {
+ $this->blankArticle = true;
+ $status->fatal( 'blankarticle' );
$status->setResult( false, self::AS_BLANK_ARTICLE );
wfProfileOut( __METHOD__ );
return $status;
@@ -1590,30 +1733,11 @@ class EditPage {
if ( $this->sectiontitle !== '' ) {
// Insert the section title above the content.
$content = $content->addSectionHeader( $this->sectiontitle );
-
- // 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 = wfMessage( 'newsectionsummary' )
- ->rawParams( $cleanSectionTitle )->inContentLanguage()->text();
- }
} elseif ( $this->summary !== '' ) {
// Insert the section title above the content.
$content = $content->addSectionHeader( $this->summary );
-
- // 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 = wfMessage( 'newsectionsummary' )
- ->rawParams( $cleanSummary )->inContentLanguage()->text();
}
+ $this->summary = $this->newSectionSummary( $result['sectionanchor'] );
}
$status->value = self::AS_SUCCESS_NEW_ARTICLE;
@@ -1631,18 +1755,24 @@ class EditPage {
$this->isConflict = true;
if ( $this->section == 'new' ) {
if ( $this->mArticle->getUserText() == $wgUser->getName() &&
- $this->mArticle->getComment() == $this->summary ) {
+ $this->mArticle->getComment() == $this->newSectionSummary()
+ ) {
// Probably a duplicate submission of a new comment.
// This can happen when squid resends a request after
// a timeout but the first one actually went through.
- wfDebug( __METHOD__ . ": duplicate new section submission; trigger edit conflict!\n" );
+ wfDebug( __METHOD__
+ . ": duplicate new section submission; trigger edit conflict!\n" );
} else {
// New comment; suppress conflict.
$this->isConflict = false;
wfDebug( __METHOD__ . ": conflict suppressed; new section\n" );
}
- } elseif ( $this->section == '' && Revision::userWasLastToEdit( DB_MASTER, $this->mTitle->getArticleID(),
- $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;
@@ -1659,13 +1789,23 @@ class EditPage {
$content = null;
if ( $this->isConflict ) {
- wfDebug( __METHOD__ . ": conflict! getting section '{$this->section}' for time '{$this->edittime}'"
- . " (article time '{$timestamp}')\n" );
-
- $content = $this->mArticle->replaceSectionContent( $this->section, $textbox_content, $sectionTitle, $this->edittime );
+ wfDebug( __METHOD__
+ . ": conflict! getting section '{$this->section}' for time '{$this->edittime}'"
+ . " (article time '{$timestamp}')\n" );
+
+ $content = $this->mArticle->replaceSectionContent(
+ $this->section,
+ $textbox_content,
+ $sectionTitle,
+ $this->edittime
+ );
} else {
wfDebug( __METHOD__ . ": getting section '{$this->section}'\n" );
- $content = $this->mArticle->replaceSectionContent( $this->section, $textbox_content, $sectionTitle );
+ $content = $this->mArticle->replaceSectionContent(
+ $this->section,
+ $textbox_content,
+ $sectionTitle
+ );
}
if ( is_null( $content ) ) {
@@ -1715,7 +1855,7 @@ class EditPage {
return $status;
}
} elseif ( !$this->allowBlankSummary
- && !$content->equals( $this->getOriginalContent() )
+ && !$content->equals( $this->getOriginalContent( $wgUser ) )
&& !$content->isRedirect()
&& md5( $this->summary ) == $this->autoSumm
) {
@@ -1730,31 +1870,15 @@ class EditPage {
wfProfileIn( __METHOD__ . '-sectionanchor' );
$sectionanchor = '';
if ( $this->section == 'new' ) {
- if ( $this->sectiontitle !== '' ) {
- $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 = 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 = wfMessage( 'newsectionsummary' )
- ->rawParams( $cleanSummary )->inContentLanguage()->text();
- }
+ $this->summary = $this->newSectionSummary( $sectionanchor );
} elseif ( $this->section != '' ) {
- # Try to get a section anchor from the section source, redirect to edited section if header found
- # XXX: might be better to integrate this into Article::replaceSection
- # for duplicate heading checking and maybe parsing
+ # Try to get a section anchor from the section source, redirect
+ # to edited section if header found.
+ # XXX: Might be better to integrate this into Article::replaceSection
+ # for duplicate heading checking and maybe parsing.
$hasmatch = preg_match( "/^ *([=]{1,6})(.*?)(\\1) *\\n/i", $this->textbox1, $matches );
- # we can't deal with anchors, includes, html etc in the header for now,
- # headline would need to be parsed to improve this
+ # We can't deal with anchors, includes, html etc in the header for now,
+ # headline would need to be parsed to improve this.
if ( $hasmatch && strlen( $matches[2] ) > 0 ) {
$sectionanchor = $wgParser->guessLegacySectionNameFromWikiText( $matches[2] );
}
@@ -1773,7 +1897,7 @@ class EditPage {
}
// Check for length errors again now that the section is merged in
- $this->kblength = (int)( strlen( $this->toEditText( $content ) ) / 1024 );
+ $this->kblength = (int)( strlen( $this->toEditText( $content ) ) / 1024 );
if ( $this->kblength > $wgMaxArticleSize ) {
$this->tooBig = true;
$status->setResult( false, self::AS_MAX_ARTICLE_SIZE_EXCEEDED );
@@ -1786,17 +1910,23 @@ class EditPage {
( ( $this->minoredit && !$this->isNew ) ? EDIT_MINOR : 0 ) |
( $bot ? EDIT_FORCE_BOT : 0 );
- $doEditStatus = $this->mArticle->doEditContent( $content, $this->summary, $flags,
- false, null, $this->contentFormat );
+ $doEditStatus = $this->mArticle->doEditContent(
+ $content,
+ $this->summary,
+ $flags,
+ false,
+ null,
+ $content->getDefaultFormat()
+ );
if ( !$doEditStatus->isOK() ) {
// 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' ) ) )
- {
+ 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;
@@ -1831,44 +1961,20 @@ class EditPage {
// Do this in its own transaction to reduce contention...
$dbw = wfGetDB( DB_MASTER );
- $dbw->onTransactionIdle( function() use ( $dbw, $title, $watch, $wgUser, $fname ) {
- $dbw->begin( $fname );
+ $dbw->onTransactionIdle( function () use ( $dbw, $title, $watch, $wgUser, $fname ) {
WatchAction::doWatchOrUnwatch( $watch, $title, $wgUser );
- $dbw->commit( $fname );
} );
}
}
/**
- * Attempts to merge text content with base and current revisions
- *
- * @param $editText string
- *
- * @return bool
- * @deprecated since 1.21, use mergeChangesIntoContent() instead
- */
- function mergeChangesInto( &$editText ) {
- ContentHandler::deprecated( __METHOD__, "1.21" );
-
- $editContent = $this->toEditContent( $editText );
-
- $ok = $this->mergeChangesIntoContent( $editContent );
-
- if ( $ok ) {
- $editText = $this->toEditText( $editContent );
- return true;
- }
- return false;
- }
-
- /**
* Attempts to do 3-way merge of edit content with a base revision
* and current content, in case of edit conflict, in whichever way appropriate
* for the content type.
*
* @since 1.21
*
- * @param $editContent
+ * @param Content $editContent
*
* @return bool
*/
@@ -1915,20 +2021,18 @@ class EditPage {
function getBaseRevision() {
if ( !$this->mBaseRevision ) {
$db = wfGetDB( DB_MASTER );
- $baseRevision = Revision::loadFromTimestamp(
+ $this->mBaseRevision = Revision::loadFromTimestamp(
$db, $this->mTitle, $this->edittime );
- return $this->mBaseRevision = $baseRevision;
- } else {
- return $this->mBaseRevision;
}
+ return $this->mBaseRevision;
}
/**
* Check given input text against $wgSpamRegex, and return the text of the first match.
*
- * @param $text string
+ * @param string $text
*
- * @return string|bool matching string or false
+ * @return string|bool Matching string or false
*/
public static function matchSpamRegex( $text ) {
global $wgSpamRegex;
@@ -1940,9 +2044,9 @@ class EditPage {
/**
* Check given input text against $wgSummarySpamRegex, and return the text of the first match.
*
- * @param $text string
+ * @param string $text
*
- * @return string|bool matching string or false
+ * @return string|bool Matching string or false
*/
public static function matchSummarySpamRegex( $text ) {
global $wgSummarySpamRegex;
@@ -1951,8 +2055,8 @@ class EditPage {
}
/**
- * @param $text string
- * @param $regexes array
+ * @param string $text
+ * @param array $regexes
* @return bool|string
*/
protected static function matchSpamRegexInternal( $text, $regexes ) {
@@ -1979,9 +2083,6 @@ class EditPage {
$wgOut->addModules( 'mediawiki.action.edit.editWarning' );
}
- // Bug #19334: textarea jumps when editing articles in IE8
- $wgOut->addStyle( 'common/IE80Fixes.css', 'screen', 'IE 8' );
-
$wgOut->setRobotPolicy( 'noindex,nofollow' );
# Enabled article-related sidebar, toplinks, etc.
@@ -1993,9 +2094,14 @@ class EditPage {
} elseif ( $contextTitle->exists() && $this->section != '' ) {
$msg = $this->section == 'new' ? 'editingcomment' : 'editingsection';
} else {
- $msg = $contextTitle->exists() || ( $contextTitle->getNamespace() == NS_MEDIAWIKI && $contextTitle->getDefaultMessageText() !== false ) ?
- 'editing' : 'creating';
+ $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 ) {
@@ -2045,14 +2151,15 @@ class EditPage {
$username = $parts[0];
$user = User::newFromName( $username, false /* allow IP users*/ );
$ip = User::isIP( $username );
+ $block = Block::newFromTarget( $user, $user );
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
+ } elseif ( !is_null( $block ) && $block->getType() != Block::TYPE_AUTO ) { # Show log extract if the user is currently blocked
LogEventsList::showLogExtract(
$wgOut,
'block',
- $user->getUserPage(),
+ MWNamespace::getCanonicalName( NS_USER ) . ':' . $block->getTarget(),
'',
array(
'lim' => 1,
@@ -2115,7 +2222,7 @@ class EditPage {
if ( $title instanceof Title && $title->exists() && $title->userCan( 'read' ) ) {
global $wgOut;
// Added using template syntax, to take <noinclude>'s into account.
- $wgOut->addWikiTextTitleTidy( '{{:' . $title->getFullText() . '}}', $this->mTitle );
+ $wgOut->addWikiTextTitleTidy( '<div class="mw-editintro">{{:' . $title->getFullText() . '}}</div>', $this->mTitle );
return true;
}
}
@@ -2129,14 +2236,16 @@ class EditPage {
*
* If $content is null or false or a string, $content is returned unchanged.
*
- * If the given Content object is not of a type that can be edited using the text base EditPage,
- * an exception will be raised. Set $this->allowNonTextContent to true to allow editing of non-textual
+ * If the given Content object is not of a type that can be edited using
+ * the text base EditPage, an exception will be raised. Set
+ * $this->allowNonTextContent to true to allow editing of non-textual
* content.
*
* @param Content|null|bool|string $content
- * @return String the editable text form of the content.
+ * @return string The editable text form of the content.
*
- * @throws MWException if $content is not an instance of TextContent and $this->allowNonTextContent is not true.
+ * @throws MWException If $content is not an instance of TextContent and
+ * $this->allowNonTextContent is not true.
*/
protected function toEditText( $content ) {
if ( $content === null || $content === false ) {
@@ -2147,9 +2256,9 @@ class EditPage {
return $content;
}
- if ( !$this->allowNonTextContent && !( $content instanceof TextContent ) ) {
- throw new MWException( "This content model can not be edited as text: "
- . ContentHandler::getLocalizedName( $content->getModel() ) );
+ if ( !$this->isSupportedContentModel( $content->getModel() ) ) {
+ throw new MWException( 'This content model is not supported: '
+ . ContentHandler::getLocalizedName( $content->getModel() ) );
}
return $content->serialize( $this->contentFormat );
@@ -2158,16 +2267,18 @@ class EditPage {
/**
* Turns the given text into a Content object by unserializing it.
*
- * If the resulting Content object is not of a type that can be edited using the text base EditPage,
- * an exception will be raised. Set $this->allowNonTextContent to true to allow editing of non-textual
+ * If the resulting Content object is not of a type that can be edited using
+ * the text base EditPage, an exception will be raised. Set
+ * $this->allowNonTextContent to true to allow editing of non-textual
* content.
*
* @param string|null|bool $text Text to unserialize
- * @return Content The content object created from $text. If $text was false or null, false resp. null will be
- * returned instead.
+ * @return Content The content object created from $text. If $text was false
+ * or null, false resp. null will be returned instead.
*
- * @throws MWException if unserializing the text results in a Content object that is not an instance of TextContent
- * and $this->allowNonTextContent is not true.
+ * @throws MWException If unserializing the text results in a Content
+ * object that is not an instance of TextContent and
+ * $this->allowNonTextContent is not true.
*/
protected function toEditContent( $text ) {
if ( $text === false || $text === null ) {
@@ -2177,8 +2288,8 @@ class EditPage {
$content = ContentHandler::makeContent( $text, $this->getTitle(),
$this->contentModel, $this->contentFormat );
- if ( !$this->allowNonTextContent && !( $content instanceof TextContent ) ) {
- throw new MWException( "This content model can not be edited as text: "
+ if ( !$this->isSupportedContentModel( $content->getModel() ) ) {
+ throw new MWException( 'This content model is not supported: '
. ContentHandler::getLocalizedName( $content->getModel() ) );
}
@@ -2187,7 +2298,7 @@ class EditPage {
/**
* Send the edit form and related headers to $wgOut
- * @param $formCallback Callback|null that takes an OutputPage parameter; will be called
+ * @param callable|null $formCallback That takes an OutputPage parameter; will be called
* during form output near the top, for captchas and the like.
*/
function showEditForm( $formCallback = null ) {
@@ -2235,9 +2346,16 @@ class EditPage {
// @todo add EditForm plugin interface and use it here!
// search for textarea1 and textares2, and allow EditForm to override all uses.
- $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' ) ) );
+ $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'
+ )
+ ) );
if ( is_callable( $formCallback ) ) {
call_user_func_array( $formCallback, array( &$wgOut ) );
@@ -2246,8 +2364,20 @@ class EditPage {
// Add an empty field to trip up spambots
$wgOut->addHTML(
Xml::openElement( 'div', array( 'id' => 'antispam-container', 'style' => 'display: none;' ) )
- . Html::rawElement( 'label', array( 'for' => 'wpAntiSpam' ), wfMessage( 'simpleantispam-label' )->parse() )
- . Xml::element( 'input', array( 'type' => 'text', 'name' => 'wpAntispam', 'id' => 'wpAntispam', 'value' => '' ) )
+ . Html::rawElement(
+ 'label',
+ array( 'for' => 'wpAntiSpam' ),
+ wfMessage( 'simpleantispam-label' )->parse()
+ )
+ . Xml::element(
+ 'input',
+ array(
+ 'type' => 'text',
+ 'name' => 'wpAntispam',
+ 'id' => 'wpAntispam',
+ 'value' => ''
+ )
+ )
. Xml::closeElement( 'div' )
);
@@ -2321,6 +2451,10 @@ class EditPage {
$wgOut->addHTML( EditPage::getEditToolbar() );
}
+ if ( $this->blankArticle ) {
+ $wgOut->addHTML( Html::hidden( 'wpIgnoreBlankArticle', true ) );
+ }
+
if ( $this->isConflict ) {
// In an edit conflict bypass the overridable content form method
// and fallback to the raw wpTextbox1 since editconflicts can't be
@@ -2364,11 +2498,19 @@ class EditPage {
$this->showConflict();
} catch ( MWContentSerializationException $ex ) {
// this can't really happen, but be nice if it does.
- $msg = wfMessage( 'content-failed-to-parse', $this->contentModel, $this->contentFormat, $ex->getMessage() );
+ $msg = wfMessage(
+ 'content-failed-to-parse',
+ $this->contentModel,
+ $this->contentFormat,
+ $ex->getMessage()
+ );
$wgOut->addWikiText( '<div class="error">' . $msg->text() . '</div>' );
}
}
+ // Marker for detecting truncated form data. This must be the last
+ // parameter sent in order to be of use, so do not move me.
+ $wgOut->addHTML( Html::hidden( 'wpUltimateParam', true ) );
$wgOut->addHTML( $this->editFormTextBottom . "\n</form>\n" );
if ( !$wgUser->getOption( 'previewontop' ) ) {
@@ -2382,7 +2524,7 @@ class EditPage {
* Extract the section title from current section text, if any.
*
* @param string $text
- * @return Mixed|string or false
+ * @return string|bool String or false
*/
public static function extractSectionTitle( $text ) {
preg_match( "/^(=+)(.+)\\1\\s*(\n|$)/i", $text, $matches );
@@ -2394,8 +2536,12 @@ class EditPage {
}
}
+ /**
+ * @return bool
+ */
protected function showHeader() {
global $wgOut, $wgUser, $wgMaxArticleSize, $wgLang;
+ global $wgAllowUserCss, $wgAllowUserJs;
if ( $this->mTitle->isTalkPage() ) {
$wgOut->addWikiMsg( 'talkpagetext' );
@@ -2437,6 +2583,10 @@ class EditPage {
$wgOut->wrapWikiMsg( "<div id='mw-missingcommentheader'>\n$1\n</div>", 'missingcommentheader' );
}
+ if ( $this->blankArticle ) {
+ $wgOut->wrapWikiMsg( "<div id='mw-blankarticle'>\n$1\n</div>", 'blankarticle' );
+ }
+
if ( $this->hookError !== '' ) {
$wgOut->addWikiText( $this->hookError );
}
@@ -2451,9 +2601,15 @@ class EditPage {
// Let sysop know that this will make private content public if saved
if ( !$revision->userCan( Revision::DELETED_TEXT, $wgUser ) ) {
- $wgOut->wrapWikiMsg( "<div class='mw-warning plainlinks'>\n$1\n</div>\n", 'rev-deleted-text-permission' );
+ $wgOut->wrapWikiMsg(
+ "<div class='mw-warning plainlinks'>\n$1\n</div>\n",
+ 'rev-deleted-text-permission'
+ );
} elseif ( $revision->isDeleted( Revision::DELETED_TEXT ) ) {
- $wgOut->wrapWikiMsg( "<div class='mw-warning plainlinks'>\n$1\n</div>\n", 'rev-deleted-text-view' );
+ $wgOut->wrapWikiMsg(
+ "<div class='mw-warning plainlinks'>\n$1\n</div>\n",
+ 'rev-deleted-text-view'
+ );
}
if ( !$revision->isCurrent() ) {
@@ -2470,32 +2626,55 @@ class EditPage {
}
if ( wfReadOnly() ) {
- $wgOut->wrapWikiMsg( "<div id=\"mw-read-only-warning\">\n$1\n</div>", array( 'readonlywarning', wfReadOnlyReason() ) );
+ $wgOut->wrapWikiMsg(
+ "<div id=\"mw-read-only-warning\">\n$1\n</div>",
+ array( 'readonlywarning', wfReadOnlyReason() )
+ );
} elseif ( $wgUser->isAnon() ) {
if ( $this->formtype != 'preview' ) {
- $wgOut->wrapWikiMsg( "<div id=\"mw-anon-edit-warning\">\n$1</div>", 'anoneditwarning' );
+ $wgOut->wrapWikiMsg(
+ "<div id='mw-anon-edit-warning'>\n$1\n</div>",
+ array( 'anoneditwarning',
+ // Log-in link
+ '{{fullurl:Special:UserLogin|returnto={{FULLPAGENAMEE}}}}',
+ // Sign-up link
+ '{{fullurl:Special:UserLogin/signup|returnto={{FULLPAGENAMEE}}}}' )
+ );
} else {
- $wgOut->wrapWikiMsg( "<div id=\"mw-anon-preview-warning\">\n$1</div>", 'anonpreviewwarning' );
+ $wgOut->wrapWikiMsg( "<div id=\"mw-anon-preview-warning\">\n$1</div>",
+ 'anonpreviewwarning'
+ );
}
} else {
if ( $this->isCssJsSubpage ) {
# Check the skin exists
if ( $this->isWrongCaseCssJsPage ) {
- $wgOut->wrapWikiMsg( "<div class='error' id='mw-userinvalidcssjstitle'>\n$1\n</div>", array( 'userinvalidcssjstitle', $this->mTitle->getSkinFromCssJsSubpage() ) );
+ $wgOut->wrapWikiMsg(
+ "<div class='error' id='mw-userinvalidcssjstitle'>\n$1\n</div>",
+ array( 'userinvalidcssjstitle', $this->mTitle->getSkinFromCssJsSubpage() )
+ );
}
if ( $this->formtype !== 'preview' ) {
- if ( $this->isCssSubpage ) {
- $wgOut->wrapWikiMsg( "<div id='mw-usercssyoucanpreview'>\n$1\n</div>", array( 'usercssyoucanpreview' ) );
+ if ( $this->isCssSubpage && $wgAllowUserCss ) {
+ $wgOut->wrapWikiMsg(
+ "<div id='mw-usercssyoucanpreview'>\n$1\n</div>",
+ array( 'usercssyoucanpreview' )
+ );
}
- if ( $this->isJsSubpage ) {
- $wgOut->wrapWikiMsg( "<div id='mw-userjsyoucanpreview'>\n$1\n</div>", array( 'userjsyoucanpreview' ) );
+ if ( $this->isJsSubpage && $wgAllowUserJs ) {
+ $wgOut->wrapWikiMsg(
+ "<div id='mw-userjsyoucanpreview'>\n$1\n</div>",
+ array( 'userjsyoucanpreview' )
+ );
}
}
}
}
- if ( $this->mTitle->getNamespace() != NS_MEDIAWIKI && $this->mTitle->isProtected( 'edit' ) ) {
+ if ( $this->mTitle->isProtected( 'edit' ) &&
+ MWNamespace::getRestrictionLevels( $this->mTitle->getNamespace() ) !== array( '' )
+ ) {
# Is the title semi-protected?
if ( $this->mTitle->isSemiProtected() ) {
$noticeMsg = 'semiprotectedpagewarning';
@@ -2534,16 +2713,27 @@ class EditPage {
if ( $this->tooBig || $this->kblength > $wgMaxArticleSize ) {
$wgOut->wrapWikiMsg( "<div class='error' id='mw-edit-longpageerror'>\n$1\n</div>",
- array( 'longpageerror', $wgLang->formatNum( $this->kblength ), $wgLang->formatNum( $wgMaxArticleSize ) ) );
+ array(
+ 'longpageerror',
+ $wgLang->formatNum( $this->kblength ),
+ $wgLang->formatNum( $wgMaxArticleSize )
+ )
+ );
} else {
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 ) )
+ array(
+ 'longpage-hint',
+ $wgLang->formatSize( strlen( $this->textbox1 ) ),
+ strlen( $this->textbox1 )
+ )
);
}
}
# Add header copyright warning
$this->showHeaderCopyrightWarning();
+
+ return true;
}
/**
@@ -2555,12 +2745,14 @@ class EditPage {
*
* @param string $summary The value of the summary input
* @param string $labelText The html to place inside the label
- * @param array $inputAttrs of attrs to use on the input
- * @param array $spanLabelAttrs of attrs to use on the span inside the label
+ * @param array $inputAttrs Array of attrs to use on the input
+ * @param array $spanLabelAttrs Array of attrs to use on the span inside the label
*
* @return array An array in the format array( $label, $input )
*/
- function getSummaryInput( $summary = "", $labelText = null, $inputAttrs = null, $spanLabelAttrs = null ) {
+ function getSummaryInput( $summary = "", $labelText = null,
+ $inputAttrs = null, $spanLabelAttrs = null
+ ) {
// Note: the maxlength is overridden in JS to 255 and to make it use UTF-8 bytes, not characters.
$inputAttrs = ( is_array( $inputAttrs ) ? $inputAttrs : array() ) + array(
'id' => 'wpSummary',
@@ -2577,7 +2769,11 @@ class EditPage {
$label = null;
if ( $labelText ) {
- $label = Xml::tags( 'label', $inputAttrs['id'] ? array( 'for' => $inputAttrs['id'] ) : null, $labelText );
+ $label = Xml::tags(
+ 'label',
+ $inputAttrs['id'] ? array( 'for' => $inputAttrs['id'] ) : null,
+ $labelText
+ );
$label = Xml::tags( 'span', $spanLabelAttrs, $label );
}
@@ -2587,11 +2783,10 @@ class EditPage {
}
/**
- * @param $isSubjectPreview Boolean: true if this is the section subject/title
- * up top, or false if this is the comment summary
- * down below the textarea
+ * @param bool $isSubjectPreview True if this is the section subject/title
+ * up top, or false if this is the comment summary
+ * down below the textarea
* @param string $summary The text of the summary to display
- * @return String
*/
protected function showSummaryInput( $isSubjectPreview, $summary = "" ) {
global $wgOut, $wgContLang;
@@ -2608,16 +2803,21 @@ class EditPage {
}
$summary = $wgContLang->recodeForEdit( $summary );
$labelText = wfMessage( $isSubjectPreview ? 'subject' : 'summary' )->parse();
- list( $label, $input ) = $this->getSummaryInput( $summary, $labelText, array( 'class' => $summaryClass ), array() );
+ list( $label, $input ) = $this->getSummaryInput(
+ $summary,
+ $labelText,
+ array( 'class' => $summaryClass ),
+ array()
+ );
$wgOut->addHTML( "{$label} {$input}" );
}
/**
- * @param $isSubjectPreview Boolean: true if this is the section subject/title
- * up top, or false if this is the comment summary
- * down below the textarea
- * @param string $summary the text of the summary to display
- * @return String
+ * @param bool $isSubjectPreview True if this is the section subject/title
+ * up top, or false if this is the comment summary
+ * down below the textarea
+ * @param string $summary The text of the summary to display
+ * @return string
*/
protected function getSummaryPreview( $isSubjectPreview, $summary = "" ) {
// avoid spaces in preview, gets always trimmed on save
@@ -2635,7 +2835,8 @@ class EditPage {
$message = $isSubjectPreview ? 'subject-preview' : 'summary-preview';
- $summary = wfMessage( $message )->parse() . 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 );
}
@@ -2689,15 +2890,17 @@ HTML
* The $textoverride method can be used by subclasses overriding showContentForm
* to pass back to this method.
*
- * @param array $customAttribs of html attributes to use in the textarea
- * @param string $textoverride optional text to override $this->textarea1 with
+ * @param array $customAttribs Array of html attributes to use in the textarea
+ * @param string $textoverride Optional text to override $this->textarea1 with
*/
protected function showTextbox1( $customAttribs = null, $textoverride = null ) {
if ( $this->wasDeletedSinceLastEdit() && $this->formtype == 'save' ) {
$attribs = array( 'style' => 'display:none;' );
} else {
$classes = array(); // Textarea CSS
- if ( $this->mTitle->getNamespace() != NS_MEDIAWIKI && $this->mTitle->isProtected( 'edit' ) ) {
+ if ( $this->mTitle->isProtected( 'edit' ) &&
+ MWNamespace::getRestrictionLevels( $this->mTitle->getNamespace() ) !== array( '' )
+ ) {
# Is the title semi-protected?
if ( $this->mTitle->isSemiProtected() ) {
$classes[] = 'mw-textarea-sprotected';
@@ -2725,7 +2928,11 @@ HTML
}
}
- $this->showTextbox( $textoverride !== null ? $textoverride : $this->textbox1, 'wpTextbox1', $attribs );
+ $this->showTextbox(
+ $textoverride !== null ? $textoverride : $this->textbox1,
+ 'wpTextbox1',
+ $attribs
+ );
}
protected function showTextbox2() {
@@ -2749,7 +2956,9 @@ HTML
'id' => $name,
'cols' => $wgUser->getIntOption( 'cols' ),
'rows' => $wgUser->getIntOption( 'rows' ),
- 'style' => '' // avoid php notices when appending preferences (appending allows customAttribs['style'] to still work
+ // Avoid PHP notices when appending preferences
+ // (appending allows customAttribs['style'] to still work).
+ 'style' => ''
);
$pageLang = $this->mTitle->getPageLanguage();
@@ -2784,7 +2993,12 @@ HTML
try {
$this->showDiff();
} catch ( MWContentSerializationException $ex ) {
- $msg = wfMessage( 'content-failed-to-parse', $this->contentModel, $this->contentFormat, $ex->getMessage() );
+ $msg = wfMessage(
+ 'content-failed-to-parse',
+ $this->contentModel,
+ $this->contentFormat,
+ $ex->getMessage()
+ );
$wgOut->addWikiText( '<div class="error">' . $msg->text() . '</div>' );
}
}
@@ -2794,7 +3008,7 @@ HTML
* Append preview output to $wgOut.
* Includes category rendering if this is a category page.
*
- * @param string $text the HTML to be output for the preview.
+ * @param string $text The HTML to be output for the preview.
*/
protected function showPreview( $text ) {
global $wgOut;
@@ -2914,6 +3128,7 @@ HTML
* Get the copyright warning
*
* Renamed to getCopyrightWarning(), old name kept around for backwards compatibility
+ * @return string
*/
protected function getCopywarn() {
return self::getCopyrightWarning( $this->mTitle );
@@ -2923,8 +3138,7 @@ HTML
* Get the copyright warning, by default returns wikitext
*
* @param Title $title
- * @param string $format output format, valid values are any function of
- * a Message object
+ * @param string $format Output format, valid values are any function of a Message object
* @return string
*/
public static function getCopyrightWarning( $title, $format = 'plain' ) {
@@ -2972,7 +3186,7 @@ HTML
foreach ( $output->getLimitReportData() as $key => $value ) {
if ( wfRunHooks( 'ParserLimitReportFormat',
- array( $key, $value, &$limitReport, true, true )
+ array( $key, &$value, &$limitReport, true, true )
) ) {
$keyMsg = wfMessage( $key );
$valueMsg = wfMessage( array( "$key-value-html", "$key-value" ) );
@@ -2998,7 +3212,7 @@ HTML
}
protected function showStandardInputs( &$tabindex = 2 ) {
- global $wgOut;
+ global $wgOut, $wgUseMediaWikiUIEverywhere;
$wgOut->addHTML( "<div class='editOptions'>\n" );
if ( $this->section != 'new' ) {
@@ -3023,14 +3237,26 @@ HTML
array( 'class' => 'mw-editButtons-pipe-separator' ),
wfMessage( 'pipe-separator' )->text() );
}
- $edithelpurl = Skin::makeInternalOrExternalUrl( wfMessage( 'edithelppage' )->inContentLanguage()->text() );
- $edithelp = '<a target="helpwindow" href="' . $edithelpurl . '">' .
- wfMessage( 'edithelp