Merge "misc style issues"
authorjenkins-bot <jenkins-bot@gerrit.wikimedia.org>
Mon, 11 Feb 2013 21:14:30 +0000 (21:14 +0000)
committerGerrit Code Review <gerrit@wikimedia.org>
Mon, 11 Feb 2013 21:14:30 +0000 (21:14 +0000)
533 files changed:
.gitignore
INSTALL
RELEASE-NOTES-1.21
api.php
bin/ulimit5.sh [deleted file]
composer.json [new file with mode: 0644]
docs/hooks.txt
img_auth.php
includes/ArrayUtils.php
includes/Article.php
includes/AutoLoader.php
includes/Block.php
includes/Category.php
includes/Categoryfinder.php
includes/Cdb.php
includes/Cdb_PHP.php
includes/ChangeTags.php
includes/ChangesFeed.php
includes/ChangesList.php
includes/Collation.php
includes/ConfEditor.php
includes/Cookie.php
includes/CryptRand.php
includes/DefaultSettings.php
includes/Defines.php
includes/DeprecatedGlobal.php
includes/EditPage.php
includes/Exception.php
includes/Export.php
includes/ExternalUser.php
includes/FakeTitle.php
includes/Feed.php
includes/FeedUtils.php
includes/FileDeleteForm.php
includes/ForkController.php
includes/GlobalFunctions.php
includes/HTMLForm.php
includes/HistoryBlob.php
includes/Hooks.php
includes/Html.php
includes/HttpFunctions.php
includes/IP.php
includes/ImageGallery.php
includes/ImagePage.php
includes/Import.php
includes/LinkFilter.php
includes/Linker.php
includes/LinksUpdate.php
includes/MagicWord.php
includes/Message.php
includes/Metadata.php
includes/MimeMagic.php
includes/Namespace.php
includes/OutputPage.php
includes/Pager.php
includes/PathRouter.php
includes/Preferences.php
includes/PrefixSearch.php
includes/ProtectionForm.php
includes/ProxyTools.php
includes/RecentChange.php
includes/Revision.php
includes/Sanitizer.php
includes/Setup.php
includes/SiteConfiguration.php
includes/Skin.php
includes/SkinLegacy.php
includes/SkinTemplate.php
includes/SpecialPage.php
includes/SpecialPageFactory.php
includes/SqlDataUpdate.php
includes/SquidPurgeClient.php
includes/Status.php
includes/StringUtils.php
includes/StubObject.php
includes/Title.php
includes/UIDGenerator.php [new file with mode: 0644]
includes/User.php
includes/UserMailer.php
includes/WatchedItem.php
includes/WebRequest.php
includes/WebResponse.php
includes/WebStart.php
includes/WikiFilePage.php
includes/WikiPage.php
includes/Xml.php
includes/ZipDirectoryReader.php
includes/actions/HistoryAction.php
includes/actions/InfoAction.php
includes/actions/RawAction.php
includes/api/ApiBase.php
includes/api/ApiBlock.php
includes/api/ApiComparePages.php
includes/api/ApiDelete.php
includes/api/ApiDisabled.php
includes/api/ApiEditPage.php
includes/api/ApiEmailUser.php
includes/api/ApiExpandTemplates.php
includes/api/ApiFeedContributions.php
includes/api/ApiFeedWatchlist.php
includes/api/ApiFileRevert.php
includes/api/ApiFormatDbg.php
includes/api/ApiFormatDump.php
includes/api/ApiFormatNone.php
includes/api/ApiFormatPhp.php
includes/api/ApiFormatTxt.php
includes/api/ApiFormatWddx.php
includes/api/ApiFormatXml.php
includes/api/ApiHelp.php
includes/api/ApiImport.php
includes/api/ApiLogout.php
includes/api/ApiMain.php
includes/api/ApiModuleManager.php [new file with mode: 0644]
includes/api/ApiMove.php
includes/api/ApiOpenSearch.php
includes/api/ApiOptions.php
includes/api/ApiPageSet.php
includes/api/ApiParamInfo.php
includes/api/ApiParse.php
includes/api/ApiPatrol.php
includes/api/ApiProtect.php
includes/api/ApiPurge.php
includes/api/ApiQuery.php
includes/api/ApiQueryAllImages.php
includes/api/ApiQueryAllMessages.php
includes/api/ApiQueryBase.php
includes/api/ApiQueryBlocks.php
includes/api/ApiQueryCategoryMembers.php
includes/api/ApiQueryDeletedrevs.php
includes/api/ApiQueryDisabled.php
includes/api/ApiQueryImageInfo.php
includes/api/ApiQueryInfo.php
includes/api/ApiQueryLinks.php
includes/api/ApiQueryPageProps.php
includes/api/ApiQueryQueryPage.php
includes/api/ApiQueryRecentChanges.php
includes/api/ApiQueryRevisions.php
includes/api/ApiQuerySiteinfo.php
includes/api/ApiQueryStashImageInfo.php
includes/api/ApiQueryUserContributions.php
includes/api/ApiQueryUsers.php
includes/api/ApiRollback.php
includes/api/ApiRsd.php
includes/api/ApiSetNotificationTimestamp.php
includes/api/ApiTokens.php
includes/api/ApiUnblock.php
includes/api/ApiUndelete.php
includes/api/ApiUpload.php
includes/api/ApiUserrights.php
includes/api/ApiWatch.php
includes/cache/CacheDependency.php
includes/cache/FileCacheBase.php
includes/cache/HTMLFileCache.php
includes/cache/MessageCache.php
includes/cache/SquidUpdate.php
includes/clientpool/RedisConnectionPool.php [new file with mode: 0644]
includes/content/AbstractContent.php
includes/content/Content.php
includes/content/ContentHandler.php
includes/content/WikitextContent.php
includes/context/RequestContext.php
includes/db/CloneDatabase.php
includes/db/Database.php
includes/db/DatabaseError.php
includes/db/DatabaseIbm_db2.php
includes/db/DatabaseMssql.php
includes/db/DatabaseMysql.php
includes/db/DatabaseOracle.php
includes/db/DatabasePostgres.php
includes/db/DatabaseSqlite.php
includes/db/DatabaseUtility.php
includes/db/IORMRow.php
includes/db/LBFactory.php
includes/db/LBFactory_Multi.php
includes/db/LoadBalancer.php
includes/db/LoadMonitor.php
includes/db/ORMIterator.php
includes/db/ORMTable.php
includes/diff/DairikiDiff.php
includes/diff/DifferenceEngine.php
includes/externalstore/ExternalStore.php
includes/externalstore/ExternalStoreDB.php
includes/externalstore/ExternalStoreMedium.php
includes/externalstore/ExternalStoreMwstore.php [new file with mode: 0644]
includes/filebackend/FSFile.php
includes/filebackend/FSFileBackend.php
includes/filebackend/FileBackend.php
includes/filebackend/FileBackendGroup.php
includes/filebackend/FileBackendMultiWrite.php
includes/filebackend/FileOp.php
includes/filebackend/SwiftFileBackend.php
includes/filebackend/lockmanager/DBLockManager.php
includes/filebackend/lockmanager/FSLockManager.php
includes/filebackend/lockmanager/LSLockManager.php
includes/filebackend/lockmanager/LockManager.php
includes/filebackend/lockmanager/LockManagerGroup.php
includes/filebackend/lockmanager/MemcLockManager.php
includes/filebackend/lockmanager/QuorumLockManager.php [new file with mode: 0644]
includes/filerepo/FSRepo.php
includes/filerepo/FileRepo.php
includes/filerepo/ForeignAPIRepo.php
includes/filerepo/LocalRepo.php
includes/filerepo/RepoGroup.php
includes/filerepo/file/ArchivedFile.php
includes/filerepo/file/File.php
includes/filerepo/file/ForeignAPIFile.php
includes/filerepo/file/LocalFile.php
includes/filerepo/file/OldLocalFile.php
includes/filerepo/file/UnregisteredLocalFile.php
includes/installer/CliInstaller.php
includes/installer/DatabaseInstaller.php
includes/installer/DatabaseUpdater.php
includes/installer/InstallDocFormatter.php
includes/installer/Installer.i18n.php
includes/installer/Installer.php
includes/installer/MysqlInstaller.php
includes/installer/MysqlUpdater.php
includes/installer/OracleInstaller.php
includes/installer/OracleUpdater.php
includes/installer/PostgresUpdater.php
includes/installer/WebInstaller.php
includes/installer/WebInstallerOutput.php
includes/installer/WebInstallerPage.php
includes/job/Job.php
includes/job/JobQueue.php
includes/job/JobQueueDB.php
includes/job/JobQueueGroup.php
includes/job/JobQueueRedis.php [new file with mode: 0644]
includes/job/jobs/DoubleRedirectJob.php
includes/job/jobs/DuplicateJob.php
includes/libs/IEContentAnalyzer.php
includes/limit.sh [new file with mode: 0644]
includes/logging/LogEventsList.php
includes/logging/LogFormatter.php
includes/logging/LogPage.php
includes/logging/LogPager.php
includes/media/BMP.php
includes/media/DjVu.php
includes/media/DjVuImage.php
includes/media/Exif.php
includes/media/ExifBitmap.php
includes/media/FormatMetadata.php
includes/media/GIF.php
includes/media/GIFMetadataExtractor.php
includes/media/IPTC.php
includes/media/ImageHandler.php
includes/media/Jpeg.php
includes/media/MediaHandler.php
includes/media/MediaTransformOutput.php
includes/media/PNG.php
includes/media/SVG.php
includes/media/SVGMetadataExtractor.php
includes/media/Tiff.php
includes/media/XCF.php
includes/media/XMP.php
includes/media/XMPInfo.php
includes/media/XMPValidate.php
includes/normal/RandomTest.php
includes/normal/Utf8CaseGenerate.php
includes/normal/Utf8Test.php
includes/normal/UtfNormal.php
includes/normal/UtfNormalBench.php
includes/normal/UtfNormalDefines.php
includes/normal/UtfNormalGenerate.php
includes/normal/UtfNormalMemStress.php
includes/normal/UtfNormalTest.php
includes/normal/UtfNormalTest2.php
includes/objectcache/EhcacheBagOStuff.php
includes/objectcache/HashBagOStuff.php
includes/objectcache/MemcachedBagOStuff.php
includes/objectcache/MemcachedClient.php
includes/objectcache/MemcachedPhpBagOStuff.php
includes/objectcache/ObjectCache.php
includes/objectcache/RedisBagOStuff.php
includes/objectcache/SqlBagOStuff.php
includes/parser/CoreLinkFunctions.php
includes/parser/CoreParserFunctions.php
includes/parser/DateFormatter.php
includes/parser/LinkHolderArray.php
includes/parser/Parser.php
includes/parser/ParserCache.php
includes/parser/ParserOptions.php
includes/parser/ParserOutput.php
includes/parser/Parser_LinkHooks.php
includes/parser/Preprocessor_DOM.php
includes/parser/Preprocessor_Hash.php
includes/parser/Preprocessor_HipHop.hphp [deleted file]
includes/parser/StripState.php
includes/parser/Tidy.php
includes/profiler/Profiler.php
includes/profiler/ProfilerSimple.php
includes/profiler/ProfilerSimpleText.php
includes/profiler/ProfilerSimpleTrace.php
includes/profiler/ProfilerSimpleUDP.php
includes/resourceloader/ResourceLoaderFileModule.php
includes/resourceloader/ResourceLoaderWikiModule.php
includes/revisiondelete/RevisionDelete.php
includes/search/SearchEngine.php
includes/search/SearchIBM_DB2.php
includes/search/SearchMssql.php
includes/search/SearchMySQL.php
includes/search/SearchOracle.php
includes/search/SearchPostgres.php
includes/search/SearchSqlite.php
includes/search/SearchUpdate.php
includes/site/MediaWikiSite.php
includes/site/Site.php
includes/site/SiteList.php
includes/site/SiteSQLStore.php
includes/specials/SpecialAllpages.php
includes/specials/SpecialBlankpage.php
includes/specials/SpecialBlock.php
includes/specials/SpecialBlockList.php
includes/specials/SpecialBooksources.php
includes/specials/SpecialBrokenRedirects.php
includes/specials/SpecialCategories.php
includes/specials/SpecialChangeEmail.php
includes/specials/SpecialChangePassword.php
includes/specials/SpecialContributions.php
includes/specials/SpecialDeletedContributions.php
includes/specials/SpecialDisambiguations.php
includes/specials/SpecialDoubleRedirects.php
includes/specials/SpecialEditWatchlist.php
includes/specials/SpecialExport.php
includes/specials/SpecialFileDuplicateSearch.php
includes/specials/SpecialImport.php
includes/specials/SpecialLinkSearch.php
includes/specials/SpecialListfiles.php
includes/specials/SpecialListusers.php
includes/specials/SpecialMostlinkedtemplates.php
includes/specials/SpecialMovepage.php
includes/specials/SpecialNewpages.php
includes/specials/SpecialPopularpages.php
includes/specials/SpecialPrefixindex.php
includes/specials/SpecialProtectedpages.php
includes/specials/SpecialProtectedtitles.php
includes/specials/SpecialRecentchanges.php
includes/specials/SpecialRecentchangeslinked.php
includes/specials/SpecialRevisiondelete.php
includes/specials/SpecialSearch.php
includes/specials/SpecialSpecialpages.php
includes/specials/SpecialStatistics.php
includes/specials/SpecialUncategorizedcategories.php
includes/specials/SpecialUndelete.php
includes/specials/SpecialUpload.php
includes/specials/SpecialUploadStash.php
includes/specials/SpecialUserlogin.php
includes/specials/SpecialUserrights.php
includes/specials/SpecialVersion.php
includes/specials/SpecialWatchlist.php
includes/specials/SpecialWhatlinkshere.php
includes/upload/UploadBase.php
includes/upload/UploadFromChunks.php
includes/upload/UploadStash.php
languages/Language.php
languages/Names.php
languages/classes/LanguageKu.php
languages/classes/LanguageRu.php
languages/classes/LanguageSr.php
languages/messages/MessagesAce.php
languages/messages/MessagesAr.php
languages/messages/MessagesArc.php
languages/messages/MessagesAst.php
languages/messages/MessagesAz.php
languages/messages/MessagesBe.php
languages/messages/MessagesBe_tarask.php
languages/messages/MessagesBg.php
languages/messages/MessagesBho.php
languages/messages/MessagesBn.php
languages/messages/MessagesCkb.php
languages/messages/MessagesCy.php
languages/messages/MessagesDa.php
languages/messages/MessagesDe.php
languages/messages/MessagesDiq.php
languages/messages/MessagesDsb.php
languages/messages/MessagesEl.php
languages/messages/MessagesEn.php
languages/messages/MessagesEo.php
languages/messages/MessagesEs.php
languages/messages/MessagesEu.php
languages/messages/MessagesFi.php
languages/messages/MessagesFr.php
languages/messages/MessagesFrp.php
languages/messages/MessagesFrr.php
languages/messages/MessagesGa.php
languages/messages/MessagesGd.php
languages/messages/MessagesGl.php
languages/messages/MessagesHe.php
languages/messages/MessagesHsb.php
languages/messages/MessagesHu.php
languages/messages/MessagesIa.php
languages/messages/MessagesId.php
languages/messages/MessagesIlo.php
languages/messages/MessagesIs.php
languages/messages/MessagesIt.php
languages/messages/MessagesJa.php
languages/messages/MessagesKa.php
languages/messages/MessagesKiu.php
languages/messages/MessagesKn.php
languages/messages/MessagesKo.php
languages/messages/MessagesKu_latn.php
languages/messages/MessagesLa.php
languages/messages/MessagesLb.php
languages/messages/MessagesLez.php
languages/messages/MessagesLt.php
languages/messages/MessagesMg.php
languages/messages/MessagesMin.php
languages/messages/MessagesMk.php
languages/messages/MessagesMl.php
languages/messages/MessagesMn.php
languages/messages/MessagesMs.php
languages/messages/MessagesMt.php
languages/messages/MessagesNb.php
languages/messages/MessagesNl.php
languages/messages/MessagesNn.php
languages/messages/MessagesOr.php
languages/messages/MessagesPa.php
languages/messages/MessagesPcd.php
languages/messages/MessagesPl.php
languages/messages/MessagesPms.php
languages/messages/MessagesPs.php
languages/messages/MessagesPt.php
languages/messages/MessagesPt_br.php
languages/messages/MessagesQqq.php
languages/messages/MessagesRo.php
languages/messages/MessagesRoa_tara.php
languages/messages/MessagesRu.php
languages/messages/MessagesSa.php
languages/messages/MessagesSah.php
languages/messages/MessagesSe.php
languages/messages/MessagesSl.php
languages/messages/MessagesSo.php
languages/messages/MessagesSv.php
languages/messages/MessagesSw.php
languages/messages/MessagesTh.php
languages/messages/MessagesTly.php
languages/messages/MessagesTr.php
languages/messages/MessagesTyv.php
languages/messages/MessagesUg_arab.php
languages/messages/MessagesUk.php
languages/messages/MessagesUz.php
languages/messages/MessagesVec.php
languages/messages/MessagesVi.php
languages/messages/MessagesVot.php
languages/messages/MessagesWar.php
languages/messages/MessagesYi.php
languages/messages/MessagesZh_hans.php
languages/messages/MessagesZh_hant.php
maintenance/Maintenance.php
maintenance/archives/upgradeLogging.php
maintenance/backupPrefetch.inc
maintenance/changePassword.php
maintenance/checkSyntax.php
maintenance/deleteEqualMessages.php [new file with mode: 0644]
maintenance/deleteOldRevisions.php
maintenance/deleteOrphanedRevisions.php
maintenance/dev/includes/router.php
maintenance/doMaintenance.php
maintenance/dumpLinks.php
maintenance/dumpTextPass.php
maintenance/edit.php
maintenance/eval.php
maintenance/fileOpPerfTest.php
maintenance/formatInstallDoc.php
maintenance/fuzz-tester.php
maintenance/lag.php
maintenance/language/generateCollationData.php
maintenance/language/languages.inc
maintenance/language/messages.inc
maintenance/locking/LockServerDaemon.php
maintenance/mergeMessageFileList.php
maintenance/mwdocgen.php
maintenance/nextJobDB.php
maintenance/populateLogUsertext.php
maintenance/postgres/archives/patch-sites.sql [new file with mode: 0644]
maintenance/postgres/tables.sql
maintenance/preprocessDump.php
maintenance/proxy_check.php
maintenance/purgeList.php
maintenance/reassignEdits.php
maintenance/refreshImageMetadata.php
maintenance/runJobs.php
maintenance/showStats.php
maintenance/storage/fixBug20757.php
maintenance/storage/moveToExternal.php
maintenance/storage/recompressTracked.php
maintenance/storage/resolveStubs.php
maintenance/storage/storageTypeStats.php
maintenance/storage/testCompression.php
maintenance/term/MWTerm.php
maintenance/userOptions.php
opensearch_desc.php
profileinfo.php
resources/Resources.php
resources/jquery/jquery.client.js
resources/jquery/jquery.tablesorter.js
resources/mediawiki.action/mediawiki.action.view.dblClickEdit.js
resources/mediawiki.special/mediawiki.special.preferences.js
resources/mediawiki/mediawiki.jqueryMsg.js
resources/mediawiki/mediawiki.js
resources/mediawiki/mediawiki.user.js
serialized/serialize.php
skins/common/shared.css
skins/vector/images/border.png [deleted file]
skins/vector/images/page-base.png [deleted file]
skins/vector/images/preferences-base.png [deleted file]
skins/vector/images/preferences-edge.png [deleted file]
skins/vector/screen.css
tests/TestsAutoLoader.php
tests/parser/parserTest.inc
tests/parser/parserTests.txt
tests/parser/preprocess/NestedTemplates.expected [new file with mode: 0644]
tests/parser/preprocess/NestedTemplates.txt [new file with mode: 0644]
tests/phpunit/includes/GlobalFunctions/GlobalTest.php
tests/phpunit/includes/HtmlTest.php
tests/phpunit/includes/ParserOptionsTest.php [deleted file]
tests/phpunit/includes/UIDGeneratorTest.php [new file with mode: 0644]
tests/phpunit/includes/api/ApiGeneratorTest.php
tests/phpunit/includes/api/ApiQueryRevisionsTest.php [deleted file]
tests/phpunit/includes/api/ApiQueryTest.php [deleted file]
tests/phpunit/includes/api/ApiTestCase.php
tests/phpunit/includes/api/ApiUploadTest.php
tests/phpunit/includes/api/PrefixUniquenessTest.php
tests/phpunit/includes/api/query/ApiQueryBasicTest.php [new file with mode: 0644]
tests/phpunit/includes/api/query/ApiQueryRevisionsTest.php [new file with mode: 0644]
tests/phpunit/includes/api/query/ApiQueryTest.php [new file with mode: 0644]
tests/phpunit/includes/db/DatabaseSqliteTest.php
tests/phpunit/includes/jobqueue/JobQueueTest.php [new file with mode: 0644]
tests/phpunit/includes/parser/PreprocessorTest.php
tests/phpunit/languages/LanguageRuTest.php
tests/qunit/suites/resources/jquery/jquery.client.test.js
tests/qunit/suites/resources/jquery/jquery.tablesorter.test.js
tests/qunit/suites/resources/mediawiki/mediawiki.jqueryMsg.test.js

index 004ecf4..ceff243 100644 (file)
@@ -37,6 +37,11 @@ StartProfiler.php
 # Building & testing
 node_modules/
 
+# Composer
+/vendor
+/composer.lock
+/composer.json
+
 # Operating systems
 ## Mac OS X
 .DS_Store
diff --git a/INSTALL b/INSTALL
index e393631..891be73 100644 (file)
--- a/INSTALL
+++ b/INSTALL
@@ -20,7 +20,8 @@ If your PHP is configured as a CGI plug-in rather than an Apache module you may
 experience problems, as this configuration is not well tested. safe_mode is also
 not tested and unlikely to work.
 
-If you want math support see the instructions in math/README
+Support for rendering mathematical formulas requires installing the Math extension,
+see http://www.mediawiki.org/wiki/Extension:Math
 
 Don't forget to check the RELEASE-NOTES file...
 
@@ -45,12 +46,15 @@ In-place web install
 
 Decompress the MediaWiki installation archive either on your server, or on your
 local machine and upload the directory tree. Rename it from "mediawiki-1.x.x" to
-something nice, like "wiki", since it'll be in your URL.
+something nice, like "wiki", since it will be appearing in your URL,
+ie. /wiki/index.php/Article.
 
   +--------------------------------------------------------------------------+
-  |  Hint: If you plan to use a fancy URL-rewriting scheme to prettify your  |
-  |  URLs, you should put the files in a *different* directory from the      |
-  |  virtual path where page names will appear.                              |
+  |  Note: If you plan to use a fancy URL-rewriting scheme to prettify your  |
+  |  URLs, such as http://www.example.com/wiki/Article, you should put the   |
+  |  files in a *different* directory from the virtual path where page names |
+  |  will appear. It is common in this case to use w as the folder name and  |
+  |  /wiki/ as the virtual article path where your articles pretend to be.   |
   |                                                                          |
   |    See: http://www.mediawiki.org/wiki/Manual:Short_URL                   |
   +--------------------------------------------------------------------------+
index b9fdecf..d1976dd 100644 (file)
@@ -16,6 +16,8 @@ production.
   of page watchers required for the number to be accessible to users
   without the unwatchedpages permission.
 * $wgBug34832TransitionalRollback has been removed.
+* (bug 29472) $wgUseDynamicDates has been removed and its functionality
+  disabled.
 
 === New features in 1.21 ===
 * (bug 38110) Schema changes (adding or dropping tables, indicies and
@@ -85,7 +87,15 @@ production.
   a security fix (bug 42202).
 * Added the ability to limit the wall clock time used by shell processes,
   as well as the CPU time. Configurable with $wgMaxShellWallClockTime.
-* Added $wgWhitelistReadRegexp for regex whitelisting
+* Allow memory of shell subprocesses to be limited using Linux cgroups
+  instead of ulimit -v, which tends to cause deadlocks in recent versions
+  of ImageMagick. Configurable with $wgShellCgroup.
+* Added $wgWhitelistReadRegexp for regex whitelisting.
+* (bug 5346) Categories that are redirects will be displayed italic in
+  the category links section at the bottom of a page.
+* (bug 43915) New maintenance script deleteEqualMessages.php.
+* New collation uppercase-sv, which is like uppercase, but adapted
+  to Swedish sort order.
 
 === Bug fixes in 1.21 ===
 * (bug 40353) SpecialDoubleRedirect should support interwiki redirects.
@@ -191,11 +201,25 @@ production.
 * (bug 43849) ApiQueryImageInfo no longer throws exceptions with ForeignDBRepo
   redirects.
 * On error, any warnings generated before that error will be shown in the result.
+* action=help suports generalized submodules (modules=query+value), querymodules obsolete
+* ApiQueryImageInfo continuation is more reliable. The only major change is
+  that the imagerepository property will no longer be set on page objects not
+  processed in the current query (i.e. non-images or those skipped due to
+  iicontinue).
+* Add supports for all pageset capabilities - generators, redirects, converttitles to
+  action=purge and action=setnotificationtimestamp.
 
 === API internal changes in 1.21 ===
 * For debugging only, a new global $wgDebugAPI removes many API restrictions when true.
   Never use on the production servers, as this flag introduces security holes.
   Whenever enabled, a warning will also be added to all output.
+* ApiModuleManager now handles all submodules (actions,props,lists) and instantiation
+* Query stores prop/list/meta as submodules
+* ApiPageSet can now be used in any action to process titles/pageids/revids or any generator.
+* BREAKING CHANGE: ApiPageSet constructor now has two params instead of three, with only the
+  first one keeping its meaning. ApiPageSet is now derived from ApiBase.
+* BREAKING CHANGE: ApiQuery::newGenerator() and executeGeneratorModule() were deleted.
+* ApiQueryGeneratorBase::setGeneratorMode() now requires a pageset param.
 
 === Languages updated in 1.21 ===
 
diff --git a/api.php b/api.php
index 94266d8..4efcdba 100644 (file)
--- a/api.php
+++ b/api.php
@@ -107,4 +107,3 @@ if ( $wgAPIRequestLog ) {
 // get here to worry about whether this should be = or =&, but the file has to parse properly.
 $lb = wfGetLBFactory();
 $lb->shutdown();
-
diff --git a/bin/ulimit5.sh b/bin/ulimit5.sh
deleted file mode 100644 (file)
index fd8aae2..0000000
+++ /dev/null
@@ -1,21 +0,0 @@
-#!/bin/bash
-
-if [ "$1" -gt 0 ]; then
-       ulimit -t "$1"
-fi
-if [ "$2" -gt 0 ]; then
-       ulimit -v "$2"
-fi
-if [ "$3" -gt 0 ]; then
-       ulimit -f "$3"
-fi
-if [ "$4" -gt 0 -a -x "/usr/bin/timeout" ]; then
-       /usr/bin/timeout $4 /bin/bash -c "$5"
-       STATUS="$?"
-       if [ "$STATUS" == 124 ]; then
-               echo "ulimit5.sh: timed out." 1>&2
-       fi
-       exit "$STATUS"
-else
-       eval "$5"
-fi
diff --git a/composer.json b/composer.json
new file mode 100644 (file)
index 0000000..fa42c29
--- /dev/null
@@ -0,0 +1,36 @@
+{
+       "name": "mediawiki/core",
+       "description": "Free software wiki application developed by the Wikimedia Foundation and others",
+       "keywords": ["mediawiki", "wiki"],
+       "homepage": "https://www.mediawiki.org/",
+       "authors": [
+               {
+                       "name": "MediaWiki Community",
+                       "homepage": "https://www.mediawiki.org/wiki/Special:Version/Credits"
+               }
+       ],
+       "license": "GPL-2.0",
+       "repositories": [
+               {
+                       "type": "vcs",
+                       "url": "https://gerrit.wikimedia.org/r/p/mediawiki/core.git"
+               }
+       ],
+       "support": {
+               "issues": "https://bugzilla.wikimedia.org/",
+               "irc": "irc://irc.freenode.net/mediawiki",
+               "wiki": "https://www.mediawiki.org/"
+       },
+       "require": {
+               "php": ">=5.3.2"
+       },
+       "require-dev": {
+               "phpunit/phpunit": "*"
+       },
+       "suggest": {
+               "ext-fileinfo": "*",
+               "ext-mbstring": "*",
+               "ext-wikidiff2": "*",
+               "ext-apc": "*"
+       }
+}
index f9274a5..28eedf4 100644 (file)
@@ -355,6 +355,7 @@ $text : the new text of the article (has yet to be saved)
 'APIGetAllowedParams': Use this hook to modify a module's parameters.
 &$module: ApiBase Module object
 &$params: Array of parameters
+$flags: int zero or OR-ed flags like ApiBase::GET_VALUES_FOR_HELP
 
 'APIGetDescription': Use this hook to modify a module's description.
 &$module: ApiBase Module object
index b04974b..2f7fb39 100644 (file)
@@ -106,7 +106,7 @@ function wfImageAuthMain() {
 
        // Check to see if the file exists
        if ( !$repo->fileExists( $filename ) ) {
-               wfForbidden( 'img-auth-accessdenied','img-auth-nofile', $filename );
+               wfForbidden( 'img-auth-accessdenied', 'img-auth-nofile', $filename );
                return;
        }
 
index 4ff31b8..d1b72a0 100644 (file)
@@ -13,11 +13,11 @@ class ArrayUtils {
         * 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 
+        *     key. This can be chosen to provide backwards compatibility with
         *     various consistent hash implementations that existed before this
         *     function was introduced.
         */
@@ -31,4 +31,3 @@ class ArrayUtils {
                } );
        }
 }
-
index 10cbac7..1dc27a7 100644 (file)
@@ -33,7 +33,7 @@
  *
  * @internal documentation reviewed 15 Mar 2010
  */
-class Article extends Page {
+class Article implements Page {
        /**@{{
         * @private
         */
@@ -420,7 +420,7 @@ class Article extends Page {
                # Pre-fill content with error message so that if something
                # fails we'll have something telling us what we intended.
                //XXX: this isn't page content but a UI message. horrible.
-               $this->mContentObject = new MessageContent( 'missing-revision', array( $oldid ), array() ) ;
+               $this->mContentObject = new MessageContent( 'missing-revision', array( $oldid ), array() );
 
                if ( $oldid ) {
                        # $this->mRevision might already be fetched by getOldIDFromRequest()
@@ -1122,7 +1122,7 @@ class Article extends Page {
 
                # Show delete and move logs
                LogEventsList::showLogExtract( $outputPage, array( 'delete', 'move' ), $this->getTitle(), '',
-                       array(  'lim' => 10,
+                       array( 'lim' => 10,
                                'conds' => array( "log_action != 'revision'" ),
                                'showIfEmpty' => false,
                                'msgKey' => array( 'moveddeleted-notice' ) )
@@ -1268,7 +1268,7 @@ class Article extends Page {
                                        'oldid' => $oldid
                                ) + $extraParams
                        );
-               $prev = $this->getTitle()->getPreviousRevisionID( $oldid ) ;
+               $prev = $this->getTitle()->getPreviousRevisionID( $oldid );
                $prevlink = $prev
                        ? Linker::linkKnown(
                                $this->getTitle(),
@@ -1483,7 +1483,7 @@ class Article extends Page {
                                $reason = $this->generateReason( $hasHistory );
                        } catch ( MWException $e ) {
                                # if a page is horribly broken, we still want to be able to delete it. so be lenient about errors here.
-                               wfDebug("Error while building auto delete summary: $e");
+                               wfDebug( "Error while building auto delete summary: $e" );
                                $reason = '';
                        }
                }
index 8096ed6..06e3f22 100644 (file)
@@ -95,6 +95,7 @@ $wgAutoloadLocalClasses = array(
        'ExternalStoreDB' => 'includes/externalstore/ExternalStoreDB.php',
        'ExternalStoreHttp' => 'includes/externalstore/ExternalStoreHttp.php',
        'ExternalStoreMedium' => 'includes/externalstore/ExternalStoreMedium.php',
+       'ExternalStoreMwstore' => 'includes/externalstore/ExternalStoreMwstore.php',
        'ExternalUser' => 'includes/ExternalUser.php',
        'FakeTitle' => 'includes/FakeTitle.php',
        'Fallback' => 'includes/Fallback.php',
@@ -253,9 +254,11 @@ $wgAutoloadLocalClasses = array(
        'TitleArray' => 'includes/TitleArray.php',
        'TitleArrayFromResult' => 'includes/TitleArray.php',
        'ThrottledError' => 'includes/Exception.php',
+       'UIDGenerator' => 'includes/UIDGenerator.php',
        'UnlistedSpecialPage' => 'includes/SpecialPage.php',
        'UploadSourceAdapter' => 'includes/Import.php',
        'UppercaseCollation' => 'includes/Collation.php',
+       'UppercaseSvCollation' => 'includes/Collation.php',
        'User' => 'includes/User.php',
        'UserArray' => 'includes/UserArray.php',
        'UserArrayFromResult' => 'includes/UserArray.php',
@@ -363,6 +366,7 @@ $wgAutoloadLocalClasses = array(
        'ApiLogin' => 'includes/api/ApiLogin.php',
        'ApiLogout' => 'includes/api/ApiLogout.php',
        'ApiMain' => 'includes/api/ApiMain.php',
+       'ApiModuleManager' => 'includes/api/ApiModuleManager.php',
        'ApiMove' => 'includes/api/ApiMove.php',
        'ApiOpenSearch' => 'includes/api/ApiOpenSearch.php',
        'ApiOptions' => 'includes/api/ApiOptions.php',
@@ -450,6 +454,10 @@ $wgAutoloadLocalClasses = array(
        'TitleDependency' => 'includes/cache/CacheDependency.php',
        'TitleListDependency' => 'includes/cache/CacheDependency.php',
 
+       # includes/clientpool
+       'RedisConnectionPool' => 'includes/clientpool/RedisConnectionPool.php',
+       'RedisConnRef' => 'includes/clientpool/RedisConnectionPool.php',
+
        # includes/context
        'ContextSource' => 'includes/context/ContextSource.php',
        'DerivativeContext' => 'includes/context/DerivativeContext.php',
@@ -573,7 +581,7 @@ $wgAutoloadLocalClasses = array(
        'DBLockManager' => 'includes/filebackend/lockmanager/DBLockManager.php',
        'LSLockManager' => 'includes/filebackend/lockmanager/LSLockManager.php',
        'MemcLockManager' => 'includes/filebackend/lockmanager/MemcLockManager.php',
-       'QuorumLockManager' => 'includes/filebackend/lockmanager/LockManager.php',
+       'QuorumLockManager' => 'includes/filebackend/lockmanager/QuorumLockManager.php',
        'MySqlLockManager'=> 'includes/filebackend/lockmanager/DBLockManager.php',
        'NullLockManager' => 'includes/filebackend/lockmanager/LockManager.php',
        'FileOp' => 'includes/filebackend/FileOp.php',
@@ -654,6 +662,7 @@ $wgAutoloadLocalClasses = array(
        'JobQueue' => 'includes/job/JobQueue.php',
        'JobQueueDB' => 'includes/job/JobQueueDB.php',
        'JobQueueGroup' => 'includes/job/JobQueueGroup.php',
+       'JobQueueRedis' => 'includes/job/JobQueueRedis.php',
 
        # includes/job/jobs
        'DoubleRedirectJob' => 'includes/job/jobs/DoubleRedirectJob.php',
@@ -775,35 +784,24 @@ $wgAutoloadLocalClasses = array(
        'MWTidyWrapper' => 'includes/parser/Tidy.php',
        'PPCustomFrame_DOM' => 'includes/parser/Preprocessor_DOM.php',
        'PPCustomFrame_Hash' => 'includes/parser/Preprocessor_Hash.php',
-       'PPCustomFrame_HipHop' => 'includes/parser/Preprocessor_HipHop.hphp',
        'PPDAccum_Hash' => 'includes/parser/Preprocessor_Hash.php',
-       'PPDAccum_HipHop' => 'includes/parser/Preprocessor_HipHop.hphp',
        'PPDPart' => 'includes/parser/Preprocessor_DOM.php',
        'PPDPart_Hash' => 'includes/parser/Preprocessor_Hash.php',
-       'PPDPart_HipHop' => 'includes/parser/Preprocessor_HipHop.hphp',
        'PPDStack' => 'includes/parser/Preprocessor_DOM.php',
        'PPDStackElement' => 'includes/parser/Preprocessor_DOM.php',
        'PPDStackElement_Hash' => 'includes/parser/Preprocessor_Hash.php',
-       'PPDStackElement_HipHop' => 'includes/parser/Preprocessor_HipHop.hphp',
        'PPDStack_Hash' => 'includes/parser/Preprocessor_Hash.php',
-       'PPDStack_HipHop' => 'includes/parser/Preprocessor_HipHop.hphp',
        'PPFrame' => 'includes/parser/Preprocessor.php',
        'PPFrame_DOM' => 'includes/parser/Preprocessor_DOM.php',
        'PPFrame_Hash' => 'includes/parser/Preprocessor_Hash.php',
-       'PPFrame_HipHop' => 'includes/parser/Preprocessor_HipHop.hphp',
        'PPNode' => 'includes/parser/Preprocessor.php',
        'PPNode_DOM' => 'includes/parser/Preprocessor_DOM.php',
        'PPNode_Hash_Array' => 'includes/parser/Preprocessor_Hash.php',
        'PPNode_Hash_Attr' => 'includes/parser/Preprocessor_Hash.php',
        'PPNode_Hash_Text' => 'includes/parser/Preprocessor_Hash.php',
        'PPNode_Hash_Tree' => 'includes/parser/Preprocessor_Hash.php',
-       'PPNode_HipHop_Array' => 'includes/parser/Preprocessor_HipHop.hphp',
-       'PPNode_HipHop_Attr' => 'includes/parser/Preprocessor_HipHop.hphp',
-       'PPNode_HipHop_Text' => 'includes/parser/Preprocessor_HipHop.hphp',
-       'PPNode_HipHop_Tree' => 'includes/parser/Preprocessor_HipHop.hphp',
        'PPTemplateFrame_DOM' => 'includes/parser/Preprocessor_DOM.php',
        'PPTemplateFrame_Hash' => 'includes/parser/Preprocessor_Hash.php',
-       'PPTemplateFrame_HipHop' => 'includes/parser/Preprocessor_HipHop.hphp',
        'Parser' => 'includes/parser/Parser.php',
        'ParserCache' => 'includes/parser/ParserCache.php',
        'ParserOptions' => 'includes/parser/ParserOptions.php',
@@ -813,7 +811,6 @@ $wgAutoloadLocalClasses = array(
        'Preprocessor' => 'includes/parser/Preprocessor.php',
        'Preprocessor_DOM' => 'includes/parser/Preprocessor_DOM.php',
        'Preprocessor_Hash' => 'includes/parser/Preprocessor_Hash.php',
-       'Preprocessor_HipHop' => 'includes/parser/Preprocessor_HipHop.hphp',
        'StripState' => 'includes/parser/StripState.php',
 
        # includes/profiler
@@ -1081,7 +1078,7 @@ $wgAutoloadLocalClasses = array(
        'wikiStatsOutput' => 'maintenance/language/StatOutputs.php',
 
        # maintenance/term
-       'AnsiTermColorer'  => 'maintenance/term/MWTerm.php',
+       'AnsiTermColorer' => 'maintenance/term/MWTerm.php',
        'DummyTermColorer' => 'maintenance/term/MWTerm.php',
 
        # mw-config
index fde5f07..1d1e2c0 100644 (file)
@@ -465,7 +465,7 @@ class Block {
                Block::purgeExpired();
 
                $row = $this->getDatabaseArray();
-               $row['ipb_id'] = $dbw->nextSequenceValue("ipblocks_ipb_id_seq");
+               $row['ipb_id'] = $dbw->nextSequenceValue( "ipblocks_ipb_id_seq" );
 
                $dbw->insert(
                        'ipblocks',
index b9c9609..53e44d7 100644 (file)
@@ -75,11 +75,11 @@ class Category {
                        # Okay, there were no contents.  Nothing to initialize.
                        if ( $this->mTitle ) {
                                # If there is a title object but no record in the category table, treat this as an empty category
-                               $this->mID      = false;
-                               $this->mName    = $this->mTitle->getDBkey();
-                               $this->mPages   = 0;
+                               $this->mID = false;
+                               $this->mName = $this->mTitle->getDBkey();
+                               $this->mPages = 0;
                                $this->mSubcats = 0;
-                               $this->mFiles   = 0;
+                               $this->mFiles = 0;
 
                                return true;
                        } else {
@@ -87,11 +87,11 @@ class Category {
                        }
                }
 
-               $this->mID      = $row->cat_id;
-               $this->mName    = $row->cat_title;
-               $this->mPages   = $row->cat_pages;
+               $this->mID = $row->cat_id;
+               $this->mName = $row->cat_title;
+               $this->mPages = $row->cat_pages;
                $this->mSubcats = $row->cat_subcats;
-               $this->mFiles   = $row->cat_files;
+               $this->mFiles = $row->cat_files;
 
                # (bug 13683) If the count is negative, then 1) it's obviously wrong
                # and should not be kept, and 2) we *probably* don't have to scan many
@@ -179,16 +179,16 @@ class Category {
                                $cat->mName = $title->getDBkey(); # if we have a title object, fetch the category name from there
                        }
 
-                       $cat->mID =   false;
+                       $cat->mID = false;
                        $cat->mSubcats = 0;
-                       $cat->mPages   = 0;
-                       $cat->mFiles   = 0;
+                       $cat->mPages = 0;
+                       $cat->mFiles = 0;
                } else {
-                       $cat->mName    = $row->cat_title;
-                       $cat->mID      = $row->cat_id;
+                       $cat->mName = $row->cat_title;
+                       $cat->mID = $row->cat_id;
                        $cat->mSubcats = $row->cat_subcats;
-                       $cat->mPages   = $row->cat_pages;
-                       $cat->mFiles   = $row->cat_files;
+                       $cat->mPages = $row->cat_pages;
+                       $cat->mFiles = $row->cat_files;
                }
 
                return $cat;
@@ -350,9 +350,9 @@ class Category {
                wfProfileOut( __METHOD__ );
 
                # Now we should update our local counts.
-               $this->mPages   = $result->pages;
+               $this->mPages = $result->pages;
                $this->mSubcats = $result->subcats;
-               $this->mFiles   = $result->files;
+               $this->mFiles = $result->files;
 
                return $ret;
        }
index 589950f..cb67aa8 100644 (file)
@@ -211,7 +211,7 @@ class Categoryfinder {
                        $res = $this->dbr->select(
                                /* FROM   */ 'page',
                                /* SELECT */ array( 'page_id', 'page_title' ),
-                               /* WHERE  */ array( 'page_namespace' => NS_CATEGORY , 'page_title' => $layer ),
+                               /* WHERE  */ array( 'page_namespace' => NS_CATEGORY, 'page_title' => $layer ),
                                __METHOD__ . '-2'
                        );
                        foreach ( $res as $o ) {
index 2a6a3d2..1c4587a 100644 (file)
@@ -133,7 +133,7 @@ class CdbReader_DBA {
        }
 
        function close() {
-               if( isset($this->handle) ) {
+               if( isset( $this->handle ) ) {
                        dba_close( $this->handle );
                }
                unset( $this->handle );
@@ -165,7 +165,7 @@ class CdbWriter_DBA {
        }
 
        function close() {
-               if( isset($this->handle) ) {
+               if( isset( $this->handle ) ) {
                        dba_close( $this->handle );
                }
                if ( wfIsWindows() ) {
@@ -183,4 +183,3 @@ class CdbWriter_DBA {
                }
        }
 }
-
index f58e07e..71b55f8 100644 (file)
@@ -332,10 +332,10 @@ class CdbWriter_PHP extends CdbWriter {
         */
        public function close() {
                $this->finish();
-               if( isset($this->handle) ) {
+               if( isset( $this->handle ) ) {
                        fclose( $this->handle );
                }
-               if ( wfIsWindows() && file_exists($this->realFileName) ) {
+               if ( wfIsWindows() && file_exists( $this->realFileName ) ) {
                        unlink( $this->realFileName );
                }
                if ( !rename( $this->tmpFileName, $this->realFileName ) ) {
@@ -351,7 +351,7 @@ class CdbWriter_PHP extends CdbWriter {
        protected function write( $buf ) {
                $len = fwrite( $this->handle, $buf );
                if ( $len !== strlen( $buf ) ) {
-                       $this->throwException( 'Error writing to CDB file "'.$this->tmpFileName.'".' );
+                       $this->throwException( 'Error writing to CDB file "' . $this->tmpFileName . '".' );
                }
        }
 
@@ -363,7 +363,7 @@ class CdbWriter_PHP extends CdbWriter {
                $newpos = $this->pos + $len;
                if ( $newpos > 0x7fffffff ) {
                        $this->throwException(
-                               'A value in the CDB file "'.$this->tmpFileName.'" is too large.' );
+                               'A value in the CDB file "' . $this->tmpFileName . '" is too large.' );
                }
                $this->pos = $newpos;
        }
@@ -392,10 +392,10 @@ class CdbWriter_PHP extends CdbWriter {
         */
        protected function addbegin( $keylen, $datalen ) {
                if ( $keylen > 0x7fffffff ) {
-                       $this->throwException( 'Key length too long in file "'.$this->tmpFileName.'".' );
+                       $this->throwException( 'Key length too long in file "' . $this->tmpFileName . '".' );
                }
                if ( $datalen > 0x7fffffff ) {
-                       $this->throwException( 'Data length too long in file "'.$this->tmpFileName.'".' );
+                       $this->throwException( 'Data length too long in file "' . $this->tmpFileName . '".' );
                }
                $buf = pack( 'VV', $keylen, $datalen );
                $this->write( $buf );
@@ -470,7 +470,7 @@ class CdbWriter_PHP extends CdbWriter {
                // Write the pointer array at the start of the file
                rewind( $this->handle );
                if ( ftell( $this->handle ) != 0 ) {
-                       $this->throwException( 'Error rewinding to start of file "'.$this->tmpFileName.'".' );
+                       $this->throwException( 'Error rewinding to start of file "' . $this->tmpFileName . '".' );
                }
                $this->write( $final );
        }
index 18f425a..1dd9b59 100644 (file)
@@ -169,7 +169,7 @@ class ChangeTags {
         *
         * @throws MWException When unable to determine appropriate JOIN condition for tagging
         */
-       static function modifyDisplayQuery( &$tables, &$fields,  &$conds,
+       static function modifyDisplayQuery( &$tables, &$fields, &$conds,
                                                                                &$join_conds, &$options, $filter_tag = false ) {
                global $wgRequest, $wgUseTagFilter;
 
@@ -221,7 +221,7 @@ class ChangeTags {
         *        - 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() ) ) {
index ee4c2d6..ae30272 100644 (file)
@@ -135,7 +135,7 @@ class ChangesFeed {
                $feedLastmod = $messageMemc->get( $timekey );
 
                if( ( $wgFeedCacheTimeout > 0 ) && $feedLastmod ) {
-                   /**
+                       /**
                         * If the cached feed was rendered very recently, we may
                         * go ahead and use it even if there have been edits made
                         * since it was rendered. This keeps a swarm of requests
index 85fd8af..a9b9c31 100644 (file)
@@ -30,7 +30,7 @@
  */
 class RCCacheEntry extends RecentChange {
        var $secureName, $link;
-       var $curlink , $difflink, $lastlink, $usertalklink, $versionlink;
+       var $curlink, $difflink, $lastlink, $usertalklink, $versionlink;
        var $userlink, $timestamp, $watched;
 
        /**
@@ -217,7 +217,7 @@ class ChangesList extends ContextSource {
                $lang = $context->getLanguage();
                $code = $lang->getCode();
                static $fastCharDiff = array();
-               if ( !isset($fastCharDiff[$code]) ) {
+               if ( !isset( $fastCharDiff[$code] ) ) {
                        $fastCharDiff[$code] = $wgMiserMode || $context->msg( 'rc-change-size' )->plain() === '$1';
                }
 
@@ -328,7 +328,7 @@ class ChangesList extends ContextSource {
                } else {
                        $query = array(
                                'curid' => $rc->mAttribs['rc_cur_id'],
-                               'diff'  => $rc->mAttribs['rc_this_oldid'],
+                               'diff' => $rc->mAttribs['rc_this_oldid'],
                                'oldid' => $rc->mAttribs['rc_last_oldid']
                        );
 
@@ -387,7 +387,7 @@ class ChangesList extends ContextSource {
                $articlelink .= $this->getLanguage()->getDirMark();
 
                wfRunHooks( 'ChangesListInsertArticleLink',
-                       array(&$this, &$articlelink, &$s, &$rc, $unpatrolled, $watched) );
+                       array( &$this, &$articlelink, &$s, &$rc, $unpatrolled, $watched ) );
 
                $s .= " $articlelink";
        }
@@ -534,14 +534,14 @@ class ChangesList extends ContextSource {
                        $page = $rc->getTitle();
                        /** Check for rollback and edit permissions, disallow special pages, and only
                          * show a link on the top-most revision */
-                       if ( $this->getUser()->isAllowed('rollback') && $rc->mAttribs['page_latest'] == $rc->mAttribs['rc_this_oldid'] )
+                       if ( $this->getUser()->isAllowed( 'rollback' ) && $rc->mAttribs['page_latest'] == $rc->mAttribs['rc_this_oldid'] )
                        {
                                $rev = new Revision( array(
-                                       'title'     => $page,
-                                       'id'        => $rc->mAttribs['rc_this_oldid'],
-                                       'user'      => $rc->mAttribs['rc_user'],
+                                       'title' => $page,
+                                       'id' => $rc->mAttribs['rc_this_oldid'],
+                                       'user' => $rc->mAttribs['rc_user'],
                                        'user_text' => $rc->mAttribs['rc_user_text'],
-                                       'deleted'   => $rc->mAttribs['rc_deleted']
+                                       'deleted' => $rc->mAttribs['rc_deleted']
                                ) );
                                $s .= ' '.Linker::generateRollback( $rev, $this->getContext() );
                        }
@@ -554,10 +554,10 @@ class ChangesList extends ContextSource {
         * @param $classes
         */
        public function insertTags( &$s, &$rc, &$classes ) {
-               if ( empty($rc->mAttribs['ts_tags']) )
+               if ( empty( $rc->mAttribs['ts_tags'] ) )
                        return;
 
-               list($tagSummary, $newClasses) = ChangeTags::formatSummaryRow( $rc->mAttribs['ts_tags'], 'changeslist' );
+               list( $tagSummary, $newClasses ) = ChangeTags::formatSummaryRow( $rc->mAttribs['ts_tags'], 'changeslist' );
                $classes = array_merge( $classes, $newClasses );
                $s .= ' ' . $tagSummary;
        }
@@ -679,7 +679,7 @@ class OldChangesList extends ChangesList {
                }
 
                if( $this->watchlist ) {
-                       $classes[] = Sanitizer::escapeClass( 'watchlist-'.$rc->mAttribs['rc_namespace'].'-'.$rc->mAttribs['rc_title'] );
+                       $classes[] = Sanitizer::escapeClass( 'watchlist-' . $rc->mAttribs['rc_namespace'] . '-' . $rc->mAttribs['rc_title'] );
                }
 
                if ( !wfRunHooks( 'OldChangesListRecentChangesLine', array( &$this, &$s, $rc, &$classes ) ) ) {
@@ -688,7 +688,7 @@ class OldChangesList extends ChangesList {
                }
 
                wfProfileOut( __METHOD__ );
-               return "$dateheader<li class=\"".implode( ' ', $classes )."\">".$s."</li>\n";
+               return "$dateheader<li class=\"" . implode( ' ', $classes ) . "\">" . $s . "</li>\n";
        }
 }
 
@@ -822,7 +822,7 @@ class EnhancedChangesList extends ChangesList {
                        $lastLink = $this->message['last'];
                } else {
                        $lastLink = Linker::linkKnown( $rc->getTitle(), $this->message['last'],
-                               array(), $curIdEq + array('diff' => $thisOldid, 'oldid' => $lastOldid) + $rcIdQuery );
+                               array(), $curIdEq + array( 'diff' => $thisOldid, 'oldid' => $lastOldid ) + $rcIdQuery );
                }
 
                # Make user links
@@ -834,7 +834,7 @@ class EnhancedChangesList extends ChangesList {
                }
 
                $rc->lastlink = $lastLink;
-               $rc->curlink  = $curLink;
+               $rc->curlink = $curLink;
                $rc->difflink = $diffLink;
 
                # Put accumulated information into the cache, for later display
@@ -843,7 +843,7 @@ class EnhancedChangesList extends ChangesList {
                $secureName = $title->getPrefixedDBkey();
                if( $type == RC_MOVE || $type == RC_MOVE_OVER_REDIRECT ) {
                        # Use an @ character to prevent collision with page names
-                       $this->rc_cache['@@' . ($this->rcMoveIndex++)] = array($rc);
+                       $this->rc_cache['@@' . ($this->rcMoveIndex++)] = array( $rc );
                } else {
                        # Logs are grouped by type
                        if( $type == RC_LOG ) {
@@ -964,7 +964,7 @@ class EnhancedChangesList extends ChangesList {
                ) );
 
                # Timestamp
-               $r .= '&#160;'.$block[0]->timestamp.'&#160;</td><td>';
+               $r .= '&#160;' . $block[0]->timestamp . '&#160;</td><td>';
 
                # Article link
                if( $namehidden ) {
@@ -979,7 +979,7 @@ class EnhancedChangesList extends ChangesList {
 
                $queryParams['curid'] = $curId;
                # Changes message
-               $n = count($block);
+               $n = count( $block );
                static $nchanges = array();
                if ( !isset( $nchanges[$n] ) ) {
                        $nchanges[$n] = $this->msg( 'nchanges' )->numParams( $n )->escaped();
@@ -1034,7 +1034,7 @@ class EnhancedChangesList extends ChangesList {
                # Character difference (does not apply if only log items)
                if( $wgRCShowChangedSize && !$allLogs ) {
                        $last = 0;
-                       $first = count($block) - 1;
+                       $first = count( $block ) - 1;
                        # Some events (like logs) have an "empty" size, so we need to skip those...
                        while( $last < $first && $block[$last]->mAttribs['rc_new_len'] === null ) {
                                $last++;
@@ -1053,7 +1053,7 @@ class EnhancedChangesList extends ChangesList {
                }
 
                $r .= $users;
-               $r .= $this->numberofWatchingusers($block[0]->numberofWatchingusers);
+               $r .= $this->numberofWatchingusers( $block[0]->numberofWatchingusers );
 
                # Sub-entries
                foreach( $block as $rcObj ) {
@@ -1081,7 +1081,7 @@ class EnhancedChangesList extends ChangesList {
                                $link = $rcObj->timestamp;
                        # Revision link
                        } elseif( !ChangesList::userCan( $rcObj, Revision::DELETED_TEXT, $this->getUser() ) ) {
-                               $link = '<span class="history-deleted">'.$rcObj->timestamp.'</span> ';
+                               $link = '<span class="history-deleted">' . $rcObj->timestamp . '</span> ';
                        } else {
                                if ( $rcObj->unpatrolled && $type == RC_NEW) {
                                        $params['rcid'] = $rcObj->mAttribs['rc_id'];
@@ -1094,7 +1094,7 @@ class EnhancedChangesList extends ChangesList {
                                                $params
                                        );
                                if( $this->isDeleted( $rcObj, Revision::DELETED_TEXT ) ) {
-                                       $link = '<span class="history-deleted">'.$link.'</span> ';
+                                       $link = '<span class="history-deleted">' . $link . '</span> ';
                                }
                        }
                        $r .= $link . '</span>';
@@ -1144,7 +1144,7 @@ class EnhancedChangesList extends ChangesList {
         * @param $title String: text
         * @return String: HTML "<img>" tag
         */
-       protected function arrow( $dir, $alt='', $title='' ) {
+       protected function arrow( $dir, $alt = '', $title = '' ) {
                global $wgStylePath;
                $encUrl = htmlspecialchars( $wgStylePath . '/common/images/Arr_' . $dir . '.png' );
                $encAlt = htmlspecialchars( $alt );
@@ -1218,7 +1218,7 @@ class EnhancedChangesList extends ChangesList {
                                'bot' => $rcObj->mAttribs['rc_bot'],
                        ) );
                }
-               $r .= '&#160;'.$rcObj->timestamp.'&#160;</td><td>';
+               $r .= '&#160;' . $rcObj->timestamp . '&#160;</td><td>';
                # Article or log link
                if( $logType ) {
                        $logPage = new LogPage( $logType );
@@ -1250,7 +1250,7 @@ class EnhancedChangesList extends ChangesList {
                if ( $type == RC_LOG ) {
                        $r .= $this->insertLogEntry( $rcObj );
                } else {
-                       $r .= ' '.$rcObj->userlink . $rcObj->usertalklink;
+                       $r .= ' ' . $rcObj->userlink . $rcObj->usertalklink;
                        $r .= $this->insertComment( $rcObj );
                        $this->insertRollback( $r, $rcObj );
                }
@@ -1258,7 +1258,7 @@ class EnhancedChangesList extends ChangesList {
                # Tags
                $this->insertTags( $r, $rcObj, $classes );
                # Show how many people are watching this if enabled
-               $r .= $this->numberofWatchingusers($rcObj->numberofWatchingusers);
+               $r .= $this->numberofWatchingusers( $rcObj->numberofWatchingusers );
 
                $r .= "</td></tr></table>\n";
 
@@ -1291,7 +1291,7 @@ class EnhancedChangesList extends ChangesList {
 
                wfProfileOut( __METHOD__ );
 
-               return '<div>'.$blockOut.'</div>';
+               return '<div>' . $blockOut . '</div>';
        }
 
        /**
index 3cc7902..301904e 100644 (file)
@@ -43,6 +43,8 @@ abstract class Collation {
                switch( $collationName ) {
                        case 'uppercase':
                                return new UppercaseCollation;
+                       case 'uppercase-sv':
+                               return new UppercaseSvCollation;
                        case 'identity':
                                return new IdentityCollation;
                        case 'uca-default':
@@ -121,6 +123,22 @@ class UppercaseCollation extends Collation {
        }
 }
 
+/**
+ * Like UppercaseCollation but swaps Ä and Æ.
+ *
+ * This provides an ordering suitable for Swedish.
+ * @author Lejonel
+ */
+class UppercaseSvCollation extends UppercaseCollation {
+
+       /* Unicode code point order is ÄÅÆÖ, Swedish order is ÅÄÖ and Æ is often sorted as Ä.
+        * Replacing Ä for Æ should give a better collation. */
+       function getSortKey( $string ) {
+               $uppercase = $this->lang->uc( $string );
+               return strtr( $uppercase, array( 'Ä' => 'Æ', 'Æ' => 'Ä' ) );
+       }
+}
+
 /**
  * Collation class that's essentially a no-op.
  *
@@ -374,5 +392,55 @@ class IcuCollation extends Collation {
                }
                return false;
        }
-}
 
+       /**
+        * Return the version of ICU library used by PHP's intl extension,
+        * or false when the extension is not installed of the version
+        * can't be determined.
+        *
+        * The constant INTL_ICU_VERSION this function refers to isn't really
+        * documented. It is available since PHP 5.3.7 (see PHP bug 54561).
+        * This function will return false on older PHPs.
+        *
+        * @since 1.21
+        * @return string|false
+        */
+       static function getICUVersion() {
+               return defined( 'INTL_ICU_VERSION' ) ? INTL_ICU_VERSION : false;
+       }
+
+       /**
+        * Return the version of Unicode appropriate for the version of ICU library
+        * currently in use, or false when it can't be determined.
+        *
+        * @since 1.21
+        * @return string|false
+        */
+       static function getUnicodeVersionForICU() {
+               $icuVersion = IcuCollation::getICUVersion();
+               if ( !$icuVersion ) {
+                       return false;
+               }
+
+               $versionPrefix = substr( $icuVersion, 0, 3 );
+               // Source: http://site.icu-project.org/download
+               $map = array(
+                       '50.' => '6.2',
+                       '49.' => '6.1',
+                       '4.8' => '6.0',
+                       '4.6' => '6.0',
+                       '4.4' => '5.2',
+                       '4.2' => '5.1',
+                       '4.0' => '5.1',
+                       '3.8' => '5.0',
+                       '3.6' => '5.0',
+                       '3.4' => '4.1',
+               );
+
+               if ( isset( $map[$versionPrefix] ) ) {
+                       return $map[$versionPrefix];
+               } else {
+                       return false;
+               }
+       }
+}
index e563416..699e83a 100644 (file)
@@ -1095,4 +1095,3 @@ class ConfEditorToken {
                return $this->type == 'END';
        }
 }
-
index 48216f0..a6eb79a 100644 (file)
@@ -113,7 +113,7 @@ class Cookie {
                }
 
                // Don't allow cookies for "co.uk" or "gov.uk", etc, but allow "supermarket.uk"
-               if ( strrpos( $domain, "." ) - strlen( $domain )  == -3 ) {
+               if ( strrpos( $domain, "." ) - strlen( $domain ) == -3 ) {
                        if ( ( count( $dc ) == 2 && strlen( $dc[0] ) <= 2 )
                                || ( count( $dc ) == 3 && strlen( $dc[0] ) == "" && strlen( $dc[1] ) <= 2 ) ) {
                                return false;
@@ -165,8 +165,8 @@ class Cookie {
        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 ),
+                               && substr( $this->domain, 0, 1 ) == '.'
+                               && substr_compare( $domain, $this->domain, -strlen( $this->domain ),
                                                                        strlen( $this->domain ), true ) == 0 ) ) {
                        return true;
                }
index fcf6a39..4255d56 100644 (file)
@@ -106,7 +106,11 @@ class MWCryptRand {
                                        }
                                }
                                // The absolute filename itself will differ from install to install so don't leave it out
-                               $state .= realpath( $file );
+                               if( ( $path = realpath( $file ) ) !== false ) {
+                                       $state .= $path;
+                               } else {
+                                       $state .= $file;
+                               }
                                $state .= implode( '', $stat );
                        } else {
                                // The fact that the file isn't there is worth at least a
index 6a4f6a6..9439df2 100644 (file)
@@ -47,7 +47,7 @@
  * This is not a valid entry point, perform no further processing unless
  * MEDIAWIKI is defined
  */
-if( !defined( 'MEDIAWIKI' ) ) {
+if ( !defined( 'MEDIAWIKI' ) ) {
        echo "This file is part of MediaWiki and is not a valid entry point\n";
        die( 1 );
 }
@@ -104,7 +104,7 @@ $wgCanonicalServer = false;
  * Other paths will be set to defaults based on it unless they are directly
  * set in LocalSettings.php
  */
-$wgScriptPath       = '/wiki';
+$wgScriptPath = '/wiki';
 
 /**
  * Whether to support URLs like index.php/Page_title These often break when PHP
@@ -123,9 +123,9 @@ $wgScriptPath       = '/wiki';
  * redirect loops when "pretty URLs" are used.
  */
 $wgUsePathInfo =
-       ( strpos( php_sapi_name(), 'cgi' ) === false ) &&
-       ( strpos( php_sapi_name(), 'apache2filter' ) === false ) &&
-       ( strpos( php_sapi_name(), 'isapi' ) === false );
+       ( strpos( PHP_SAPI, 'cgi' ) === false ) &&
+       ( strpos( PHP_SAPI, 'apache2filter' ) === false ) &&
+       ( strpos( PHP_SAPI, 'isapi' ) === false );
 
 /**
  * The extension to append to script names by default. This can either be .php
@@ -134,7 +134,7 @@ $wgUsePathInfo =
  * Some hosting providers use PHP 4 for *.php files, and PHP 5 for *.php5. This
  * variable is provided to support those providers.
  */
-$wgScriptExtension  = '.php';
+$wgScriptExtension = '.php';
 
 
 /**@}*/
@@ -438,14 +438,34 @@ $wgUseInstantCommons = false;
 
 /**
  * File backend structure configuration.
+ *
  * This is an array of file backend configuration arrays.
  * Each backend configuration has the following parameters:
- *  - 'name'        : A unique name for the backend
- *  - 'class'       : The file backend class to use
- *  - 'wikiId'      : A unique string that identifies the wiki (container prefix)
- *  - 'lockManager' : The name of a lock manager (see $wgLockManagers)
- *
- * Additional parameters are specific to the class used.
+ *  - 'name'         : A unique name for the backend
+ *  - 'class'        : The file backend class to use
+ *  - 'wikiId'       : A unique string that identifies the wiki (container prefix)
+ *  - 'lockManager'  : The name of a lock manager (see $wgLockManagers)
+ *
+ * See FileBackend::__construct() for more details.
+ * Additional parameters are specific to the file backend class used.
+ * These settings should be global to all wikis when possible.
+ *
+ * There are two particularly important aspects about each backend:
+ *   - a) Whether it is fully qualified or wiki-relative.
+ *        By default, the paths of files are relative to the current wiki,
+ *        which works via prefixing them with the current wiki ID when accessed.
+ *        Setting 'wikiId' forces the backend to be fully qualified by prefixing
+ *        all paths with the specified value instead. This can be useful if
+ *        multiple wikis need to share the same data. Note that 'name' is *not*
+ *        part of any prefix and thus should not be relied upon for namespacing.
+ *   - b) Whether it is only defined for some wikis or is defined on all
+ *        wikis in the wiki farm. Defining a backend globally is useful
+ *        if multiple wikis need to share the same data.
+ * One should be aware of these aspects when configuring a backend for use with
+ * any basic feature or plugin. For example, suppose an extension stores data for
+ * different wikis in different directories and sometimes needs to access data from
+ * a foreign wiki's directory in order to render a page on given wiki. The extension
+ * would need a fully qualified backend that is defined on all wikis in the wiki farm.
  */
 $wgFileBackends = array();
 
@@ -455,6 +475,7 @@ $wgFileBackends = array();
  *  - 'name'        : A unique name for the lock manager
  *  - 'class'       : The lock manger class to use
  * Additional parameters are specific to the class used.
+ * These settings should be global to all wikis.
  */
 $wgLockManagers = array();
 
@@ -562,7 +583,7 @@ $wgCopyUploadProxy = false;
  * will have a maximum of 500 kB.
  *
  */
-$wgMaxUploadSize = 1024*1024*100; # 100MB
+$wgMaxUploadSize = 1024 * 1024 * 100; # 100MB
 
 /**
  * Point the upload navigation link to an external URL
@@ -663,7 +684,7 @@ $wgFileBlacklist = array(
  */
 $wgMimeTypeBlacklist = array(
        # HTML may contain cookie-stealing JavaScript and web bugs
-       'text/html', 'text/javascript', 'text/x-javascript',  'application/x-shellscript',
+       'text/html', 'text/javascript', 'text/x-javascript', 'application/x-shellscript',
        # PHP scripts may execute arbitrary code on the server
        'application/x-php', 'text/x-php',
        # Other types that may be interpreted by some servers
@@ -721,10 +742,10 @@ $wgUploadSizeWarning = false;
  */
 $wgTrustedMediaFormats = array(
        MEDIATYPE_BITMAP, //all bitmap formats
-       MEDIATYPE_AUDIO,  //all audio formats
-       MEDIATYPE_VIDEO,  //all plain video formats
-       "image/svg+xml",  //svg (only needed if inline rendering of svg is not supported)
-       "application/pdf",  //PDF files
+       MEDIATYPE_AUDIO, //all audio formats
+       MEDIATYPE_VIDEO, //all plain video formats
+       "image/svg+xml", //svg (only needed if inline rendering of svg is not supported)
+       "application/pdf", //PDF files
        #"application/x-shockwave-flash", //flash/shockwave movie
 );
 
@@ -733,18 +754,18 @@ $wgTrustedMediaFormats = array(
  * Each entry in the array maps a MIME type to a class name
  */
 $wgMediaHandlers = array(
-       'image/jpeg'     => 'JpegHandler',
-       'image/png'      => 'PNGHandler',
-       'image/gif'      => 'GIFHandler',
-       'image/tiff'     => 'TiffHandler',
+       'image/jpeg' => 'JpegHandler',
+       'image/png' => 'PNGHandler',
+       'image/gif' => 'GIFHandler',
+       'image/tiff' => 'TiffHandler',
        'image/x-ms-bmp' => 'BmpHandler',
-       'image/x-bmp'    => 'BmpHandler',
-       'image/x-xcf'    => 'XCFHandler',
-       'image/svg+xml'  => 'SvgHandler', // official
-       'image/svg'      => 'SvgHandler', // compat
+       'image/x-bmp' => 'BmpHandler',
+       'image/x-xcf' => 'XCFHandler',
+       'image/svg+xml' => 'SvgHandler', // official
+       'image/svg' => 'SvgHandler', // compat
        'image/vnd.djvu' => 'DjVuHandler', // official
-       'image/x.djvu'   => 'DjVuHandler', // compat
-       'image/x-djvu'   => 'DjVuHandler', // compat
+       'image/x.djvu' => 'DjVuHandler', // compat
+       'image/x-djvu' => 'DjVuHandler', // compat
 );
 
 /**
@@ -827,7 +848,7 @@ $wgSVGConverters = array(
        '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' ),
-       );
+);
 
 /** Pick a converter defined in $wgSVGConverters */
 $wgSVGConverter = 'ImageMagick';
@@ -890,7 +911,7 @@ $wgMaxAnimatedGifArea = 1.25e7;
  *  $wgTiffThumbnailType = array( 'jpg', 'image/jpeg' );
  * @endcode
  */
- $wgTiffThumbnailType = false;
+$wgTiffThumbnailType = false;
 
 /**
  * If rendered thumbnail files are older than this timestamp, they
@@ -923,8 +944,8 @@ $wgIgnoreImageErrors = false;
 $wgGenerateThumbnailOnParse = true;
 
 /**
-* Show thumbnails for old images on the image description page
-*/
+ * Show thumbnails for old images on the image description page
+ */
 $wgShowArchiveThumbnails = true;
 
 /** Obsolete, always true, kept for compatibility with extensions */
@@ -981,16 +1002,14 @@ $wgAntivirus = null;
 $wgAntivirusSetup = array(
 
        #setup for clamav
-       'clamav' => array (
+       'clamav' => array(
                'command' => "clamscan --no-summary ",
-
-               'codemap' => array (
-                       "0" =>  AV_NO_VIRUS, # no virus
-                       "1" =>  AV_VIRUS_FOUND, # virus found
+               'codemap' => array(
+                       "0" => AV_NO_VIRUS, # no virus
+                       "1" => AV_VIRUS_FOUND, # virus found
                        "52" => AV_SCAN_ABORTED, # unsupported file format (probably imune)
-                       "*" =>  AV_SCAN_FAILED, # else scan failed
+                       "*" => AV_SCAN_FAILED, # else scan failed
                ),
-
                'messagepattern' => '/.*?:(.*)/sim',
        ),
 );
@@ -1008,7 +1027,7 @@ $wgMimeTypeFile = "includes/mime.types";
 #$wgMimeTypeFile= null; #use built-in defaults only.
 
 /** Sets the mime type info file to use by MimeMagic.php. */
-$wgMimeInfoFile= "includes/mime.info";
+$wgMimeInfoFile = "includes/mime.info";
 #$wgMimeInfoFile= null; #use built-in defaults only.
 
 /**
@@ -1042,11 +1061,11 @@ $wgTrivialMimeDetection = false;
  * array = ( 'rootElement' => 'associatedMimeType' )
  */
 $wgXMLMimeTypes = array(
-       'http://www.w3.org/2000/svg:svg'               => 'image/svg+xml',
-       'svg'                                          => 'image/svg+xml',
+       'http://www.w3.org/2000/svg:svg' => 'image/svg+xml',
+       'svg' => 'image/svg+xml',
        'http://www.lysator.liu.se/~alla/dia/:diagram' => 'application/x-dia-diagram',
-       'http://www.w3.org/1999/xhtml:html'            => 'text/html', // application/xhtml+xml?
-       'html'                                         => 'text/html', // application/xhtml+xml?
+       'http://www.w3.org/1999/xhtml:html' => 'text/html', // application/xhtml+xml?
+       'html' => 'text/html', // application/xhtml+xml?
 );
 
 /**
@@ -1082,7 +1101,7 @@ $wgThumbLimits = array(
 /**
  * Default parameters for the "<gallery>" tag
  */
-$wgGalleryOptions = array (
+$wgGalleryOptions = array(
        'imagesPerRow' => 0, // Default number of images per-row in the gallery. 0 -> Adapt to screensize
        'imageWidth' => 120, // Width of the cells containing images in galleries (in "px")
        'imageHeight' => 120, // Height of the cells containing images in galleries (in "px")
@@ -1247,12 +1266,12 @@ $wgUserEmailConfirmationTokenExpiry = 7 * 24 * 60 * 60;
  *
  * @code
  * $wgSMTP = array(
- *     'host'     => 'SMTP domain',
- *     'IDHost'   => 'domain for MessageID',
- *     'port'     => '25',
- *     'auth'     => [true|false],
- *     'username' => [SMTP username],
- *     'password' => [SMTP password],
+ *     'host'     => 'SMTP domain',
+ *     'IDHost'   => 'domain for MessageID',
+ *     'port'     => '25',
+ *     'auth'     => [true|false],
+ *     'username' => [SMTP username],
+ *     'password' => [SMTP password],
  * );
  * @endcode
  */
@@ -1606,7 +1625,7 @@ $wgExternalStores = false;
  * Create a cluster named 'cluster1' containing three servers:
  * @code
  * $wgExternalServers = array(
- *     'cluster1' => array( 'srv28', 'srv29', 'srv30' )
+ *     'cluster1' => array( 'srv28', 'srv29', 'srv30' )
  * );
  * @endcode
  *
@@ -2168,7 +2187,21 @@ $wgUsePrivateIPs = false;
  * @{
  */
 
-/** Site language code, should be one of ./languages/Language(.*).php */
+/**
+ * Site language code. See languages/Names.php for languages supported by
+ * MediaWiki out of the box. Not all languages listed there have translations,
+ * see languages/messages/ for the list of languages with some localisation.
+ *
+ * Warning: Don't use language codes listed in $wgDummyLanguageCodes like "no"
+ * for Norwegian (use "nb" instead), or things will break unexpectedly.
+ *
+ * This defines the default interface language for all users, but users can
+ * change it in their preferences.
+ *
+ * This also defines the language of pages in the wiki. The content is wrapped
+ * in a html element with lang=XX attribute. This behaviour can be overriden
+ * via hooks, see Title::getPageLanguage.
+ */
 $wgLanguageCode = 'en';
 
 /**
@@ -2331,16 +2364,11 @@ $wgBrowserBlackList = array(
  */
 $wgLegacySchemaConversion = false;
 
-/**
- * Enable to allow rewriting dates in page text.
- * DOES NOT FORMAT CORRECTLY FOR MOST LANGUAGES.
- */
-$wgUseDynamicDates  = false;
 /**
  * Enable dates like 'May 12' instead of '12 May', this only takes effect if
  * the interface is set to English.
  */
-$wgAmericanDates    = false;
+$wgAmericanDates = false;
 /**
  * For Hindi and Arabic use local numerals instead of Western style (0-9)
  * numerals in interface.
@@ -2393,9 +2421,9 @@ $wgDisabledVariants = array();
  *
  * @par Example:
  * @code
- *     $wgLanguageCode = 'sr';
- *     $wgVariantArticlePath = '/$2/$1';
- *     $wgArticlePath = '/wiki/$1';
+ *     $wgLanguageCode = 'sr';
+ *     $wgVariantArticlePath = '/$2/$1';
+ *     $wgArticlePath = '/wiki/$1';
  * @endcode
  *
  * A link to /wiki/ would be redirected to /sr/Главна_страна
@@ -2428,7 +2456,7 @@ $wgLoginLanguageSelector = false;
  * To allow language-specific main page and community
  * portal:
  * @code
- *     $wgForceUIMsgAsContentMsg = array( 'mainpage', 'portal-url' );
+ *     $wgForceUIMsgAsContentMsg = array( 'mainpage', 'portal-url' );
  * @endcode
  */
 $wgForceUIMsgAsContentMsg = array();
@@ -2962,21 +2990,21 @@ $wgPreloadJavaScriptMwUtil = false;
  *
  * @par Example of legacy code:
  * @code{,js}
- *     if ( window.wgRestrictionEdit ) { ... }
+ *     if ( window.wgRestrictionEdit ) { ... }
  * @endcode
  * or:
  * @code{,js}
- *     if ( wgIsArticle ) { ... }
+ *     if ( wgIsArticle ) { ... }
  * @endcode
  *
  * Instead, one needs to use mw.config.
  * @par Example using mw.config global configuration:
  * @code{,js}
- *     if ( mw.config.exists('wgRestrictionEdit') ) { ... }
+ *     if ( mw.config.exists('wgRestrictionEdit') ) { ... }
  * @endcode
  * or:
  * @code{,js}
- *     if ( mw.config.get('wgIsArticle') ) { ... }
+ *     if ( mw.config.get('wgIsArticle') ) { ... }
  * @endcode
  */
 $wgLegacyJavaScriptGlobals = true;
@@ -3157,13 +3185,13 @@ $wgInterwikiExpiry = 10800;
 $wgInterwikiCache = false;
 /**
  * Specify number of domains to check for messages.
- *     - 1: Just wiki(db)-level
- *     - 2: wiki and global levels
- *     - 3: site levels
+ *    - 1: Just wiki(db)-level
+ *    - 2: wiki and global levels
+ *    - 3: site levels
  */
 $wgInterwikiScopes = 3;
 /**
- *     $wgInterwikiFallbackSite - if unable to resolve from cache
+ *    $wgInterwikiFallbackSite - if unable to resolve from cache
  */
 $wgInterwikiFallbackSite = 'wiki';
 /** @} */ # end of Interwiki caching settings.
@@ -3205,7 +3233,7 @@ $wgCapitalLinks = true;
  *
  * @par Example:
  * @code
- *     $wgCapitalLinkOverrides[ NS_FILE ] = false;
+ *     $wgCapitalLinkOverrides[ NS_FILE ] = false;
  * @endcode
  */
 $wgCapitalLinkOverrides = array();
@@ -3214,18 +3242,18 @@ $wgCapitalLinkOverrides = array();
  * See Language.php for a list of namespaces.
  */
 $wgNamespacesWithSubpages = array(
-       NS_TALK           => true,
-       NS_USER           => true,
-       NS_USER_TALK      => true,
-       NS_PROJECT        => true,
-       NS_PROJECT_TALK   => true,
-       NS_FILE_TALK      => true,
-       NS_MEDIAWIKI      => true,
+       NS_TALK => true,
+       NS_USER => true,
+       NS_USER_TALK => true,
+       NS_PROJECT => true,
+       NS_PROJECT_TALK => true,
+       NS_FILE_TALK => true,
+       NS_MEDIAWIKI => true,
        NS_MEDIAWIKI_TALK => true,
-       NS_TEMPLATE_TALK  => true,
-       NS_HELP           => true,
-       NS_HELP_TALK      => true,
-       NS_CATEGORY_TALK  => true
+       NS_TEMPLATE_TALK => true,
+       NS_HELP => true,
+       NS_HELP_TALK => true,
+       NS_CATEGORY_TALK => true
 );
 
 /**
@@ -3327,7 +3355,7 @@ $wgUrlProtocols = array(
        'https://',
        'ftp://',
        'irc://',
-       'ircs://',  // @bug 28503
+       'ircs://', // @bug 28503
        'gopher://',
        'telnet://', // Well if we're going to support the above.. -ævar
        'nntp://', // @bug 3808 RFC 1738
@@ -3403,7 +3431,7 @@ $wgAlwaysUseTidy = false;
 /** @see $wgUseTidy */
 $wgTidyBin = 'tidy';
 /** @see $wgUseTidy */
-$wgTidyConf = $IP.'/includes/tidy.conf';
+$wgTidyConf = $IP . '/includes/tidy.conf';
 /** @see $wgUseTidy */
 $wgTidyOpts = '';
 /** @see $wgUseTidy */
@@ -3599,68 +3627,68 @@ $wgReservedUsernames = array(
  *
  */
 $wgDefaultUserOptions = array(
-       'ccmeonemails'            => 0,
-       'cols'                    => 80,
-       'date'                    => 'default',
-       'diffonly'                => 0,
-       'disablemail'             => 0,
-       'disablesuggest'          => 0,
-       'editfont'                => 'default',
-       'editondblclick'          => 0,
-       'editsection'             => 1,
+       'ccmeonemails' => 0,
+       'cols' => 80,
+       'date' => 'default',
+       'diffonly' => 0,
+       'disablemail' => 0,
+       'disablesuggest' => 0,
+       'editfont' => 'default',
+       'editondblclick' => 0,
+       'editsection' => 1,
        'editsectiononrightclick' => 0,
-       'enotifminoredits'        => 0,
-       'enotifrevealaddr'        => 0,
-       'enotifusertalkpages'     => 1,
-       'enotifwatchlistpages'    => 0,
-       'extendwatchlist'         => 0,
-       'externaldiff'            => 0,
-       'externaleditor'          => 0,
-       'fancysig'                => 0,
-       'forceeditsummary'        => 0,
-       'gender'                  => 'unknown',
-       'hideminor'               => 0,
-       'hidepatrolled'           => 0,
-       'imagesize'               => 2,
-       'justify'                 => 0,
-       'math'                    => 1,
-       'minordefault'            => 0,
-       'newpageshidepatrolled'   => 0,
-       'nocache'                 => 0,
-       'noconvertlink'           => 0,
-       'norollbackdiff'          => 0,
-       'numberheadings'          => 0,
-       'previewonfirst'          => 0,
-       'previewontop'            => 1,
-       'quickbar'                => 5,
-       'rcdays'                  => 7,
-       'rclimit'                 => 50,
-       'rememberpassword'        => 0,
-       'rows'                    => 25,
-       'searchlimit'             => 20,
-       'showhiddencats'          => 0,
-       'showjumplinks'           => 1,
-       'shownumberswatching'     => 1,
-       'showtoc'                 => 1,
-       'showtoolbar'             => 1,
-       'skin'                    => false,
-       'stubthreshold'           => 0,
-       'thumbsize'               => 2,
-       'underline'               => 2,
-       'uselivepreview'          => 0,
-       'usenewrc'                => 0,
-       'watchcreations'          => 0,
-       'watchdefault'            => 0,
-       'watchdeletion'           => 0,
-       'watchlistdays'           => 3.0,
-       'watchlisthideanons'      => 0,
-       'watchlisthidebots'       => 0,
-       'watchlisthideliu'        => 0,
-       'watchlisthideminor'      => 0,
-       'watchlisthideown'        => 0,
-       'watchlisthidepatrolled'  => 0,
-       'watchmoves'              => 0,
-       'wllimit'                 => 250,
+       'enotifminoredits' => 0,
+       'enotifrevealaddr' => 0,
+       'enotifusertalkpages' => 1,
+       'enotifwatchlistpages' => 0,
+       'extendwatchlist' => 0,
+       'externaldiff' => 0,
+       'externaleditor' => 0,
+       'fancysig' => 0,
+       'forceeditsummary' => 0,
+       'gender' => 'unknown',
+       'hideminor' => 0,
+       'hidepatrolled' => 0,
+       'imagesize' => 2,
+       'justify' => 0,
+       'math' => 1,
+       'minordefault' => 0,
+       'newpageshidepatrolled' => 0,
+       'nocache' => 0,
+       'noconvertlink' => 0,
+       'norollbackdiff' => 0,
+       'numberheadings' => 0,
+       'previewonfirst' => 0,
+       'previewontop' => 1,
+       'quickbar' => 5,
+       'rcdays' => 7,
+       'rclimit' => 50,
+       'rememberpassword' => 0,
+       'rows' => 25,
+       'searchlimit' => 20,
+       'showhiddencats' => 0,
+       'showjumplinks' => 1,
+       'shownumberswatching' => 1,
+       'showtoc' => 1,
+       'showtoolbar' => 1,
+       'skin' => false,
+       'stubthreshold' => 0,
+       'thumbsize' => 2,
+       'underline' => 2,
+       'uselivepreview' => 0,
+       'usenewrc' => 0,
+       'watchcreations' => 0,
+       'watchdefault' => 0,
+       'watchdeletion' => 0,
+       'watchlistdays' => 3.0,
+       'watchlisthideanons' => 0,
+       'watchlisthidebots' => 0,
+       'watchlisthideliu' => 0,
+       'watchlisthideminor' => 0,
+       'watchlisthideown' => 0,
+       'watchlisthidepatrolled' => 0,
+       'watchmoves' => 0,
+       'wllimit' => 250,
 );
 
 /** An array of preferences to not show for the user */
@@ -3749,6 +3777,13 @@ $wgAllowPrefChange = array();
  */
 $wgSecureLogin = false;
 
+/**
+ * By default, keep users logged in via HTTPS when $wgSecureLogin is also
+ * true. Users opt-out of HTTPS when they login by de-selecting the checkbox.
+ * @since 1.21
+ */
+$wgSecureLoginDefaultHTTPS = true;
+
 /** @} */ # end user accounts }
 
 /************************************************************************//**
@@ -3878,85 +3913,85 @@ $wgGroupPermissions = array();
 
 /** @cond file_level_code */
 // Implicit group for all visitors
-$wgGroupPermissions['*']['createaccount']    = true;
-$wgGroupPermissions['*']['read']             = true;
-$wgGroupPermissions['*']['edit']             = true;
-$wgGroupPermissions['*']['createpage']       = true;
-$wgGroupPermissions['*']['createtalk']       = true;
-$wgGroupPermissions['*']['writeapi']         = true;
+$wgGroupPermissions['*']['createaccount'] = true;
+$wgGroupPermissions['*']['read'] = true;
+$wgGroupPermissions['*']['edit'] = true;
+$wgGroupPermissions['*']['createpage'] = true;
+$wgGroupPermissions['*']['createtalk'] = true;
+$wgGroupPermissions['*']['writeapi'] = true;
 //$wgGroupPermissions['*']['patrolmarks']      = false; // let anons see what was patrolled
 
 // Implicit group for all logged-in accounts
-$wgGroupPermissions['user']['move']             = true;
-$wgGroupPermissions['user']['move-subpages']    = true;
+$wgGroupPermissions['user']['move'] = true;
+$wgGroupPermissions['user']['move-subpages'] = true;
 $wgGroupPermissions['user']['move-rootuserpages'] = true; // can move root userpages
-$wgGroupPermissions['user']['movefile']         = true;
-$wgGroupPermissions['user']['read']             = true;
-$wgGroupPermissions['user']['edit']             = true;
-$wgGroupPermissions['user']['createpage']       = true;
-$wgGroupPermissions['user']['createtalk']       = true;
-$wgGroupPermissions['user']['writeapi']         = true;
-$wgGroupPermissions['user']['upload']           = true;
-$wgGroupPermissions['user']['reupload']         = true;
-$wgGroupPermissions['user']['reupload-shared']  = true;
-$wgGroupPermissions['user']['minoredit']        = true;
-$wgGroupPermissions['user']['purge']            = true; // can use ?action=purge without clicking "ok"
-$wgGroupPermissions['user']['sendemail']        = true;
+$wgGroupPermissions['user']['movefile'] = true;
+$wgGroupPermissions['user']['read'] = true;
+$wgGroupPermissions['user']['edit'] = true;
+$wgGroupPermissions['user']['createpage'] = true;
+$wgGroupPermissions['user']['createtalk'] = true;
+$wgGroupPermissions['user']['writeapi'] = true;
+$wgGroupPermissions['user']['upload'] = true;
+$wgGroupPermissions['user']['reupload'] = true;
+$wgGroupPermissions['user']['reupload-shared'] = true;
+$wgGroupPermissions['user']['minoredit'] = true;
+$wgGroupPermissions['user']['purge'] = true; // can use ?action=purge without clicking "ok"
+$wgGroupPermissions['user']['sendemail'] = true;
 
 // Implicit group for accounts that pass $wgAutoConfirmAge
 $wgGroupPermissions['autoconfirmed']['autoconfirmed'] = true;
 
 // Users with bot privilege can have their edits hidden
 // from various log pages by default
-$wgGroupPermissions['bot']['bot']              = true;
-$wgGroupPermissions['bot']['autoconfirmed']    = true;
-$wgGroupPermissions['bot']['nominornewtalk']   = true;
-$wgGroupPermissions['bot']['autopatrol']       = true;
+$wgGroupPermissions['bot']['bot'] = true;
+$wgGroupPermissions['bot']['autoconfirmed'] = true;
+$wgGroupPermissions['bot']['nominornewtalk'] = true;
+$wgGroupPermissions['bot']['autopatrol'] = true;
 $wgGroupPermissions['bot']['suppressredirect'] = true;
-$wgGroupPermissions['bot']['apihighlimits']    = true;
-$wgGroupPermissions['bot']['writeapi']         = true;
+$wgGroupPermissions['bot']['apihighlimits'] = true;
+$wgGroupPermissions['bot']['writeapi'] = true;
 #$wgGroupPermissions['bot']['editprotected']    = true; // can edit all protected pages without cascade protection enabled
 
 // Most extra permission abilities go to this group
-$wgGroupPermissions['sysop']['block']            = true;
-$wgGroupPermissions['sysop']['createaccount']    = true;
-$wgGroupPermissions['sysop']['delete']           = true;
-$wgGroupPermissions['sysop']['bigdelete']        = true; // can be separately configured for pages with > $wgDeleteRevisionsLimit revs
-$wgGroupPermissions['sysop']['deletedhistory']   = true; // can view deleted history entries, but not see or restore the text
-$wgGroupPermissions['sysop']['deletedtext']      = true; // can view deleted revision text
-$wgGroupPermissions['sysop']['undelete']         = true;
-$wgGroupPermissions['sysop']['editinterface']    = true;
-$wgGroupPermissions['sysop']['editusercss']      = true;
-$wgGroupPermissions['sysop']['edituserjs']       = true;
-$wgGroupPermissions['sysop']['import']           = true;
-$wgGroupPermissions['sysop']['importupload']     = true;
-$wgGroupPermissions['sysop']['move']             = true;
-$wgGroupPermissions['sysop']['move-subpages']    = true;
+$wgGroupPermissions['sysop']['block'] = true;
+$wgGroupPermissions['sysop']['createaccount'] = true;
+$wgGroupPermissions['sysop']['delete'] = true;
+$wgGroupPermissions['sysop']['bigdelete'] = true; // can be separately configured for pages with > $wgDeleteRevisionsLimit revs
+$wgGroupPermissions['sysop']['deletedhistory'] = true; // can view deleted history entries, but not see or restore the text
+$wgGroupPermissions['sysop']['deletedtext'] = true; // can view deleted revision text
+$wgGroupPermissions['sysop']['undelete'] = true;
+$wgGroupPermissions['sysop']['editinterface'] = true;
+$wgGroupPermissions['sysop']['editusercss'] = true;
+$wgGroupPermissions['sysop']['edituserjs'] = true;
+$wgGroupPermissions['sysop']['import'] = true;
+$wgGroupPermissions['sysop']['importupload'] = true;
+$wgGroupPermissions['sysop']['move'] = true;
+$wgGroupPermissions['sysop']['move-subpages'] = true;
 $wgGroupPermissions['sysop']['move-rootuserpages'] = true;
-$wgGroupPermissions['sysop']['patrol']           = true;
-$wgGroupPermissions['sysop']['autopatrol']       = true;
-$wgGroupPermissions['sysop']['protect']          = true;
-$wgGroupPermissions['sysop']['proxyunbannable']  = true;
-$wgGroupPermissions['sysop']['rollback']         = true;
-$wgGroupPermissions['sysop']['upload']           = true;
-$wgGroupPermissions['sysop']['reupload']         = true;
-$wgGroupPermissions['sysop']['reupload-shared']  = true;
-$wgGroupPermissions['sysop']['unwatchedpages']   = true;
-$wgGroupPermissions['sysop']['autoconfirmed']    = true;
-$wgGroupPermissions['sysop']['ipblock-exempt']   = true;
-$wgGroupPermissions['sysop']['blockemail']       = true;
-$wgGroupPermissions['sysop']['markbotedits']     = true;
-$wgGroupPermissions['sysop']['apihighlimits']    = true;
-$wgGroupPermissions['sysop']['browsearchive']    = true;
-$wgGroupPermissions['sysop']['noratelimit']      = true;
-$wgGroupPermissions['sysop']['movefile']         = true;
-$wgGroupPermissions['sysop']['unblockself']      = true;
+$wgGroupPermissions['sysop']['patrol'] = true;
+$wgGroupPermissions['sysop']['autopatrol'] = true;
+$wgGroupPermissions['sysop']['protect'] = true;
+$wgGroupPermissions['sysop']['proxyunbannable'] = true;
+$wgGroupPermissions['sysop']['rollback'] = true;
+$wgGroupPermissions['sysop']['upload'] = true;
+$wgGroupPermissions['sysop']['reupload'] = true;
+$wgGroupPermissions['sysop']['reupload-shared'] = true;
+$wgGroupPermissions['sysop']['unwatchedpages'] = true;
+$wgGroupPermissions['sysop']['autoconfirmed'] = true;
+$wgGroupPermissions['sysop']['ipblock-exempt'] = true;
+$wgGroupPermissions['sysop']['blockemail'] = true;
+$wgGroupPermissions['sysop']['markbotedits'] = true;
+$wgGroupPermissions['sysop']['apihighlimits'] = true;
+$wgGroupPermissions['sysop']['browsearchive'] = true;
+$wgGroupPermissions['sysop']['noratelimit'] = true;
+$wgGroupPermissions['sysop']['movefile'] = true;
+$wgGroupPermissions['sysop']['unblockself'] = true;
 $wgGroupPermissions['sysop']['suppressredirect'] = true;
 #$wgGroupPermissions['sysop']['upload_by_url']    = true;
 #$wgGroupPermissions['sysop']['mergehistory']     = true;
 
 // Permission to change users' group assignments
-$wgGroupPermissions['bureaucrat']['userrights']  = true;
+$wgGroupPermissions['bureaucrat']['userrights'] = true;
 $wgGroupPermissions['bureaucrat']['noratelimit'] = true;
 // Permission to change users' groups assignments across wikis
 #$wgGroupPermissions['bureaucrat']['userrights-interwiki'] = true;
@@ -4137,11 +4172,11 @@ $wgAutopromote = array(
  *
  * The format is:
  * @code
- *     array( event => criteria, ... )
+ *    array( event => criteria, ... )
  * @endcode
  * Where event is either:
- *     - 'onEdit' (when user edits)
- *     - 'onView' (when user views the wiki)
+ *    - 'onEdit' (when user edits)
+ *    - 'onView' (when user views the wiki)
  *
  * Criteria has the same format as $wgAutopromote
  *
@@ -4200,7 +4235,8 @@ $wgDeleteRevisionsLimit = 0;
 /**
  * Number of accounts each IP address may create, 0 to disable.
  *
- * @warning Requires memcached */
+ * @warning Requires memcached
+ */
 $wgAccountCreationThrottle = 0;
 
 /**
@@ -4291,25 +4327,25 @@ $wgProxyWhitelist = array();
  */
 $wgRateLimits = array(
        'edit' => array(
-               'anon'   => null, // for any and all anonymous edits (aggregate)
-               'user'   => null, // for each logged-in user
+               'anon' => null, // for any and all anonymous edits (aggregate)
+               'user' => null, // for each logged-in user
                'newbie' => null, // for each recent (autoconfirmed) account; overrides 'user'
-               'ip'     => null, // for each anon and recent account
+               'ip' => null, // for each anon and recent account
                'subnet' => null, // ... with final octet removed
-               ),
+       ),
        'move' => array(
-               'user'   => null,
+               'user' => null,
                'newbie' => null,
-               'ip'     => null,
+               'ip' => null,
                'subnet' => null,
-               ),
+       ),
        'mailpassword' => array(
                'anon' => null,
-               ),
+       ),
        'emailuser' => array(
                'user' => null,
-               ),
-       );
+       ),
+);
 
 /**
  * Set to a filename to log rate limiter hits.
@@ -4394,7 +4430,7 @@ $wgProxyKey = false;
 /**
  * Default cookie expiration time. Setting to 0 makes all cookies session-only.
  */
-$wgCookieExpiration = 180*86400;
+$wgCookieExpiration = 180 * 86400;
 
 /**
  * Set to set an explicit domain on the login cookies eg, "justthis.domain.org"
@@ -4456,7 +4492,7 @@ $wgCacheVaryCookies = array();
 /** Override to customise the session name */
 $wgSessionName = false;
 
-/** @} */  # end of cookie settings }
+/** @} */ # end of cookie settings }
 
 /************************************************************************//**
  * @name   LaTeX (mathematical formulas)
@@ -4846,7 +4882,7 @@ $wgNamespacesToBeSearchedDefault = array(
  */
 $wgNamespacesToBeSearchedHelp = array(
        NS_PROJECT => true,
-       NS_HELP    => true,
+       NS_HELP => true,
 );
 
 /**
@@ -4873,10 +4909,10 @@ $wgDisableInternalSearch = false;
  * To forward to Google you'd have something like:
  * @code
  * $wgSearchForwardUrl =
- *     'http://www.google.com/search?q=$1' .
- *     '&domains=http://example.com' .
- *     '&sitesearch=http://example.com' .
- *     '&ie=utf-8&oe=utf-8';
+ *     'http://www.google.com/search?q=$1' .
+ *     '&domains=http://example.com' .
+ *     '&sitesearch=http://example.com' .
+ *     '&ie=utf-8&oe=utf-8';
  * @endcode
  */
 $wgSearchForwardUrl = null;
@@ -4980,7 +5016,7 @@ $wgUseAutomaticEditSummaries = true;
  * @cond file_level_code
  * Set $wgCommandLineMode if it's not set already, to avoid notices
  */
-if( !isset( $wgCommandLineMode ) ) {
+if ( !isset( $wgCommandLineMode ) ) {
        $wgCommandLineMode = false;
 }
 /** @endcond */
@@ -5037,8 +5073,8 @@ $wgUpgradeKey = false;
  * @since 1.20
  */
 $wgGitRepositoryViewers = array(
-    'https://gerrit.wikimedia.org/r/p/(.*)' => 'https://gerrit.wikimedia.org/r/gitweb?p=$1;h=%H',
-    'ssh://(?:[a-z0-9_]+@)?gerrit.wikimedia.org:29418/(.*)' => 'https://gerrit.wikimedia.org/r/gitweb?p=$1;h=%H',
+       'https://gerrit.wikimedia.org/r/p/(.*)' => 'https://gerrit.wikimedia.org/r/gitweb?p=$1;h=%H',
+       'ssh://(?:[a-z0-9_]+@)?gerrit.wikimedia.org:29418/(.*)' => 'https://gerrit.wikimedia.org/r/gitweb?p=$1;h=%H',
 );
 
 /** @} */ # End of maintenance }
@@ -5154,7 +5190,7 @@ $wgOverrideSiteFeed = array();
  * $wgOut->isSyndicated() is true.
  */
 $wgFeedClasses = array(
-       'rss'  => 'RSSFeed',
+       'rss' => 'RSSFeed',
        'atom' => 'AtomFeed',
 );
 
@@ -5311,8 +5347,8 @@ $wgExportAllowHistory = true;
 $wgExportMaxHistory = 0;
 
 /**
-* Return distinct author list (when not returning full history)
-*/
+ * Return distinct author list (when not returning full history)
+ */
 $wgExportAllowListContributors = false;
 
 /**
@@ -5329,13 +5365,13 @@ $wgExportAllowListContributors = false;
 $wgExportMaxLinkDepth = 0;
 
 /**
-* Whether to allow the "export all pages in namespace" option
-*/
+ * Whether to allow the "export all pages in namespace" option
+ */
 $wgExportFromNamespaces = false;
 
 /**
-* Whether to allow exporting the entire wiki into a single file
-*/
+ * Whether to allow exporting the entire wiki into a single file
+ */
 $wgExportAllowAll = false;
 
 /** @} */ # end of import/export }
@@ -5470,19 +5506,18 @@ $wgHooks = array();
  * can add to this to provide custom jobs
  */
 $wgJobClasses = array(
-       'refreshLinks'      => 'RefreshLinksJob',
-       'refreshLinks2'     => 'RefreshLinksJob2',
-       'htmlCacheUpdate'   => 'HTMLCacheUpdateJob',
+       'refreshLinks' => 'RefreshLinksJob',
+       'refreshLinks2' => 'RefreshLinksJob2',
+       'htmlCacheUpdate' => 'HTMLCacheUpdateJob',
        'html_cache_update' => 'HTMLCacheUpdateJob', // backwards-compatible
-       'sendMail'          => 'EmaillingJob',
-       'enotifNotify'      => 'EnotifNotifyJob',
+       'sendMail' => 'EmaillingJob',
+       'enotifNotify' => 'EnotifNotifyJob',
        'fixDoubleRedirect' => 'DoubleRedirectJob',
-       'uploadFromUrl'     => 'UploadFromUrlJob',
-       'null'              => 'NullJob'
+       'uploadFromUrl' => 'UploadFromUrlJob',
+       'null' => 'NullJob'
 );
 
 /**
-
  * Jobs that must be explicitly requested, i.e. aren't run by job runners unless
  * special flags are set. The values here are keys of $wgJobClasses.
  *
@@ -5654,16 +5689,16 @@ $wgFilterLogTypes = array(
  * where TYPE is your log type, yoy don't need to use this array.
  */
 $wgLogNames = array(
-       ''        => 'all-logs-page',
-       'block'   => 'blocklogpage',
+       '' => 'all-logs-page',
+       'block' => 'blocklogpage',
        'protect' => 'protectlogpage',
-       'rights'  => 'rightslog',
-       'delete'  => 'dellogpage',
-       'upload'  => 'uploadlogpage',
-       'move'    => 'movelogpage',
-       'import'  => 'importlogpage',
-       'patrol'  => 'patrol-log-page',
-       'merge'   => 'mergelog',
+       'rights' => 'rightslog',
+       'delete' => 'dellogpage',
+       'upload' => 'uploadlogpage',
+       'move' => 'movelogpage',
+       'import' => 'importlogpage',
+       'patrol' => 'patrol-log-page',
+       'merge' => 'mergelog',
        'suppress' => 'suppressionlog',
 );
 
@@ -5677,16 +5712,16 @@ $wgLogNames = array(
  * where TYPE is your log type, yoy don't need to use this array.
  */
 $wgLogHeaders = array(
-       ''        => 'alllogstext',
-       'block'   => 'blocklogtext',
+       '' => 'alllogstext',
+       'block' => 'blocklogtext',
        'protect' => 'protectlogtext',
-       'rights'  => 'rightslogtext',
-       'delete'  => 'dellogpagetext',
-       'upload'  => 'uploadlogpagetext',
-       'move'    => 'movelogpagetext',
-       'import'  => 'importlogpagetext',
-       'patrol'  => 'patrol-log-header',
-       'merge'   => 'mergelogpagetext',
+       'rights' => 'rightslogtext',
+       'delete' => 'dellogpagetext',
+       'upload' => 'uploadlogpagetext',
+       'move' => 'movelogpagetext',
+       'import' => 'importlogpagetext',
+       'patrol' => 'patrol-log-header',
+       'merge' => 'mergelogpagetext',
        'suppress' => 'suppressionlogtext',
 );
 
@@ -5697,21 +5732,21 @@ $wgLogHeaders = array(
  * Extensions with custom log types may add to this array.
  */
 $wgLogActions = array(
-       'block/block'        => 'blocklogentry',
-       'block/unblock'      => 'unblocklogentry',
-       'block/reblock'      => 'reblock-logentry',
-       'protect/protect'    => 'protectedarticle',
-       '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',
-       'suppress/block'     => 'blocklogentry',
-       'suppress/reblock'   => 'reblock-logentry',
+       'block/block' => 'blocklogentry',
+       'block/unblock' => 'unblocklogentry',
+       'block/reblock' => 'reblock-logentry',
+       'protect/protect' => 'protectedarticle',
+       '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',
+       'suppress/block' => 'blocklogentry',
+       'suppress/reblock' => 'reblock-logentry',
 );
 
 /**
@@ -5721,17 +5756,17 @@ $wgLogActions = array(
  * @see LogFormatter
  */
 $wgLogActionsHandlers = array(
-       'move/move'          => 'MoveLogFormatter',
-       'move/move_redir'    => 'MoveLogFormatter',
-       'delete/delete'      => 'DeleteLogFormatter',
-       'delete/restore'     => 'DeleteLogFormatter',
-       'delete/revision'    => 'DeleteLogFormatter',
-       'delete/event'       => 'DeleteLogFormatter',
-       'suppress/revision'  => 'DeleteLogFormatter',
-       'suppress/event'     => 'DeleteLogFormatter',
-       'suppress/delete'    => 'DeleteLogFormatter',
-       'patrol/patrol'      => 'PatrolLogFormatter',
-       'rights/rights'      => 'RightsLogFormatter',
+       'move/move' => 'MoveLogFormatter',
+       'move/move_redir' => 'MoveLogFormatter',
+       'delete/delete' => 'DeleteLogFormatter',
+       'delete/restore' => 'DeleteLogFormatter',
+       'delete/revision' => 'DeleteLogFormatter',
+       'delete/event' => 'DeleteLogFormatter',
+       'suppress/revision' => 'DeleteLogFormatter',
+       'suppress/event' => 'DeleteLogFormatter',
+       'suppress/delete' => 'DeleteLogFormatter',
+       'patrol/patrol' => 'PatrolLogFormatter',
+       'rights/rights' => 'RightsLogFormatter',
        'rights/autopromote' => 'RightsLogFormatter',
 );
 
@@ -5763,107 +5798,107 @@ $wgDisableQueryPageUpdate = false;
  * at Special:SpecialPages
  */
 $wgSpecialPageGroups = array(
-       'DoubleRedirects'           => 'maintenance',
-       'BrokenRedirects'           => 'maintenance',
-       'Lonelypages'               => 'maintenance',
-       'Uncategorizedpages'        => 'maintenance',
-       'Uncategorizedcategories'   => 'maintenance',
-       'Uncategorizedimages'       => 'maintenance',
-       'Uncategorizedtemplates'    => 'maintenance',
-       'Unusedcategories'          => 'maintenance',
-       'Unusedimages'              => 'maintenance',
-       'Protectedpages'            => 'maintenance',
-       'Protectedtitles'           => 'maintenance',
-       'Unusedtemplates'           => 'maintenance',
-       'Withoutinterwiki'          => 'maintenance',
-       'Longpages'                 => 'maintenance',
-       'Shortpages'                => 'maintenance',
-       'Ancientpages'              => 'maintenance',
-       'Deadendpages'              => 'maintenance',
-       'Wantedpages'               => 'maintenance',
-       'Wantedcategories'          => 'maintenance',
-       'Wantedfiles'               => 'maintenance',
-       'Wantedtemplates'           => 'maintenance',
-       'Unwatchedpages'            => 'maintenance',
-       'Fewestrevisions'           => 'maintenance',
-
-       'Userlogin'                 => 'login',
-       'Userlogout'                => 'login',
-       'CreateAccount'             => 'login',
-
-       'Recentchanges'             => 'changes',
-       'Recentchangeslinked'       => 'changes',
-       'Watchlist'                 => 'changes',
-       'Newimages'                 => 'changes',
-       'Newpages'                  => 'changes',
-       'Log'                       => 'changes',
-       'Tags'                      => 'changes',
-
-       'Upload'                    => 'media',
-       'Listfiles'                 => 'media',
-       'MIMEsearch'                => 'media',
-       'FileDuplicateSearch'       => 'media',
-       'Filepath'                  => 'media',
-
-       'Listusers'                 => 'users',
-       'Activeusers'               => 'users',
-       'Listgrouprights'           => 'users',
-       'BlockList'                 => 'users',
-       'Contributions'             => 'users',
-       'Emailuser'                 => 'users',
-       'Listadmins'                => 'users',
-       'Listbots'                  => 'users',
-       'Userrights'                => 'users',
-       'Block'                     => 'users',
-       'Unblock'                   => 'users',
-       'Preferences'               => 'users',
-       'ChangeEmail'               => 'users',
-       'ChangePassword'            => 'users',
-       'DeletedContributions'      => 'users',
-       'PasswordReset'             => 'users',
-
-       'Mostlinked'                => 'highuse',
-       'Mostlinkedcategories'      => 'highuse',
-       'Mostlinkedtemplates'       => 'highuse',
-       'Mostcategories'            => 'highuse',
-       'Mostimages'                => 'highuse',
-       'Mostinterwikis'            => 'highuse',
-       'Mostrevisions'             => 'highuse',
-
-       'Allpages'                  => 'pages',
-       'Prefixindex'               => 'pages',
-       'Listredirects'             => 'pages',
-       'Categories'                => 'pages',
-       'Disambiguations'           => 'pages',
-
-       'Randompage'                => 'redirects',
-       'Randomredirect'            => 'redirects',
-       'Mypage'                    => 'redirects',
-       'Mytalk'                    => 'redirects',
-       'Mycontributions'           => 'redirects',
-       'Search'                    => 'redirects',
-       'LinkSearch'                => 'redirects',
-
-       'ComparePages'              => 'pagetools',
-       'Movepage'                  => 'pagetools',
-       'MergeHistory'              => 'pagetools',
-       'Revisiondelete'            => 'pagetools',
-       'Undelete'                  => 'pagetools',
-       'Export'                    => 'pagetools',
-       'Import'                    => 'pagetools',
-       'Whatlinkshere'             => 'pagetools',
-
-       'Statistics'                => 'wiki',
-       'Version'                   => 'wiki',
-       'Lockdb'                    => 'wiki',
-       'Unlockdb'                  => 'wiki',
-       'Allmessages'               => 'wiki',
-       'Popularpages'              => 'wiki',
-
-       'Specialpages'              => 'other',
-       'Blockme'                   => 'other',
-       'Booksources'               => 'other',
-       'JavaScriptTest'            => 'other',
+       'DoubleRedirects' => 'maintenance',
+       'BrokenRedirects' => 'maintenance',
+       'Lonelypages' => 'maintenance',
+       'Uncategorizedpages' => 'maintenance',
+       'Uncategorizedcategories' => 'maintenance',
+       'Uncategorizedimages' => 'maintenance',
+       'Uncategorizedtemplates' => 'maintenance',
+       'Unusedcategories' => 'maintenance',
+       'Unusedimages' => 'maintenance',
+       'Protectedpages' => 'maintenance',
+       'Protectedtitles' => 'maintenance',
+       'Unusedtemplates' => 'maintenance',
+       'Withoutinterwiki' => 'maintenance',
+       'Longpages' => 'maintenance',
+       'Shortpages' => 'maintenance',
+       'Ancientpages' => 'maintenance',
+       'Deadendpages' => 'maintenance',
+       'Wantedpages' => 'maintenance',
+       'Wantedcategories' => 'maintenance',
+       'Wantedfiles' => 'maintenance',
+       'Wantedtemplates' => 'maintenance',
+       'Unwatchedpages' => 'maintenance',
+       'Fewestrevisions' => 'maintenance',
+
+       'Userlogin' => 'login',
+       'Userlogout' => 'login',
+       'CreateAccount' => 'login',
+
+       'Recentchanges' => 'changes',
+       'Recentchangeslinked' => 'changes',
+       'Watchlist' => 'changes',
+       'Newimages' => 'changes',
+       'Newpages' => 'changes',
+       'Log' => 'changes',
+       'Tags' => 'changes',
+
+       'Upload' => 'media',
+       'Listfiles' => 'media',
+       'MIMEsearch' => 'media',
+       'FileDuplicateSearch' => 'media',
+       'Filepath' => 'media',
+
+       'Listusers' => 'users',
+       'Activeusers' => 'users',
+       'Listgrouprights' => 'users',
+       'BlockList' => 'users',
+       'Contributions' => 'users',
+       'Emailuser' => 'users',
+       'Listadmins' => 'users',
+       'Listbots' => 'users',
+       'Userrights' => 'users',
+       'Block' => 'users',
+       'Unblock' => 'users',
+       'Preferences' => 'users',
+       'ChangeEmail' => 'users',
+       'ChangePassword' => 'users',
+       'DeletedContributions' => 'users',
+       'PasswordReset' => 'users',
+
+       'Mostlinked' => 'highuse',
+       'Mostlinkedcategories' => 'highuse',
+       'Mostlinkedtemplates' => 'highuse',
+       'Mostcategories' => 'highuse',
+       'Mostimages' => 'highuse',
+       'Mostinterwikis' => 'highuse',
+       'Mostrevisions' => 'highuse',
+
+       'Allpages' => 'pages',
+       'Prefixindex' => 'pages',
+       'Listredirects' => 'pages',
+       'Categories' => 'pages',
+       'Disambiguations' => 'pages',
+
+       'Randompage' => 'redirects',
+       'Randomredirect' => 'redirects',
+       'Mypage' => 'redirects',
+       'Mytalk' => 'redirects',
+       'Mycontributions' => 'redirects',
+       'Search' => 'redirects',
+       'LinkSearch' => 'redirects',
+
+       'ComparePages' => 'pagetools',
+       'Movepage' => 'pagetools',
+       'MergeHistory' => 'pagetools',
+       'Revisiondelete' => 'pagetools',
+       'Undelete' => 'pagetools',
+       'Export' => 'pagetools',
+       'Import' => 'pagetools',
+       'Whatlinkshere' => 'pagetools',
+
+       'Statistics' => 'wiki',
+       'Version' => 'wiki',
+       'Lockdb' => 'wiki',
+       'Unlockdb' => 'wiki',
+       'Allmessages' => 'wiki',
+       'Popularpages' => 'wiki',
+
+       'Specialpages' => 'other',
+       'Blockme' => 'other',
+       'Booksources' => 'other',
+       'JavaScriptTest' => 'other',
 );
 
 /** Whether or not to sort special pages in Special:Specialpages */
@@ -5900,24 +5935,24 @@ $wgMaxRedirectLinksRetrieved = 500;
  * Unsetting core actions will probably cause things to complain loudly.
  */
 $wgActions = array(
-       'credits'        => true,
-       'delete'         => true,
-       'edit'           => true,
-       'history'        => true,
-       'info'           => true,
-       'markpatrolled'  => true,
-       'protect'        => true,
-       'purge'          => true,
-       'raw'            => true,
-       'render'         => true,
-       'revert'         => true,
+       'credits' => true,
+       'delete' => true,
+       'edit' => true,
+       'history' => true,
+       'info' => true,
+       'markpatrolled' => true,
+       'protect' => true,
+       'purge' => true,
+       'raw' => true,
+       'render' => true,
+       'revert' => true,
        'revisiondelete' => true,
-       'rollback'       => true,
-       'submit'         => true,
-       'unprotect'      => true,
-       'unwatch'        => true,
-       'view'           => true,
-       'watch'          => true,
+       'rollback' => true,
+       'submit' => true,
+       'unprotect' => true,
+       'unwatch' => true,
+       'view' => true,
+       'watch' => true,
 );
 
 /**
@@ -5965,8 +6000,8 @@ $wgNamespaceRobotPolicies = array();
  * @par Example:
  * @code
  * $wgArticleRobotPolicies = array(
- *             'Main Page' => 'noindex,follow',
- *             'User:Bob' => 'index,follow',
+ *         'Main Page' => 'noindex,follow',
+ *         'User:Bob' => 'index,follow',
  * );
  * @endcode
  *
@@ -6077,7 +6112,7 @@ $wgAPIRequestLog = false;
 /**
  * Set the timeout for the API help text cache. If set to 0, caching disabled
  */
-$wgAPICacheHelpTimeout = 60*60;
+$wgAPICacheHelpTimeout = 60 * 60;
 
 /**
  * Enable AJAX framework
@@ -6119,10 +6154,10 @@ $wgAjaxLicensePreview = true;
  * @par Example:
  * @code
  * $wgCrossSiteAJAXdomains = array(
- *     'www.mediawiki.org',
- *     '*.wikipedia.org',
- *     '*.wikimedia.org',
- *     '*.wiktionary.org',
+ *     'www.mediawiki.org',
+ *     '*.wikipedia.org',
+ *     '*.wikimedia.org',
+ *     '*.wiktionary.org',
  * );
  * @endcode
  */
@@ -6165,6 +6200,31 @@ $wgMaxShellTime = 180;
  */
 $wgMaxShellWallClockTime = 180;
 
+/**
+ * Under Linux: a cgroup directory used to constrain memory usage of shell 
+ * commands. The directory must be writable by the user which runs MediaWiki.
+ *
+ * If specified, this is used instead of ulimit, which is inaccurate, and
+ * causes malloc() to return NULL, which exposes bugs in C applications, making
+ * them segfault or deadlock.
+ *
+ * A wrapper script will create a cgroup for each shell command that runs, as
+ * a subgroup of the specified cgroup. If the memory limit is exceeded, the 
+ * kernel will send a SIGKILL signal to a process in the subgroup.
+ *
+ * @par Example:
+ * @code
+ *    mkdir -p /sys/fs/cgroup/memory/mediawiki
+ *    mkdir -m 0777 /sys/fs/cgroup/memory/mediawiki/job
+ *    echo '$wgShellCgroup = "/sys/fs/cgroup/memory/mediawiki/job";' >> LocalSettings.php
+ * @endcode
+ *
+ * The reliability of cgroup cleanup can be improved by installing a 
+ * notify_on_release script in the root cgroup, see e.g.
+ * https://gerrit.wikimedia.org/r/#/c/40784
+ */
+$wgShellCgroup = false;
+
 /**
  * Executable path of the PHP cli binary (php/php5). Should be set up on install.
  */
@@ -6415,9 +6475,9 @@ $wgContentHandlerUseDB = false;
  * @since 1.21
  */
 $wgTextModelsToParse = array(
-       CONTENT_MODEL_WIKITEXT,    // Just for completeness, wikitext will always be parsed.
-       CONTENT_MODEL_JAVASCRIPT,  // Make categories etc work, people put them into comments.
-       CONTENT_MODEL_CSS,         // Make categories etc work, people put them into comments.
+       CONTENT_MODEL_WIKITEXT, // Just for completeness, wikitext will always be parsed.
+       CONTENT_MODEL_JAVASCRIPT, // Make categories etc work, people put them into comments.
+       CONTENT_MODEL_CSS, // Make categories etc work, people put them into comments.
 );
 
 /**
index 882f318..46a3773 100644 (file)
@@ -54,12 +54,12 @@ define( 'DBO_COMPRESS', 512 );
  */
 define( 'DB_SLAVE', -1 );     # Read from the slave (or only server)
 define( 'DB_MASTER', -2 );    # Write to master (or only server)
-define( 'DB_LAST', -3 );     # Whatever database was used last
 /**@}*/
 
 # Obsolete aliases
 define( 'DB_READ', -1 );
 define( 'DB_WRITE', -2 );
+define( 'DB_LAST', -3 ); # deprecated since 2008, usage throws exception
 
 
 /**@{
@@ -227,7 +227,7 @@ define( 'MW_SUPPORTS_RESOURCE_MODULES', 1 );
 define( 'OT_HTML', 1 );
 define( 'OT_WIKI', 2 );
 define( 'OT_PREPROCESS', 3 );
-define( 'OT_MSG' , 3 );  // b/c alias for OT_PREPROCESS
+define( 'OT_MSG', 3 );  // b/c alias for OT_PREPROCESS
 define( 'OT_PLAIN', 4 );
 /**@}*/
 
index 4d7b968..d48bd0b 100644 (file)
@@ -27,7 +27,7 @@
  */
 
 class DeprecatedGlobal extends StubObject {
-        // The m's are to stay consistent with parent class.
+       // The m's are to stay consistent with parent class.
        protected $mRealValue, $mVersion;
 
        function __construct( $name, $realValue, $version = false ) {
index 5b01ca5..4e3ea49 100644 (file)
@@ -546,8 +546,8 @@ class EditPage {
                        // Standard preference behaviour
                        return true;
                } elseif ( !$this->mTitle->exists() &&
-                 isset( $wgPreviewOnOpenNamespaces[$this->mTitle->getNamespace()] ) &&
-                 $wgPreviewOnOpenNamespaces[$this->mTitle->getNamespace()] )
+                       isset( $wgPreviewOnOpenNamespaces[$this->mTitle->getNamespace()] ) &&
+                       $wgPreviewOnOpenNamespaces[$this->mTitle->getNamespace()] )
                {
                        // Categories are special
                        return true;
@@ -1162,7 +1162,7 @@ class EditPage {
                                return false;
 
                        case self::AS_PARSE_ERROR:
-                               $wgOut->addWikiText( '<div class="error">' . $status->getWikiText() . '</div>');
+                               $wgOut->addWikiText( '<div class="error">' . $status->getWikiText() . '</div>' );
                                return true;
 
                        case self::AS_SUCCESS_NEW_ARTICLE:
@@ -2197,7 +2197,7 @@ class EditPage {
                        } 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() );
-                               $wgOut->addWikiText( '<div class="error">' . $msg->text() . '</div>');
+                               $wgOut->addWikiText( '<div class="error">' . $msg->text() . '</div>' );
                        }
                }
 
@@ -2616,7 +2616,7 @@ HTML
                                $this->showDiff();
                        } catch ( MWContentSerializationException $ex ) {
                                $msg = wfMessage( 'content-failed-to-parse', $this->contentModel, $this->contentFormat, $ex->getMessage() );
-                               $wgOut->addWikiText( '<div class="error">' . $msg->text() . '</div>');
+                               $wgOut->addWikiText( '<div class="error">' . $msg->text() . '</div>' );
                        }
                }
        }
@@ -2888,21 +2888,24 @@ HTML
                $dbr = wfGetDB( DB_SLAVE );
                $data = $dbr->selectRow(
                        array( 'logging', 'user' ),
-                       array( 'log_type',
-                                  'log_action',
-                                  'log_timestamp',
-                                  'log_user',
-                                  'log_namespace',
-                                  'log_title',
-                                  'log_comment',
-                                  'log_params',
-                                  'log_deleted',
-                                  'user_name' ),
-                       array( 'log_namespace' => $this->mTitle->getNamespace(),
-                                  'log_title' => $this->mTitle->getDBkey(),
-                                  'log_type' => 'delete',
-                                  'log_action' => 'delete',
-                                  'user_id=log_user' ),
+                       array(
+                               'log_type',
+                               'log_action',
+                               'log_timestamp',
+                               'log_user',
+                               'log_namespace',
+                               'log_title',
+                               'log_comment',
+                               'log_params',
+                               'log_deleted',
+                               'user_name'
+                       ), array(
+                               'log_namespace' => $this->mTitle->getNamespace(),
+                               'log_title' => $this->mTitle->getDBkey(),
+                               'log_type' => 'delete',
+                               'log_action' => 'delete',
+                               'user_id=log_user'
+                       ),
                        __METHOD__,
                        array( 'LIMIT' => 1, 'ORDER BY' => 'log_timestamp DESC' )
                );
@@ -2957,13 +2960,13 @@ HTML
 
                        if ( $this->mTriedSave && !$this->mTokenOk ) {
                                if ( $this->mTokenOkExceptSuffix ) {
-                                       $note = wfMessage( 'token_suffix_mismatch' )->plain() ;
+                                       $note = wfMessage( 'token_suffix_mismatch' )->plain();
 
                                } else {
-                                       $note = wfMessage( 'session_fail_preview' )->plain() ;
+                                       $note = wfMessage( 'session_fail_preview' )->plain();
                                }
                        } elseif ( $this->incompleteForm ) {
-                               $note = wfMessage( 'edit_form_incomplete' )->plain() ;
+                               $note = wfMessage( 'edit_form_incomplete' )->plain();
                        } else {
                                $note = wfMessage( 'previewnote' )->plain() .
                                        ' [[#' . self::EDITFORM_ID . '|' . $wgLang->getArrow() . ' ' . wfMessage( 'continue-editing' )->text() . ']]';
@@ -2972,7 +2975,7 @@ HTML
                        $parserOptions = $this->mArticle->makeParserOptions( $this->mArticle->getContext() );
                        $parserOptions->setEditSection( false );
                        $parserOptions->setIsPreview( true );
-                       $parserOptions->setIsSectionPreview( !is_null($this->section) && $this->section !== '' );
+                       $parserOptions->setIsSectionPreview( !is_null( $this->section ) && $this->section !== '' );
 
                        # don't parse non-wikitext pages, show message about preview
                        if ( $this->mTitle->isCssJsSubpage() || $this->mTitle->isCssOrJsPage() ) {
@@ -2995,7 +2998,7 @@ HTML
                                # Used messages to make sure grep find them:
                                # Messages: usercsspreview, userjspreview, sitecsspreview, sitejspreview
                                if( $level && $format ) {
-                                       $note = "<div id='mw-{$level}{$format}preview'>" . wfMessage( "{$level}{$format}preview" )->text()  . "</div>";
+                                       $note = "<div id='mw-{$level}{$format}preview'>" . wfMessage( "{$level}{$format}preview" )->text() . "</div>";
                                }
                        }
 
@@ -3031,7 +3034,7 @@ HTML
                                }
                        }
                } catch ( MWContentSerializationException $ex ) {
-                       $m = wfMessage('content-failed-to-parse', $this->contentModel, $this->contentFormat, $ex->getMessage() );
+                       $m = wfMessage( 'content-failed-to-parse', $this->contentModel, $this->contentFormat, $ex->getMessage() );
                        $note .= "\n\n" . $m->parse();
                        $previewHTML = '';
                }
index 7000119..81d1a9b 100644 (file)
@@ -262,7 +262,7 @@ class MWException extends Exception {
                if ( defined( 'MW_API' ) ) {
                        // Unhandled API exception, we can't be sure that format printer is alive
                        header( 'MediaWiki-API-Error: internal_api_error_' . get_class( $this ) );
-                       wfHttpError(500, 'Internal Server Error', $this->getText() );
+                       wfHttpError( 500, 'Internal Server Error', $this->getText() );
                } elseif ( self::isCommandLine() ) {
                        MWExceptionHandler::printError( $this->getText() );
                } else {
@@ -536,7 +536,7 @@ class UserNotLoggedIn extends ErrorPageError {
         */
        public function __construct(
                $reasonMsg = 'exception-nologin-text',
-               $titleMsg  = 'exception-nologin',
+               $titleMsg = 'exception-nologin',
                $params = null
        ) {
                parent::__construct( $titleMsg, $reasonMsg, $params );
@@ -567,14 +567,38 @@ class HttpError extends MWException {
                $this->content = $content;
        }
 
+       /**
+        * Returns the HTTP status code supplied to the constructor.
+        *
+        * @return int
+        */
+       public function getStatusCode() {
+               return $this->httpCode;
+       }
+
+       /**
+        * Report the HTTP error.
+        * Sends the appropriate HTTP status code and outputs an
+        * HTML page with an error message.
+        */
        public function report() {
                $httpMessage = HttpStatus::getMessage( $this->httpCode );
 
                header( "Status: {$this->httpCode} {$httpMessage}", true, $this->httpCode );
                header( 'Content-type: text/html; charset=utf-8' );
 
+               print $this->getHTML();
+       }
+
+       /**
+        * Returns HTML for reporting the HTTP error.
+        * This will be a minimal but complete HTML document.
+        *
+        * @return string HTML
+        */
+       public function getHTML() {
                if ( $this->header === null ) {
-                       $header = $httpMessage;
+                       $header = HttpStatus::getMessage( $this->httpCode );
                } elseif ( $this->header instanceof Message ) {
                        $header = $this->header->escaped();
                } else {
@@ -587,7 +611,7 @@ class HttpError extends MWException {
                        $content = htmlspecialchars( $this->content );
                }
 
-               print "<!DOCTYPE html>\n".
+               return "<!DOCTYPE html>\n".
                        "<html><head><title>$header</title></head>\n" .
                        "<body><h1>$header</h1><p>$content</p></body></html>\n";
        }
index 088a807..9248575 100644 (file)
@@ -31,8 +31,8 @@
  * @ingroup SpecialPage Dump
  */
 class WikiExporter {
-       var $list_authors = false ; # Return distinct author list (when not returning full history)
-       var $author_list = "" ;
+       var $list_authors = false; # Return distinct author list (when not returning full history)
+       var $author_list = "";
 
        var $dumpUploads = false;
        var $dumpUploadFileContents = false;
@@ -87,10 +87,10 @@ class WikiExporter {
                        $buffer = WikiExporter::BUFFER, $text = WikiExporter::TEXT ) {
                $this->db = $db;
                $this->history = $history;
-               $this->buffer  = $buffer;
-               $this->writer  = new XmlDumpWriter();
-               $this->sink    = new DumpOutput();
-               $this->text    = $text;
+               $this->buffer = $buffer;
+               $this->writer = new XmlDumpWriter();
+               $this->sink = new DumpOutput();
+               $this->text = $text;
        }
 
        /**
@@ -226,7 +226,7 @@ class WikiExporter {
                foreach ( $res as $row ) {
                        $this->author_list .= "<contributor>" .
                                "<username>" .
-                               htmlentities( $row->rev_user_text )  .
+                               htmlentities( $row->rev_user_text ) .
                                "</username>" .
                                "<id>" .
                                $row->rev_user .
@@ -634,7 +634,7 @@ class XmlDumpWriter {
        function writeRevision( $row ) {
                wfProfileIn( __METHOD__ );
 
-               $out  = "    <revision>\n";
+               $out = "    <revision>\n";
                $out .= "      " . Xml::element( 'id', null, strval( $row->rev_id ) ) . "\n";
                if( isset( $row->rev_parent_id ) && $row->rev_parent_id ) {
                        $out .= "      " . Xml::element( 'parentid', null, strval( $row->rev_parent_id ) ) . "\n";
@@ -674,12 +674,12 @@ class XmlDumpWriter {
                }
 
                if ( isset( $row->rev_sha1 ) && $row->rev_sha1 && !( $row->rev_deleted & Revision::DELETED_TEXT ) ) {
-                       $out .= "      " . Xml::element('sha1', null, strval( $row->rev_sha1 ) ) . "\n";
+                       $out .= "      " . Xml::element( 'sha1', null, strval( $row->rev_sha1 ) ) . "\n";
                } else {
                        $out .= "      <sha1/>\n";
                }
 
-               if ( isset( $row->rev_content_model ) && !is_null( $row->rev_content_model )  ) {
+               if ( isset( $row->rev_content_model ) && !is_null( $row->rev_content_model ) ) {
                        $content_model = strval( $row->rev_content_model );
                } else {
                        // probably using $wgContentHandlerUseDB = false;
@@ -688,7 +688,7 @@ class XmlDumpWriter {
                        $content_model = ContentHandler::getDefaultModelFor( $title );
                }
 
-               $out .= "      " . Xml::element('model', null, strval( $content_model ) ) . "\n";
+               $out .= "      " . Xml::element( 'model', null, strval( $content_model ) ) . "\n";
 
                if ( isset( $row->rev_content_format ) && !is_null( $row->rev_content_format ) ) {
                        $content_format = strval( $row->rev_content_format );
@@ -699,7 +699,7 @@ class XmlDumpWriter {
                        $content_format = $content_handler->getDefaultFormat();
                }
 
-               $out .= "      " . Xml::element('format', null, strval( $content_format ) ) . "\n";
+               $out .= "      " . Xml::element( 'format', null, strval( $content_format ) ) . "\n";
 
                wfRunHooks( 'XmlDumpWriterWriteRevision', array( &$this, &$out, $row, $text ) );
 
@@ -720,7 +720,7 @@ class XmlDumpWriter {
        function writeLogItem( $row ) {
                wfProfileIn( __METHOD__ );
 
-               $out  = "  <logitem>\n";
+               $out = "  <logitem>\n";
                $out .= "    " . Xml::element( 'id', null, strval( $row->log_id ) ) . "\n";
 
                $out .= $this->writeTimestamp( $row->log_timestamp, "    " );
@@ -940,7 +940,6 @@ class DumpOutput {
         * @param $newname mixed File name. May be a string or an array with one element
         */
        function closeRenameAndReopen( $newname ) {
-               return;
        }
 
        /**
@@ -951,7 +950,6 @@ class DumpOutput {
         * @param $open bool If true, a new file with the old filename will be opened again for writing (default: false)
         */
        function closeAndRename( $newname, $open = false ) {
-               return;
        }
 
        /**
@@ -960,7 +958,7 @@ class DumpOutput {
         * @return null
         */
        function getFilenames() {
-               return NULL;
+               return null;
        }
 }
 
@@ -1009,7 +1007,7 @@ class DumpFileOutput extends DumpOutput {
         * @throws MWException
         */
        function renameOrException( $newname ) {
-                       if (rename( $this->filename, $newname ) ) {
+                       if ( !rename( $this->filename, $newname ) ) {
                                throw new MWException( __METHOD__ . ": rename of file {$this->filename} to $newname failed\n" );
                        }
        }
@@ -1072,7 +1070,7 @@ class DumpPipeOutput extends DumpFileOutput {
         */
        function __construct( $command, $file = null ) {
                if ( !is_null( $file ) ) {
-                       $command .=  " > " . wfEscapeShellArg( $file );
+                       $command .= " > " . wfEscapeShellArg( $file );
                }
 
                $this->startCommand( $command );
@@ -1128,7 +1126,7 @@ class DumpPipeOutput extends DumpFileOutput {
                        $this->renameOrException( $newname );
                        if ( $open ) {
                                $command = $this->command;
-                               $command .=  " > " . wfEscapeShellArg( $this->filename );
+                               $command .= " > " . wfEscapeShellArg( $this->filename );
                                $this->startCommand( $command );
                        }
                }
@@ -1361,7 +1359,7 @@ class DumpNamespaceFilter extends DumpFilter {
                        "NS_PROJECT_TALK"   => NS_PROJECT_TALK,
                        "NS_FILE"           => NS_FILE,
                        "NS_FILE_TALK"      => NS_FILE_TALK,
-                       "NS_IMAGE"          => NS_IMAGE,  // NS_IMAGE is an alias for NS_FILE
+                       "NS_IMAGE"          => NS_IMAGE, // NS_IMAGE is an alias for NS_FILE
                        "NS_IMAGE_TALK"     => NS_IMAGE_TALK,
                        "NS_MEDIAWIKI"      => NS_MEDIAWIKI,
                        "NS_MEDIAWIKI_TALK" => NS_MEDIAWIKI_TALK,
@@ -1529,7 +1527,7 @@ class DumpMultiWriter {
        function getFilenames() {
                $filenames = array();
                for ( $i = 0; $i < $this->count; $i++ ) {
-                       $filenames[] =  $this->sinks[$i]->getFilenames();
+                       $filenames[] = $this->sinks[$i]->getFilenames();
                }
                return $filenames;
        }
index 82fe196..8cf9c84 100644 (file)
@@ -285,7 +285,7 @@ abstract class ExternalUser {
                $dbw->replace( 'external_user',
                        array( 'eu_local_id', 'eu_external_id' ),
                        array( 'eu_local_id' => $id,
-                                  'eu_external_id' => $this->getId() ),
+                               'eu_external_id' => $this->getId() ),
                        __METHOD__ );
        }
 
index 60f7600..efa213f 100644 (file)
@@ -114,9 +114,9 @@ class FakeTitle extends Title {
        function getParentCategories() { $this->error(); }
        function getParentCategoryTree( $children = array() ) { $this->error(); }
        function pageCond() { $this->error(); }
-       function getPreviousRevisionID( $revId, $flags=0 ) { $this->error(); }
-       function getNextRevisionID( $revId, $flags=0 ) { $this->error(); }
-       function getFirstRevision( $flags=0 ) { $this->error(); }
+       function getPreviousRevisionID( $revId, $flags = 0 ) { $this->error(); }
+       function getNextRevisionID( $revId, $flags = 0 ) { $this->error(); }
+       function getFirstRevision( $flags = 0 ) { $this->error(); }
        function isNewPage() { $this->error(); }
        function getEarliestRevTime( $flags = 0 ) { $this->error(); }
        function countRevisionsBetween( $old, $new ) { $this->error(); }
index f9dbf5b..8e000ae 100644 (file)
@@ -243,9 +243,9 @@ abstract class ChannelFeed extends FeedItem {
         */
        function contentType() {
                global $wgRequest;
-               $ctype = $wgRequest->getVal('ctype','application/xml');
-               $allowedctypes = array('application/xml','text/xml','application/rss+xml','application/atom+xml');
-               return (in_array($ctype, $allowedctypes) ? $ctype : 'application/xml');
+               $ctype = $wgRequest->getVal( 'ctype', 'application/xml' );
+               $allowedctypes = array( 'application/xml', 'text/xml', 'application/rss+xml', 'application/atom+xml' );
+               return (in_array( $ctype, $allowedctypes ) ? $ctype : 'application/xml');
        }
 
        /**
index 82c6e4a..67011d2 100644 (file)
@@ -39,7 +39,7 @@ class FeedUtils {
        public static function checkPurge( $timekey, $key ) {
                global $wgRequest, $wgUser, $messageMemc;
                $purge = $wgRequest->getVal( 'action' ) === 'purge';
-               if ( $purge && $wgUser->isAllowed('purge') ) {
+               if ( $purge && $wgUser->isAllowed( 'purge' ) ) {
                        $messageMemc->delete( $timekey );
                        $messageMemc->delete( $key );
                }
@@ -85,7 +85,7 @@ class FeedUtils {
                        $row->rc_last_oldid, $row->rc_this_oldid,
                        $timestamp,
                        ($row->rc_deleted & Revision::DELETED_COMMENT)
-                               ? wfMessage('rev-deleted-comment')->escaped()
+                               ? wfMessage( 'rev-deleted-comment' )->escaped()
                                : $row->rc_comment,
                        $actiontext
                );
@@ -102,7 +102,7 @@ class FeedUtils {
         * @param $actiontext String: text of the action; in case of log event
         * @return String
         */
-       public static function formatDiffRow( $title, $oldid, $newid, $timestamp, $comment, $actiontext='' ) {
+       public static function formatDiffRow( $title, $oldid, $newid, $timestamp, $comment, $actiontext = '' ) {
                global $wgFeedDiffCutoff, $wgLang;
                wfProfileIn( __METHOD__ );
 
@@ -222,7 +222,7 @@ class FeedUtils {
        protected static function getDiffLink( Title $title, $newid, $oldid = null ) {
                $queryParameters = ($oldid == null)
                        ? "diff={$newid}"
-                       : "diff={$newid}&oldid={$oldid}" ;
+                       : "diff={$newid}&oldid={$oldid}";
                $diffUrl = $title->getFullUrl( $queryParameters );
 
                $diffLink = Html::element( 'a', array( 'href' => $diffUrl ),
index e2fcd9c..48073f7 100644 (file)
@@ -80,13 +80,13 @@ class FileDeleteForm {
                $this->oldimage = $wgRequest->getText( 'oldimage', false );
                $token = $wgRequest->getText( 'wpEditToken' );
                # Flag to hide all contents of the archived revisions
-               $suppress = $wgRequest->getVal( 'wpSuppress' ) && $wgUser->isAllowed('suppressrevision');
+               $suppress = $wgRequest->getVal( 'wpSuppress' ) && $wgUser->isAllowed( 'suppressrevision' );
 
                if( $this->oldimage ) {
                        $this->oldfile = RepoGroup::singleton()->getLocalRepo()->newFromArchiveName( $this->title, $this->oldimage );
                }
 
-               if( !self::haveDeletableFile($this->file, $this->oldfile, $this->oldimage) ) {
+               if( !self::haveDeletableFile( $this->file, $this->oldfile, $this->oldimage ) ) {
                        $wgOut->addHTML( $this->prepareMessage( 'filedelete-nofile' ) );
                        $wgOut->addReturnTo( $this->title );
                        return;
@@ -344,7 +344,7 @@ class FileDeleteForm {
         *
         * @return bool
         */
-       public static function isValidOldSpec($oldimage) {
+       public static function isValidOldSpec( $oldimage ) {
                return strlen( $oldimage ) >= 16
                        && strpos( $oldimage, '/' ) === false
                        && strpos( $oldimage, '\\' ) === false;
@@ -360,7 +360,7 @@ class FileDeleteForm {
         * @param $oldimage File
         * @return bool
         */
-       public static function haveDeletableFile(&$file, &$oldfile, $oldimage) {
+       public static function haveDeletableFile( &$file, &$oldfile, $oldimage ) {
                return $oldimage
                        ? $oldfile && $oldfile->exists() && $oldfile->isLocal()
                        : $file && $file->exists() && $file->isLocal();
index 448bc03..89ad955 100644 (file)
@@ -53,7 +53,7 @@ class ForkController {
        const RESTART_ON_ERROR = 1;
 
        public function __construct( $numProcs, $flags = 0 ) {
-               if ( php_sapi_name() != 'cli' ) {
+               if ( PHP_SAPI != 'cli' ) {
                        throw new MWException( "ForkController cannot be used from the web." );
                }
                $this->procsToStart = $numProcs;
@@ -140,7 +140,7 @@ class ForkController {
                // Don't share DB, storage, or memcached connections
                wfGetLBFactory()->destroyInstance();
                FileBackendGroup::destroySingleton();
-               LockManagerGroup::destroySingleton();
+               LockManagerGroup::destroySingletons();
                ObjectCache::clear();
                $wgMemc = null;
        }
index 2292e31..3fa816f 100644 (file)
@@ -50,7 +50,7 @@ if ( !function_exists( 'mb_substr' ) ) {
         * @codeCoverageIgnore
         * @return string
         */
-       function mb_substr( $str, $start, $count='end' ) {
+       function mb_substr( $str, $start, $count = 'end' ) {
                return Fallback::mb_substr( $str, $start, $count );
        }
 
@@ -392,7 +392,7 @@ function wfArrayToCgi( $array1, $array2 = null, $prefix = '' ) {
 
        $cgi = '';
        foreach ( $array1 as $key => $value ) {
-               if ( !is_null($value) && $value !== false ) {
+               if ( !is_null( $value ) && $value !== false ) {
                        if ( $cgi != '' ) {
                                $cgi .= '&';
                        }
@@ -2449,7 +2449,7 @@ function wfTimestamp( $outputtype = TS_UNIX, $ts = 0 ) {
                $timestamp = new MWTimestamp( $ts );
                return $timestamp->getTimestamp( $outputtype );
        } catch( TimestampException $e ) {
-               wfDebug("wfTimestamp() fed bogus time value: TYPE=$outputtype; VALUE=$ts\n");
+               wfDebug( "wfTimestamp() fed bogus time value: TYPE=$outputtype; VALUE=$ts\n" );
                return false;
        }
 }
@@ -2622,12 +2622,14 @@ function wfPercent( $nr, $acc = 2, $round = true ) {
 /**
  * Find out whether or not a mixed variable exists in a string
  *
+ * @deprecated Just use str(i)pos
  * @param $needle String
  * @param $str String
  * @param $insensitive Boolean
  * @return Boolean
  */
 function in_string( $needle, $str, $insensitive = false ) {
+       wfDeprecated( __METHOD__, '1.21' );
        $func = 'strpos';
        if( $insensitive ) $func = 'stripos';
 
@@ -2681,8 +2683,7 @@ function wfDl( $extension, $fileName = null ) {
        }
 
        $canDl = false;
-       $sapi = php_sapi_name();
-       if( $sapi == 'cli' || $sapi == 'cgi' || $sapi == 'embed' ) {
+       if( PHP_SAPI == 'cli' || PHP_SAPI == 'cgi' || PHP_SAPI == 'embed' ) {
                $canDl = ( function_exists( 'dl' ) && is_callable( 'dl' )
                && wfIniGetBool( 'enable_dl' ) && !wfIniGetBool( 'safe_mode' ) );
        }
@@ -2777,7 +2778,7 @@ function wfEscapeShellArg( ) {
  */
 function wfShellExec( $cmd, &$retval = null, $environ = array(), $limits = array() ) {
        global $IP, $wgMaxShellMemory, $wgMaxShellFileSize, $wgMaxShellTime,
-               $wgMaxShellWallClockTime;
+               $wgMaxShellWallClockTime, $wgShellCgroup;
 
        static $disabled;
        if ( is_null( $disabled ) ) {
@@ -2824,7 +2825,7 @@ function wfShellExec( $cmd, &$retval = null, $environ = array(), $limits = array
        $cmd = $envcmd . $cmd;
 
        if ( php_uname( 's' ) == 'Linux' ) {
-               $time = intval ( isset($limits['time']) ? $limits['time'] : $wgMaxShellTime );
+               $time = intval ( isset( $limits['time'] ) ? $limits['time'] : $wgMaxShellTime );
                if ( isset( $limits['walltime'] ) ) {
                        $wallTime = intval( $limits['walltime'] );
                } elseif ( isset( $limits['time'] ) ) {
@@ -2832,12 +2833,19 @@ function wfShellExec( $cmd, &$retval = null, $environ = array(), $limits = array
                } else {
                        $wallTime = intval( $wgMaxShellWallClockTime );
                }
-               $mem = intval ( isset($limits['memory']) ? $limits['memory'] : $wgMaxShellMemory );
-               $filesize = intval ( isset($limits['filesize']) ? $limits['filesize'] : $wgMaxShellFileSize );
+               $mem = intval ( isset( $limits['memory'] ) ? $limits['memory'] : $wgMaxShellMemory );
+               $filesize = intval ( isset( $limits['filesize'] ) ? $limits['filesize'] : $wgMaxShellFileSize );
 
                if ( $time > 0 || $mem > 0 || $filesize > 0 || $wallTime > 0 ) {
-                       $cmd = '/bin/bash ' . escapeshellarg( "$IP/bin/ulimit5.sh" ) .
-                               " $time $mem $filesize $wallTime " . escapeshellarg( $cmd );
+                       $cmd = '/bin/bash ' . escapeshellarg( "$IP/includes/limit.sh" ) . ' ' .
+                               escapeshellarg( $cmd ) . ' ' .
+                               escapeshellarg(
+                                       "MW_CPU_LIMIT=$time; " .
+                                       'MW_CGROUP=' . escapeshellarg( $wgShellCgroup ) . '; ' .
+                                       "MW_MEM_LIMIT=$mem; " .
+                                       "MW_FILE_SIZE_LIMIT=$filesize; " .
+                                       "MW_WALL_CLOCK_LIMIT=$wallTime"
+                               );
                }
        }
        wfDebug( "wfShellExec: $cmd\n" );
index 952022f..86eb38d 100644 (file)
@@ -639,9 +639,9 @@ class HTMLForm extends ContextSource {
                        : 'application/x-www-form-urlencoded';
                # Attributes
                $attribs = array(
-                       'action'  => $this->mAction === false ? $this->getTitle()->getFullURL() : $this->mAction,
-                       'method'  => $this->mMethod,
-                       'class'   => 'visualClear',
+                       'action' => $this->mAction === false ? $this->getTitle()->getFullURL() : $this->mAction,
+                       'method' => $this->mMethod,
+                       'class' => 'visualClear',
                        'enctype' => $encType,
                );
                if ( !empty( $this->mId ) ) {
@@ -712,8 +712,8 @@ class HTMLForm extends ContextSource {
 
                foreach ( $this->mButtons as $button ) {
                        $attrs = array(
-                               'type'  => 'submit',
-                               'name'  => $button['name'],
+                               'type' => 'submit',
+                               'name' => $button['name'],
                                'value' => $button['value']
                        );
 
index 3de148b..5974173 100644 (file)
@@ -247,7 +247,7 @@ class HistoryBlobStub {
                                if ( !isset( $parts[1] ) || $parts[1] == '' ) {
                                        return false;
                                }
-                               $row->old_text = ExternalStore::fetchFromUrl($url);
+                               $row->old_text = ExternalStore::fetchFromUrl( $url );
 
                        }
                        if( !in_array( 'object', $flags ) ) {
@@ -395,7 +395,7 @@ class DiffHistoryBlob implements HistoryBlob {
         */
        function addItem( $text ) {
                if ( $this->mFrozen ) {
-                       throw new MWException( __METHOD__.": Cannot add more items after sleep/wakeup" );
+                       throw new MWException( __METHOD__ . ": Cannot add more items after sleep/wakeup" );
                }
 
                $this->mItems[] = $text;
@@ -535,11 +535,11 @@ class DiffHistoryBlob implements HistoryBlob {
                # Check the checksum if hash/mhash is available
                $ofp = $this->xdiffAdler32( $base );
                if ( $ofp !== false && $ofp !== substr( $diff, 0, 4 ) ) {
-                       wfDebug( __METHOD__. ": incorrect base checksum\n" );
+                       wfDebug( __METHOD__ . ": incorrect base checksum\n" );
                        return false;
                }
                if ( $header['csize'] != strlen( $base ) ) {
-                       wfDebug( __METHOD__. ": incorrect base length\n" );
+                       wfDebug( __METHOD__ . ": incorrect base length\n" );
                        return false;
                }
 
@@ -568,7 +568,7 @@ class DiffHistoryBlob implements HistoryBlob {
                                $out .= substr( $base, $x['off'], $x['csize'] );
                                break;
                        default:
-                               wfDebug( __METHOD__.": invalid op\n" );
+                               wfDebug( __METHOD__ . ": invalid op\n" );
                                return false;
                        }
                }
index 9e201a2..a29e5fe 100644 (file)
@@ -150,6 +150,7 @@ class Hooks {
                        return true;
                }
 
+               wfProfileIn( 'hook: ' . $event );
                $hooks = self::getHandlers( $event );
 
                foreach ( $hooks as $hook ) {
@@ -288,10 +289,12 @@ class Hooks {
                                        );
                                }
                        } elseif ( !$retval ) {
+                               wfProfileOut( 'hook: ' . $event );
                                return false;
                        }
                }
 
+               wfProfileOut( 'hook: ' . $event );
                return true;
        }
 
index 14456e4..60be863 100644 (file)
@@ -465,8 +465,7 @@ class Html {
                        $key = strtolower( $key );
 
                        // Here we're blacklisting some HTML5-only attributes...
-                       if ( !$wgHtml5 && in_array( $key, self::$HTMLFiveOnlyAttribs )
-                        ) {
+                       if ( !$wgHtml5 && in_array( $key, self::$HTMLFiveOnlyAttribs ) ) {
                                continue;
                        }
 
@@ -738,7 +737,7 @@ class Html {
                        }
                }
 
-               if (substr($value, 0, 1) == "\n") {
+               if ( substr( $value, 0, 1 ) == "\n" ) {
                        // Workaround for bug 12130: browsers eat the initial newline
                        // assuming that it's just for show, but they do keep the later
                        // newlines, which we may want to preserve during editing.
@@ -930,7 +929,7 @@ class Html {
                        $icon = $wgStylePath.'/common/images/'.$icon;
                }
 
-               $s  = Html::openElement( 'div', array( 'class' => "mw-infobox $class") );
+               $s = Html::openElement( 'div', array( 'class' => "mw-infobox $class" ) );
 
                $s .= Html::openElement( 'div', array( 'class' => 'mw-infobox-left' ) ).
                                Html::element( 'img',
index 337beb4..6a348a6 100644 (file)
@@ -244,7 +244,7 @@ class MWHttpRequest {
                }
 
                $members = array( "postData", "proxy", "noProxy", "sslVerifyHost", "caInfo",
-                                 "method", "followRedirects", "maxRedirects", "sslVerifyCert", "callback" );
+                               "method", "followRedirects", "maxRedirects", "sslVerifyCert", "callback" );
 
                foreach ( $members as $o ) {
                        if ( isset( $options[$o] ) ) {
@@ -284,7 +284,7 @@ class MWHttpRequest {
                        Http::$httpEngine = function_exists( 'curl_init' ) ? 'curl' : 'php';
                } elseif ( Http::$httpEngine == 'curl' && !function_exists( 'curl_init' ) ) {
                        throw new MWException( __METHOD__ . ': curl (http://php.net/curl) is not installed, but' .
-                                                                  ' Http::$httpEngine is set to "curl"' );
+                               ' Http::$httpEngine is set to "curl"' );
                }
 
                switch( Http::$httpEngine ) {
@@ -338,7 +338,7 @@ class MWHttpRequest {
                if ( Http::isLocalURL( $this->url ) || $this->noProxy ) {
                        $this->proxy = '';
                } elseif ( $wgHTTPProxy ) {
-                       $this->proxy = $wgHTTPProxy ;
+                       $this->proxy = $wgHTTPProxy;
                } elseif ( getenv( "http_proxy" ) ) {
                        $this->proxy = getenv( "http_proxy" );
                }
@@ -646,12 +646,12 @@ class MWHttpRequest {
                        $locations = $headers[ 'location' ];
                        $domain = '';
                        $foundRelativeURI = false;
-                       $countLocations = count($locations);
+                       $countLocations = count( $locations );
 
                        for ( $i = $countLocations - 1; $i >= 0; $i-- ) {
                                $url = parse_url( $locations[ $i ] );
 
-                               if ( isset($url[ 'host' ]) ) {
+                               if ( isset( $url['host'] ) ) {
                                        $domain = $url[ 'scheme' ] . '://' . $url[ 'host' ];
                                        break;  //found correct URI (with host)
                                } else {
index 1b40f4b..5c50c22 100644 (file)
@@ -714,7 +714,9 @@ class IP {
         * @return String: valid dotted quad IPv4 address or null
         */
        public static function canonicalize( $addr ) {
-               $addr = preg_replace( '/\%.*/','', $addr ); // remove zone info (bug 35738)
+               // remove zone info (bug 35738)
+               $addr = preg_replace( '/\%.*/', '', $addr );
+
                if ( self::isValid( $addr ) ) {
                        return $addr;
                }
index 91c3190..037093a 100644 (file)
@@ -161,7 +161,7 @@ class ImageGallery {
         * @param $alt   String: Alt text for the image
         * @param $link  String: Override image link (optional)
         */
-       function add( $title, $html = '', $alt = '', $link = '') {
+       function add( $title, $html = '', $alt = '', $link = '' ) {
                if ( $title instanceof File ) {
                        // Old calling convention
                        $title = $title->getTitle();
@@ -354,7 +354,7 @@ class ImageGallery {
                                        array(),
                                        array( 'known', 'noclasses' )
                                ) . "<br />\n" :
-                               '' ;
+                               '';
 
                        # ATTENTION: The newline after <div class="gallerytext"> is needed to accommodate htmltidy which
                        # in version 4.8.6 generated crackpot html in its absence, see:
index a54bd92..0b814ec 100644 (file)
@@ -156,7 +156,7 @@ class ImagePage extends Article {
                        $pageLang = $this->getTitle()->getPageViewLanguage();
                        $out->addHTML( Xml::openElement( 'div', array( 'id' => 'mw-imagepage-content',
                                'lang' => $pageLang->getHtmlCode(), 'dir' => $pageLang->getDir(),
-                               'class' => 'mw-content-'.$pageLang->getDir() ) ) );
+                               'class' => 'mw-content-' . $pageLang->getDir() ) ) );
 
                        parent::view();
 
@@ -298,18 +298,7 @@ class ImagePage extends Article {
                $dirmark = $lang->getDirMarkEntity();
                $request = $this->getContext()->getRequest();
 
-               $sizeSel = intval( $user->getOption( 'imagesize' ) );
-               if ( !isset( $wgImageLimits[$sizeSel] ) ) {
-                       $sizeSel = User::getDefaultOption( 'imagesize' );
-
-                       // The user offset might still be incorrect, specially if
-                       // $wgImageLimits got changed (see bug #8858).
-                       if ( !isset( $wgImageLimits[$sizeSel] ) ) {
-                               // Default to the first offset in $wgImageLimits
-                               $sizeSel = 0;
-                       }
-               }
-               $max = $wgImageLimits[$sizeSel];
+               $max = $this->getImageLimitsFromOption( $user, 'imagesize' );
                $maxWidth = $max[0];
                $maxHeight = $max[1];
 
@@ -358,10 +347,7 @@ class ImagePage extends Article {
                                        } else {
                                                # Creating thumb links triggers thumbnail generation.
                                                # Just generate the thumb for the current users prefs.
-                                               $thumbOption = $user->getOption( 'thumbsize' );
-                                               $thumbSizes = array( isset( $wgImageLimits[$thumbOption] )
-                                                       ? $wgImageLimits[$thumbOption]
-                                                       : $wgImageLimits[User::getDefaultOption( 'thumbsize' )] );
+                                               $thumbSizes = array( $this->getImageLimitsFromOption( $user, 'thumbsize' ) );
                                        }
                                        # Generate thumbnails or thumbnail links as needed...
                                        $otherSizes = array();
@@ -369,12 +355,19 @@ class ImagePage extends Article {
                                                if ( $size[0] < $width_orig && $size[1] < $height_orig
                                                        && $size[0] != $width && $size[1] != $height )
                                                {
-                                                       $otherSizes[] = $this->makeSizeLink( $params, $size[0], $size[1] );
+                                                       $sizeLink = $this->makeSizeLink( $params, $size[0], $size[1] );
+                                                       if ( $sizeLink ) {
+                                                               $otherSizes[] = $sizeLink;
+                                                       }
                                                }
                                        }
-                                       $msgsmall = wfMessage( 'show-big-image-preview' )->
-                                               rawParams( $this->makeSizeLink( $params, $width, $height ) )->
-                                               parse();
+                                       $msgsmall = '';
+                                       $sizeLinkBigImagePreview = $this->makeSizeLink( $params, $width, $height );
+                                       if ( $sizeLinkBigImagePreview ) {
+                                               $msgsmall .= wfMessage( 'show-big-image-preview' )->
+                                                       rawParams( $sizeLinkBigImagePreview )->
+                                                       parse();
+                                       }
                                        if ( count( $otherSizes ) ) {
                                                $msgsmall .= ' ' .
                                                Html::rawElement( 'span', array( 'class' => 'mw-filepage-other-resolutions' ),
@@ -538,7 +531,7 @@ EOT
                                        array( 'delete', 'move' ),
                                        $this->getTitle()->getPrefixedText(),
                                        '',
-                                       array(  'lim' => 10,
+                                       array( 'lim' => 10,
                                                'conds' => array( "log_action != 'revision'" ),
                                                'showIfEmpty' => false,
                                                'msgKey' => array( 'moveddeleted-notice' )
@@ -611,7 +604,7 @@ EOT
                $wrap = "<div class=\"sharedUploadNotice\">\n$1\n</div>\n";
                $repo = $this->mPage->getFile()->getRepo()->getDisplayName();
 
-               if ( $descUrl && $descText && wfMessage( 'sharedupload-desc-here' )->plain() !== '-'  ) {
+               if ( $descUrl && $descText && wfMessage( 'sharedupload-desc-here' )->plain() !== '-' ) {
                        $out->wrapWikiMsg( $wrap, array( 'sharedupload-desc-here', $repo, $descUrl ) );
                } elseif ( $descUrl && wfMessage( 'sharedupload-desc-there' )->plain() !== '-' ) {
                        $out->wrapWikiMsg( $wrap, array( 'sharedupload-desc-there', $repo, $descUrl ) );
@@ -630,7 +623,7 @@ EOT
                return $uploadTitle->getFullURL( array(
                        'wpDestFile' => $this->mPage->getFile()->getName(),
                        'wpForReUpload' => 1
-                ) );
+               ) );
        }
 
        /**
@@ -811,7 +804,7 @@ EOT
 
                                $ul = Html::rawElement(
                                        'ul',
-                                       array( 'class' => 'mw-imagepage-redirectstofile'),
+                                       array( 'class' => 'mw-imagepage-redirectstofile' ),
                                        $li
                                        ) . "\n";
                                $liContents = wfMessage( 'linkstoimage-redirect' )->rawParams(
@@ -911,6 +904,34 @@ EOT
                        return $a->page_namespace - $b->page_namespace;
                }
        }
+
+       /**
+        * Returns the corrosponding $wgImageLimits entry for the selected user option
+        *
+        * @param $user User
+        * @param $optionName string Name of a option to check, typically imagesize or thumbsize
+        * @return array
+        * @since 1.21
+        */
+       public function getImageLimitsFromOption( $user, $optionName ) {
+               global $wgImageLimits;
+
+               $option = intval( $user->getOption( $optionName ) );
+               if ( !isset( $wgImageLimits[$option] ) ) {
+                       $option = User::getDefaultOption( $optionName );
+               }
+
+               // The user offset might still be incorrect, specially if
+               // $wgImageLimits got changed (see bug #8858).
+               if ( !isset( $wgImageLimits[$option] ) ) {
+                       // Default to the first offset in $wgImageLimits
+                       $option = 0;
+               }
+
+               return isset( $wgImageLimits[$option] )
+                       ? $wgImageLimits[$option]
+                       : array( 800, 600 ); // if nothing is set, fallback to a hardcoded default
+       }
 }
 
 /**
@@ -1044,9 +1065,9 @@ class ImageHistoryList extends ContextSource {
                                } else {
                                        list( $ts, ) = explode( '!', $img, 2 );
                                        $query = array(
-                                               'type'   => 'oldimage',
+                                               'type' => 'oldimage',
                                                'target' => $this->title->getPrefixedText(),
-                                               'ids'    => $ts,
+                                               'ids' => $ts,
                                        );
                                        $del = Linker::revDeleteLink( $query,
                                                $file->isDeleted( File::DELETED_RESTRICTED ), $canHide );
index d00002a..15e6620 100644 (file)
@@ -400,7 +400,7 @@ class WikiImporter {
        /** Left in for debugging */
        private function dumpElement() {
                static $lookup = null;
-               if (!$lookup) {
+               if ( !$lookup ) {
                        $xmlReaderConstants = array(
                                "NONE",
                                "ELEMENT",
@@ -473,7 +473,7 @@ class WikiImporter {
                                $skip = true;
                        }
 
-                       if ($skip) {
+                       if ( $skip ) {
                                $keepReading = $this->reader->next();
                                $skip = false;
                                $this->debug( "Skip" );
@@ -509,7 +509,7 @@ class WikiImporter {
 
                while ( $this->reader->read() ) {
                        if ( $this->reader->nodeType == XmlReader::END_ELEMENT &&
-                                       $this->reader->name == 'logitem') {
+                                       $this->reader->name == 'logitem' ) {
                                break;
                        }
 
@@ -572,7 +572,7 @@ class WikiImporter {
 
                while ( $skip ? $this->reader->next() : $this->reader->read() ) {
                        if ( $this->reader->nodeType == XmlReader::END_ELEMENT &&
-                                       $this->reader->name == 'page') {
+                                       $this->reader->name == 'page' ) {
                                break;
                        }
 
@@ -626,7 +626,7 @@ class WikiImporter {
 
                while ( $skip ? $this->reader->next() : $this->reader->read() ) {
                        if ( $this->reader->nodeType == XmlReader::END_ELEMENT &&
-                                       $this->reader->name == 'revision') {
+                                       $this->reader->name == 'revision' ) {
                                break;
                        }
 
@@ -712,7 +712,7 @@ class WikiImporter {
 
                while ( $skip ? $this->reader->next() : $this->reader->read() ) {
                        if ( $this->reader->nodeType == XmlReader::END_ELEMENT &&
-                                       $this->reader->name == 'upload') {
+                                       $this->reader->name == 'upload' ) {
                                break;
                        }
 
@@ -809,7 +809,7 @@ class WikiImporter {
 
                while ( $this->reader->read() ) {
                        if ( $this->reader->nodeType == XmlReader::END_ELEMENT &&
-                                       $this->reader->name == 'contributor') {
+                                       $this->reader->name == 'contributor' ) {
                                break;
                        }
 
@@ -897,7 +897,7 @@ class UploadSourceAdapter {
         * @return bool
         */
        function stream_open( $path, $mode, $options, &$opened_path ) {
-               $url = parse_url($path);
+               $url = parse_url( $path );
                $id = $url['host'];
 
                if ( !isset( self::$sourceRegistrations[$id] ) ) {
@@ -918,22 +918,22 @@ class UploadSourceAdapter {
                $leave = false;
 
                while ( !$leave && !$this->mSource->atEnd() &&
-                               strlen($this->mBuffer) < $count ) {
+                               strlen( $this->mBuffer ) < $count ) {
                        $read = $this->mSource->readChunk();
 
-                       if ( !strlen($read) ) {
+                       if ( !strlen( $read ) ) {
                                $leave = true;
                        }
 
                        $this->mBuffer .= $read;
                }
 
-               if ( strlen($this->mBuffer) ) {
+               if ( strlen( $this->mBuffer ) ) {
                        $return = substr( $this->mBuffer, 0, $count );
                        $this->mBuffer = substr( $this->mBuffer, $count );
                }
 
-               $this->mPosition += strlen($return);
+               $this->mPosition += strlen( $return );
 
                return $return;
        }
@@ -1390,7 +1390,7 @@ class WikiRevision {
                                array( 'rev_page' => $pageId,
                                        'rev_timestamp' => $dbw->timestamp( $this->timestamp ),
                                        'rev_user_text' => $userText,
-                                       'rev_comment'   => $this->getComment() ),
+                                       'rev_comment' => $this->getComment() ),
                                __METHOD__
                        );
                        if( $prior ) {
@@ -1405,15 +1405,15 @@ class WikiRevision {
                # @todo FIXME: Use original rev_id optionally (better for backups)
                # Insert the row
                $revision = new Revision( array(
-                       'title'      => $this->title,
-                       'page'       => $pageId,
-                       'content_model'  => $this->getModel(),
+                       'title' => $this->title,
+                       'page' => $pageId,
+                       'content_model' => $this->getModel(),
                        'content_format' => $this->getFormat(),
-                       'text'       => $this->getContent()->serialize( $this->getFormat() ), //XXX: just set 'content' => $this->getContent()?
-                       'comment'    => $this->getComment(),
-                       'user'       => $userId,
-                       'user_text'  => $userText,
-                       'timestamp'  => $this->timestamp,
+                       'text' => $this->getContent()->serialize( $this->getFormat() ), //XXX: just set 'content' => $this->getContent()?
+                       'comment' => $this->getComment(),
+                       'user' => $userId,
+                       'user_text' => $userText,
+                       'timestamp' => $this->timestamp,
                        'minor_edit' => $this->minor,
                        ) );
                $revision->insertOn( $dbw );
@@ -1442,13 +1442,13 @@ class WikiRevision {
                // @todo FIXME: Use original log ID (better for backups)
                $prior = $dbw->selectField( 'logging', '1',
                        array( 'log_type' => $this->getType(),
-                               'log_action'    => $this->getAction(),
+                               'log_action' => $this->getAction(),
                                'log_timestamp' => $dbw->timestamp( $this->timestamp ),
                                'log_namespace' => $this->getTitle()->getNamespace(),
-                               'log_title'     => $this->getTitle()->getDBkey(),
-                               'log_comment'   => $this->getComment(),
+                               'log_title' => $this->getTitle()->getDBkey(),
+                               'log_comment' => $this->getComment(),
                                #'log_user_text' => $this->user_text,
-                               'log_params'    => $this->params ),
+                               'log_params' => $this->params ),
                        __METHOD__
                );
                // @todo FIXME: This could fail slightly for multiple matches :P
index c2f6b1e..28379c7 100644 (file)
@@ -89,7 +89,7 @@ class LinkFilter {
         * @param $prot        String: protocol
         * @return Array to be passed to DatabaseBase::buildLike() or false on error
         */
-        public static function makeLikeArray( $filterEntry , $prot = 'http://' ) {
+       public static function makeLikeArray( $filterEntry, $prot = 'http://' ) {
                $db = wfGetDB( DB_MASTER );
                if ( substr( $filterEntry, 0, 2 ) == '*.' ) {
                        $subdomains = true;
@@ -118,7 +118,7 @@ class LinkFilter {
                }
                // Reverse the labels in the hostname, convert to lower case
                // For emails reverse domainpart only
-               if ( $prot == 'mailto:' && strpos($host, '@') ) {
+               if ( $prot == 'mailto:' && strpos( $host, '@' ) ) {
                        // complete email adress
                        $mailparts = explode( '@', $host );
                        $domainpart = strtolower( implode( '.', array_reverse( explode( '.', $mailparts[1] ) ) ) );
index bc0bb77..4555398 100644 (file)
@@ -33,7 +33,7 @@ class Linker {
         * Flags for userToolLinks()
         */
        const TOOL_LINKS_NOBLOCK = 1;
-       const TOOL_LINKS_EMAIL   = 2;
+       const TOOL_LINKS_EMAIL = 2;
 
        /**
         * Get the appropriate HTML attributes to add to the "a" element of an ex-
@@ -600,9 +600,9 @@ class Linker {
                $prefix = $postfix = '';
 
                if ( 'center' == $fp['align'] ) {
-                       $prefix  = '<div class="center">';
+                       $prefix = '<div class="center">';
                        $postfix = '</div>';
-                       $fp['align']   = 'none';
+                       $fp['align'] = 'none';
                }
                if ( $file && !isset( $hp['width'] ) ) {
                        if ( isset( $hp['height'] ) && $file->isVectorized() ) {
@@ -724,7 +724,7 @@ class Linker {
                                $extLinkAttrs = $parser->getExternalLinkAttribs( $frameParams['link-url'] );
                                foreach ( $extLinkAttrs as $name => $val ) {
                                        // Currently could include 'rel' and 'target'
-                                       $mtoParams['parser-extlink-'.$name] = $val;
+                                       $mtoParams['parser-extlink-' . $name] = $val;
                                }
                        }
                } elseif ( isset( $frameParams['link-title'] ) && $frameParams['link-title'] !== '' ) {
@@ -751,7 +751,7 @@ class Linker {
         * @return mixed
         */
        public static function makeThumbLinkObj( Title $title, $file, $label = '', $alt,
-               $align = 'right', $params = array(), $framed = false , $manualthumb = "" )
+               $align = 'right', $params = array(), $framed = false, $manualthumb = "" )
        {
                $frameParams = array(
                        'alt' => $alt,
@@ -1028,7 +1028,7 @@ class Linker {
                        $key = strtolower( $name );
                }
 
-               return self::linkKnown( SpecialPage::getTitleFor( $name ) , wfMessage( $key )->text() );
+               return self::linkKnown( SpecialPage::getTitleFor( $name ), wfMessage( $key )->text() );
        }
 
        /**
@@ -1672,11 +1672,10 @@ class Linker {
                $lang = wfGetLangObj( $lang );
                $title = wfMessage( 'toc' )->inLanguage( $lang )->escaped();
 
-               return
-                  '<table id="toc" class="toc"><tr><td>'
-                . '<div id="toctitle"><h2>' . $title . "</h2></div>\n"
-                . $toc
-                . "</ul>\n</td></tr></table>\n";
+               return '<table id="toc" class="toc"><tr><td>'
+                       . '<div id="toctitle"><h2>' . $title . "</h2></div>\n"
+                       . $toc
+                       . "</ul>\n</td></tr></table>\n";
        }
 
        /**
@@ -2075,7 +2074,7 @@ class Linker {
                        # Compatibility: formerly some tooltips had [alt-.] hardcoded
                        $tooltip = preg_replace( "/ ?\[alt-.\]$/", '', $tooltip );
                        # Message equal to '-' means suppress it.
-                       if (  $tooltip == '-' ) {
+                       if ( $tooltip == '-' ) {
                                $tooltip = false;
                        }
                }
@@ -2157,17 +2156,17 @@ class Linker {
                                // RevDelete links using revision ID are stable across
                                // page deletion and undeletion; use when possible.
                                $query = array(
-                                       'type'   => 'revision',
+                                       'type' => 'revision',
                                        'target' => $title->getPrefixedDBkey(),
-                                       'ids'    => $rev->getId()
+                                       'ids' => $rev->getId()
                                );
                        } else {
                                // Older deleted entries didn't save a revision ID.
                                // We have to refer to these by timestamp, ick!
                                $query = array(
-                                       'type'   => 'archive',
+                                       'type' => 'archive',
                                        'target' => $title->getPrefixedDBkey(),
-                                       'ids'    => $rev->getTimestamp()
+                                       'ids' => $rev->getTimestamp()
                                );
                        }
                        return Linker::revDeleteLink( $query,
@@ -2287,7 +2286,7 @@ class Linker {
         * @return string the a-element
         */
        static function makeKnownLinkObj(
-               $title, $text = '', $query = '', $trail = '', $prefix = '' , $aprops = '', $style = ''
+               $title, $text = '', $query = '', $trail = '', $prefix = '', $aprops = '', $style = ''
        ) {
                wfDeprecated( __METHOD__, '1.21' );
 
index cfd7413..83883b5 100644 (file)
@@ -213,14 +213,14 @@ class LinksUpdate extends SqlDataUpdate {
                $existing = $this->getExistingImages();
                $imageUpdates = array_diff_key( $existing, $this->mImages ) + array_diff_key( $this->mImages, $existing );
 
-               $this->dumbTableUpdate( 'pagelinks',     $this->getLinkInsertions(),     'pl_from' );
-               $this->dumbTableUpdate( 'imagelinks',    $this->getImageInsertions(),    'il_from' );
+               $this->dumbTableUpdate( 'pagelinks', $this->getLinkInsertions(), 'pl_from' );
+               $this->dumbTableUpdate( 'imagelinks', $this->getImageInsertions(), 'il_from' );
                $this->dumbTableUpdate( 'categorylinks', $this->getCategoryInsertions(), 'cl_from' );
                $this->dumbTableUpdate( 'templatelinks', $this->getTemplateInsertions(), 'tl_from' );
                $this->dumbTableUpdate( 'externallinks', $this->getExternalInsertions(), 'el_from' );
-               $this->dumbTableUpdate( 'langlinks',     $this->getInterlangInsertions(),'ll_from' );
-               $this->dumbTableUpdate( 'iwlinks',       $this->getInterwikiInsertions(),'iwl_from' );
-               $this->dumbTableUpdate( 'page_props',    $this->getPropertyInsertions(), 'pp_page' );
+               $this->dumbTableUpdate( 'langlinks', $this->getInterlangInsertions(), 'll_from' );
+               $this->dumbTableUpdate( 'iwlinks', $this->getInterwikiInsertions(), 'iwl_from' );
+               $this->dumbTableUpdate( 'page_props', $this->getPropertyInsertions(), 'pp_page' );
 
                # Update the cache of all the category pages and image description
                # pages which were changed, and fix the category table count
@@ -291,7 +291,7 @@ class LinksUpdate extends SqlDataUpdate {
                $this->mDb->delete( $table, array( $fromField => $this->mId ), __METHOD__ );
                if ( count( $insertions ) ) {
                        # The link array was constructed without FOR UPDATE, so there may
-                       # be collisions.  This may cause minor link table inconsistencies,
+                       # be collisions. This may cause minor link table inconsistencies,
                        # which is better than crippling the site with lock contention.
                        $this->mDb->insert( $table, $insertions, __METHOD__, array( 'IGNORE' ) );
                }
@@ -360,9 +360,9 @@ class LinksUpdate extends SqlDataUpdate {
                                : $dbkeys;
                        foreach ( $diffs as $dbk => $id ) {
                                $arr[] = array(
-                                       'pl_from'      => $this->mId,
+                                       'pl_from' => $this->mId,
                                        'pl_namespace' => $ns,
-                                       'pl_title'     => $dbk
+                                       'pl_title' => $dbk
                                );
                        }
                }
@@ -380,9 +380,9 @@ class LinksUpdate extends SqlDataUpdate {
                        $diffs = isset( $existing[$ns] ) ? array_diff_key( $dbkeys, $existing[$ns] ) : $dbkeys;
                        foreach ( $diffs as $dbk => $id ) {
                                $arr[] = array(
-                                       'tl_from'      => $this->mId,
+                                       'tl_from' => $this->mId,
                                        'tl_namespace' => $ns,
-                                       'tl_title'     => $dbk
+                                       'tl_title' => $dbk
                                );
                        }
                }
@@ -401,7 +401,7 @@ class LinksUpdate extends SqlDataUpdate {
                foreach( $diffs as $iname => $dummy ) {
                        $arr[] = array(
                                'il_from' => $this->mId,
-                               'il_to'   => $iname
+                               'il_to' => $iname
                        );
                }
                return $arr;
@@ -418,9 +418,9 @@ class LinksUpdate extends SqlDataUpdate {
                foreach( $diffs as $url => $dummy ) {
                        foreach( wfMakeUrlIndexes( $url ) as $index ) {
                                $arr[] = array(
-                                       'el_from'   => $this->mId,
-                                       'el_to'     => $url,
-                                       'el_index'  => $index,
+                                       'el_from' => $this->mId,
+                                       'el_to' => $url,
+                                       'el_index' => $index,
                                );
                        }
                }
@@ -459,8 +459,8 @@ class LinksUpdate extends SqlDataUpdate {
                                $this->mTitle->getCategorySortkey( $prefix ) );
 
                        $arr[] = array(
-                               'cl_from'    => $this->mId,
-                               'cl_to'      => $name,
+                               'cl_from' => $this->mId,
+                               'cl_to' => $name,
                                'cl_sortkey' => $sortkey,
                                'cl_timestamp' => $this->mDb->timestamp(),
                                'cl_sortkey_prefix' => $prefix,
@@ -483,8 +483,8 @@ class LinksUpdate extends SqlDataUpdate {
                $arr = array();
                foreach( $diffs as $lang => $title ) {
                        $arr[] = array(
-                               'll_from'  => $this->mId,
-                               'll_lang'  => $lang,
+                               'll_from' => $this->mId,
+                               'll_lang' => $lang,
                                'll_title' => $title
                        );
                }
@@ -501,9 +501,9 @@ class LinksUpdate extends SqlDataUpdate {
                $arr = array();
                foreach ( $diffs as $name => $value ) {
                        $arr[] = array(
-                               'pp_page'      => $this->mId,
-                               'pp_propname'  => $name,
-                               'pp_value'     => $value,
+                               'pp_page' => $this->mId,
+                               'pp_propname' => $name,
+                               'pp_value' => $value,
                        );
                }
                return $arr;
@@ -521,9 +521,9 @@ class LinksUpdate extends SqlDataUpdate {
                        $diffs = isset( $existing[$prefix] ) ? array_diff_key( $dbkeys, $existing[$prefix] ) : $dbkeys;
                        foreach ( $diffs as $dbk => $id ) {
                                $arr[] = array(
-                                       'iwl_from'   => $this->mId,
+                                       'iwl_from' => $this->mId,
                                        'iwl_prefix' => $prefix,
-                                       'iwl_title'  => $dbk
+                                       'iwl_title' => $dbk
                                );
                        }
                }
index d1f6a0f..257a46d 100644 (file)
@@ -217,7 +217,7 @@ class MagicWord {
 
        /**#@-*/
 
-       function __construct($id = 0, $syn = array(), $cs = false) {
+       function __construct( $id = 0, $syn = array(), $cs = false ) {
                $this->mId = $id;
                $this->mSynonyms = (array)$syn;
                $this->mCaseSensitive = $cs;
@@ -367,7 +367,7 @@ class MagicWord {
         * @return string
         */
        function getRegex() {
-               if ($this->mRegex == '' ) {
+               if ( $this->mRegex == '' ) {
                        $this->initRegex();
                }
                return $this->mRegex;
@@ -393,7 +393,7 @@ class MagicWord {
         * @return string
         */
        function getRegexStart() {
-               if ($this->mRegex == '' ) {
+               if ( $this->mRegex == '' ) {
                        $this->initRegex();
                }
                return $this->mRegexStart;
@@ -405,7 +405,7 @@ class MagicWord {
         * @return string
         */
        function getBaseRegex() {
-               if ($this->mRegex == '') {
+               if ( $this->mRegex == '' ) {
                        $this->initRegex();
                }
                return $this->mBaseRegex;
@@ -454,9 +454,9 @@ class MagicWord {
                        # blank elements and re-sort the indices.
                        # See also bug 6526
 
-                       $matches = array_values(array_filter($matches));
+                       $matches = array_values( array_filter( $matches ) );
 
-                       if ( count($matches) == 1 ) {
+                       if ( count( $matches ) == 1 ) {
                                return $matches[0];
                        } else {
                                return $matches[1];
@@ -618,7 +618,7 @@ class MagicWord {
        function addToArray( &$array, $value ) {
                global $wgContLang;
                foreach ( $this->mSynonyms as $syn ) {
-                       $array[$wgContLang->lc($syn)] = $value;
+                       $array[$wgContLang->lc( $syn )] = $value;
                }
        }
 
@@ -812,7 +812,7 @@ class MagicWordArray {
                        return array( $magicName, $paramValue );
                }
                // This shouldn't happen either
-               throw new MWException( __METHOD__.': parameter not found' );
+               throw new MWException( __METHOD__ . ': parameter not found' );
        }
 
        /**
index 96747c9..8d8cdee 100644 (file)
@@ -252,9 +252,9 @@ class Message {
        public static function newFallbackSequence( /*...*/ ) {
                $keys = func_get_args();
                if ( func_num_args() == 1 ) {
-                       if ( is_array($keys[0]) ) {
+                       if ( is_array( $keys[0] ) ) {
                                // Allow an array to be passed as the first argument instead
-                               $keys = array_values($keys[0]);
+                               $keys = array_values( $keys[0] );
                        } else {
                                // Optimize a single string to not need special fallback handling
                                $keys = $keys[0];
@@ -416,7 +416,7 @@ class Message {
         */
        public function content() {
                if ( !$this->content ) {
-                       $this->content = new MessageContent( $this->key );
+                       $this->content = new MessageContent( $this );
                }
 
                return $this->content;
@@ -431,7 +431,7 @@ class Message {
                $string = $this->fetchMessage();
 
                if ( $string === false ) {
-                       $key =  htmlspecialchars( is_array( $this->key ) ? $this->key[0] : $this->key );
+                       $key = htmlspecialchars( is_array( $this->key ) ? $this->key[0] : $this->key );
                        if ( $this->format === 'plain' ) {
                                return '<' . $key . '>';
                        }
@@ -474,7 +474,7 @@ class Message {
 
        /**
         * Magic method implementation of the above (for PHP >= 5.2.0), so we can do, eg:
-        *     $foo = Message::get($key);
+        *     $foo = Message::get( $key );
         *     $string = "<abbr>$foo</abbr>";
         * @since 1.18
         * @return String
index 9a4ddca..0b8014a 100644 (file)
@@ -82,10 +82,10 @@ abstract class RdfMetaData {
                print "\t\t<dc:{$name}>{$value}</dc:{$name}>\n";
        }
 
-       protected function date($timestamp) {
-               return substr($timestamp, 0, 4) . '-'
-                 . substr($timestamp, 4, 2) . '-'
-                 . substr($timestamp, 6, 2);
+       protected function date( $timestamp ) {
+               return substr( $timestamp, 0, 4 ) . '-'
+                       . substr( $timestamp, 4, 2 ) . '-'
+                       . substr( $timestamp, 6, 2 );
        }
 
        protected function pageOrString( $name, $page, $str ) {
@@ -110,7 +110,7 @@ abstract class RdfMetaData {
                $this->url( $name, $title->getFullUrl() );
        }
 
-       protected function url($name, $url) {
+       protected function url( $name, $url ) {
                $url = htmlspecialchars( $url );
                print "\t\t<dc:{$name} rdf:resource=\"{$url}\" />\n";
        }
@@ -166,23 +166,23 @@ abstract class RdfMetaData {
        }
 
        protected function getKnownLicenses() {
-               $ccLicenses = array('by', 'by-nd', 'by-nd-nc', 'by-nc',
-                                                       'by-nc-sa', 'by-sa');
-               $ccVersions = array('1.0', '2.0');
+               $ccLicenses = array( 'by', 'by-nd', 'by-nd-nc', 'by-nc',
+                                                       'by-nc-sa', 'by-sa' );
+               $ccVersions = array( '1.0', '2.0' );
                $knownLicenses = array();
 
-               foreach ($ccVersions as $version) {
-                       foreach ($ccLicenses as $license) {
-                               if( $version == '2.0' && substr( $license, 0, 2) != 'by' ) {
+               foreach ( $ccVersions as $version ) {
+                       foreach ( $ccLicenses as $license ) {
+                               if( $version == '2.0' && substr( $license, 0, 2 ) != 'by' ) {
                                        # 2.0 dropped the non-attribs licenses
                                        continue;
                                }
                                $lurl = "http://creativecommons.org/licenses/{$license}/{$version}/";
-                               $knownLicenses[$lurl] = explode('-', $license);
+                               $knownLicenses[$lurl] = explode( '-', $license );
                                $knownLicenses[$lurl][] = 're';
                                $knownLicenses[$lurl][] = 'di';
                                $knownLicenses[$lurl][] = 'no';
-                               if (!in_array('nd', $knownLicenses[$lurl])) {
+                               if ( !in_array( 'nd', $knownLicenses[$lurl] ) ) {
                                        $knownLicenses[$lurl][] = 'de';
                                }
                        }
@@ -191,11 +191,11 @@ abstract class RdfMetaData {
                /* Handle the GPL and LGPL, too. */
 
                $knownLicenses['http://creativecommons.org/licenses/GPL/2.0/'] =
-                 array('de', 're', 'di', 'no', 'sa', 'sc');
+                       array( 'de', 're', 'di', 'no', 'sa', 'sc' );
                $knownLicenses['http://creativecommons.org/licenses/LGPL/2.1/'] =
-                 array('de', 're', 'di', 'no', 'sa', 'sc');
+                       array( 'de', 're', 'di', 'no', 'sa', 'sc' );
                $knownLicenses['http://www.gnu.org/copyleft/fdl.html'] =
-                 array('de', 're', 'di', 'no', 'sa', 'sc');
+                       array( 'de', 're', 'di', 'no', 'sa', 'sc' );
 
                return $knownLicenses;
        }
index b2611c2..e787fbd 100644 (file)
@@ -39,7 +39,7 @@
  * appending MM_WELL_KNOWN_MIME_TYPES behind $wgMimeTypeFile, but who knows
  * what will break? In practice this probably isn't a problem anyway -- Bryan)
  */
-define('MM_WELL_KNOWN_MIME_TYPES',<<<END_STRING
+define('MM_WELL_KNOWN_MIME_TYPES', <<<END_STRING
 application/ogg ogx ogg ogm ogv oga spx
 application/pdf pdf
 application/vnd.oasis.opendocument.chart odc
@@ -197,14 +197,14 @@ class MimeMagic {
 
                if ( $wgMimeTypeFile ) {
                        if ( is_file( $wgMimeTypeFile ) and is_readable( $wgMimeTypeFile ) ) {
-                               wfDebug( __METHOD__.": loading mime types from $wgMimeTypeFile\n" );
+                               wfDebug( __METHOD__ . ": loading mime types from $wgMimeTypeFile\n" );
                                $types .= "\n";
                                $types .= file_get_contents( $wgMimeTypeFile );
                        } else {
-                               wfDebug( __METHOD__.": can't load mime types from $wgMimeTypeFile\n" );
+                               wfDebug( __METHOD__ . ": can't load mime types from $wgMimeTypeFile\n" );
                        }
                } else {
-                       wfDebug( __METHOD__.": no mime types file defined, using build-ins only.\n" );
+                       wfDebug( __METHOD__ . ": no mime types file defined, using build-ins only.\n" );
                }
 
                $types = str_replace( array( "\r\n", "\n\r", "\n\n", "\r\r", "\r" ), "\n", $types );
@@ -213,7 +213,7 @@ class MimeMagic {
                $this->mMimeToExt = array();
                $this->mToMime = array();
 
-               $lines = explode( "\n",$types );
+               $lines = explode( "\n", $types );
                foreach ( $lines as $s ) {
                        $s = trim( $s );
                        if ( empty( $s ) ) {
@@ -231,7 +231,7 @@ class MimeMagic {
                        }
 
                        $mime = substr( $s, 0, $i );
-                       $ext = trim( substr($s, $i+1 ) );
+                       $ext = trim( substr( $s, $i+1 ) );
 
                        if ( empty( $ext ) ) {
                                continue;
@@ -272,17 +272,17 @@ class MimeMagic {
 
                if ( $wgMimeInfoFile ) {
                        if ( is_file( $wgMimeInfoFile ) and is_readable( $wgMimeInfoFile ) ) {
-                               wfDebug( __METHOD__.": loading mime info from $wgMimeInfoFile\n" );
+                               wfDebug( __METHOD__ . ": loading mime info from $wgMimeInfoFile\n" );
                                $info .= "\n";
                                $info .= file_get_contents( $wgMimeInfoFile );
                        } else {
-                               wfDebug(__METHOD__.": can't load mime info from $wgMimeInfoFile\n");
+                               wfDebug( __METHOD__ . ": can't load mime info from $wgMimeInfoFile\n" );
                        }
                } else {
-                       wfDebug(__METHOD__.": no mime info file defined, using build-ins only.\n");
+                       wfDebug( __METHOD__ . ": no mime info file defined, using build-ins only.\n" );
                }
 
-               $info = str_replace( array( "\r\n", "\n\r", "\n\n", "\r\r", "\r" ), "\n", $info);
+               $info = str_replace( array( "\r\n", "\n\r", "\n\n", "\r\r", "\r" ), "\n", $info );
                $info = str_replace( "\t", " ", $info );
 
                $this->mMimeTypeAliases = array();
@@ -332,7 +332,7 @@ class MimeMagic {
 
                        if ( count( $m ) > 1 ) {
                                $main = $m[0];
-                               for ( $i=1; $i<count($m); $i += 1 ) {
+                               for ( $i = 1; $i < count( $m ); $i += 1 ) {
                                        $mime = $m[$i];
                                        $this->mMimeTypeAliases[$mime] = $main;
                                }
@@ -511,7 +511,7 @@ class MimeMagic {
        public function improveTypeFromExtension( $mime, $ext ) {
                if ( $mime === 'unknown/unknown' ) {
                        if ( $this->isRecognizableExtension( $ext ) ) {
-                               wfDebug( __METHOD__. ': refusing to guess mime type for .' .
+                               wfDebug( __METHOD__ . ': refusing to guess mime type for .' .
                                        "$ext file, we should have recognized it\n" );
                        } else {
                                // Not something we can detect, so simply
@@ -525,7 +525,7 @@ class MimeMagic {
                                // find the proper mime type for that file extension
                                $mime = $this->guessTypesForExtension( $ext );
                        } else {
-                               wfDebug( __METHOD__. ": refusing to guess better type for $mime file, " .
+                               wfDebug( __METHOD__ . ": refusing to guess better type for $mime file, " .
                                        ".$ext is not a known OPC extension.\n" );
                                $mime = 'application/zip';
                        }
@@ -535,7 +535,7 @@ class MimeMagic {
                        $mime = $this->mMimeTypeAliases[$mime];
                }
 
-               wfDebug(__METHOD__.": improved mime type for .$ext: $mime\n");
+               wfDebug( __METHOD__ . ": improved mime type for .$ext: $mime\n" );
                return $mime;
        }
 
@@ -555,14 +555,14 @@ class MimeMagic {
         */
        public function guessMimeType( $file, $ext = true ) {
                if ( $ext ) { // TODO: make $ext default to false. Or better, remove it.
-                       wfDebug( __METHOD__.": WARNING: use of the \$ext parameter is deprecated. " .
+                       wfDebug( __METHOD__ . ": WARNING: use of the \$ext parameter is deprecated. " .
                                "Use improveTypeFromExtension(\$mime, \$ext) instead.\n" );
                }
 
                $mime = $this->doGuessMimeType( $file, $ext );
 
                if( !$mime ) {
-                       wfDebug( __METHOD__.": internal type detection failed for $file (.$ext)...\n" );
+                       wfDebug( __METHOD__ . ": internal type detection failed for $file (.$ext)...\n" );
                        $mime = $this->detectMimeType( $file, $ext );
                }
 
@@ -570,7 +570,7 @@ class MimeMagic {
                        $mime = $this->mMimeTypeAliases[$mime];
                }
 
-               wfDebug(__METHOD__.": guessed mime type of $file: $mime\n");
+               wfDebug( __METHOD__ . ": guessed mime type of $file: $mime\n" );
                return $mime;
        }
 
@@ -629,7 +629,7 @@ class MimeMagic {
                        $doctype = strpos( $head, "\x42\x82" );
                        if ( $doctype ) {
                                // Next byte is datasize, then data (sizes larger than 1 byte are very stupid muxers)
-                               $data = substr($head, $doctype+3, 8);
+                               $data = substr( $head, $doctype+3, 8 );
                                if ( strncmp( $data, "matroska", 8 ) == 0 ) {
                                        wfDebug( __METHOD__ . ": recognized file as video/x-matroska\n" );
                                        return "video/x-matroska";
@@ -661,12 +661,11 @@ class MimeMagic {
                 * strings like "<? ", but should it be axed completely?
                 */
                if ( ( strpos( $head, '<?php' ) !== false ) ||
-
-                   ( strpos( $head, "<\x00?\x00p\x00h\x00p" ) !== false ) ||
-                   ( strpos( $head, "<\x00?\x00 " ) !== false ) ||
-                   ( strpos( $head, "<\x00?\x00\n" ) !== false ) ||
-                   ( strpos( $head, "<\x00?\x00\t" ) !== false ) ||
-                   ( strpos( $head, "<\x00?\x00=" ) !== false ) ) {
+                       ( strpos( $head, "<\x00?\x00p\x00h\x00p" ) !== false ) ||
+                       ( strpos( $head, "<\x00?\x00 " ) !== false ) ||
+                       ( strpos( $head, "<\x00?\x00\n" ) !== false ) ||
+                       ( strpos( $head, "<\x00?\x00\t" ) !== false ) ||
+                       ( strpos( $head, "<\x00?\x00=" ) !== false ) ) {
 
                        wfDebug( __METHOD__ . ": recognized $file as application/x-php\n" );
                        return 'application/x-php';
@@ -698,11 +697,11 @@ class MimeMagic {
                } elseif ( substr( $head, 0, 7) == "\xfe\xff\x00#\x00!" ) {
                        $script_type = "UTF-16BE";
                } elseif ( substr( $head, 0, 7 ) == "\xff\xfe#\x00!" ) {
-                       $script_type= "UTF-16LE";
+                       $script_type = "UTF-16LE";
                }
 
                if ( $script_type ) {
-                       if ( $script_type !== "UTF-8" && $script_type !== "ASCII") {
+                       if ( $script_type !== "UTF-8" && $script_type !== "ASCII" ) {
                                // Quick and dirty fold down to ASCII!
                                $pack = array( 'UTF-16BE' => 'n*', 'UTF-16LE' => 'v*' );
                                $chars = unpack( $pack[$script_type], substr( $head, 2 ) );
@@ -720,14 +719,14 @@ class MimeMagic {
 
                        if ( preg_match( '%/?([^\s]+/)(\w+)%', $head, $match ) ) {
                                $mime = "application/x-{$match[2]}";
-                               wfDebug( __METHOD__.": shell script recognized as $mime\n" );
+                               wfDebug( __METHOD__ . ": shell script recognized as $mime\n" );
                                return $mime;
                        }
                }
 
                // Check for ZIP variants (before getimagesize)
                if ( strpos( $tail, "PK\x05\x06" ) !== false ) {
-                       wfDebug( __METHOD__.": ZIP header present in $file\n" );
+                       wfDebug( __METHOD__ . ": ZIP header present in $file\n" );
                        return $this->detectZipType( $head, $tail, $ext );
                }
 
@@ -737,14 +736,14 @@ class MimeMagic {
 
                if( $gis && isset( $gis['mime'] ) ) {
                        $mime = $gis['mime'];
-                       wfDebug( __METHOD__.": getimagesize detected $file as $mime\n" );
+                       wfDebug( __METHOD__ . ": getimagesize detected $file as $mime\n" );
                        return $mime;
                }
 
                // Also test DjVu
                $deja = new DjVuImage( $file );
                if( $deja->isValid() ) {
-                       wfDebug( __METHOD__.": detected $file as image/vnd.djvu\n" );
+                       wfDebug( __METHOD__ . ": detected $file as image/vnd.djvu\n" );
                        return 'image/vnd.djvu';
                }
 
@@ -766,7 +765,7 @@ class MimeMagic {
         */
        function detectZipType( $header, $tail = null, $ext = false ) {
                if( $ext ) { # TODO: remove $ext param
-                       wfDebug( __METHOD__.": WARNING: use of the \$ext parameter is deprecated. " .
+                       wfDebug( __METHOD__ . ": WARNING: use of the \$ext parameter is deprecated. " .
                                "Use improveTypeFromExtension(\$mime, \$ext) instead.\n" );
                }
 
@@ -797,7 +796,7 @@ class MimeMagic {
 
                if ( preg_match( $opendocRegex, substr( $header, 30 ), $matches ) ) {
                        $mime = $matches[1];
-                       wfDebug( __METHOD__.": detected $mime from ZIP archive\n" );
+                       wfDebug( __METHOD__ . ": detected $mime from ZIP archive\n" );
                } elseif ( preg_match( $openxmlRegex, substr( $header, 30 ) ) ) {
                        $mime = "application/x-opc+zip";
                        # TODO: remove the block below, as soon as improveTypeFromExtension is used everywhere
@@ -814,7 +813,7 @@ class MimeMagic {
                                        $mime = "application/zip";
                                }
                        }
-                       wfDebug( __METHOD__.": detected an Open Packaging Conventions archive: $mime\n" );
+                       wfDebug( __METHOD__ . ": detected an Open Packaging Conventions archive: $mime\n" );
                } elseif ( substr( $header, 0, 8 ) == "\xd0\xcf\x11\xe0\xa1\xb1\x1a\xe1" &&
                                ($headerpos = strpos( $tail, "PK\x03\x04" ) ) !== false &&
                                preg_match( $openxmlRegex, substr( $tail, $headerpos + 30 ) ) ) {
@@ -843,9 +842,9 @@ class MimeMagic {
                                        break;
                        }
 
-                       wfDebug( __METHOD__.": detected a MS Office document with OPC trailer\n");
+                       wfDebug( __METHOD__ . ": detected a MS Office document with OPC trailer\n" );
                } else {
-                       wfDebug( __METHOD__.": unable to identify type of ZIP archive\n" );
+                       wfDebug( __METHOD__ . ": unable to identify type of ZIP archive\n" );
                }
                return $mime;
        }
@@ -872,7 +871,7 @@ class MimeMagic {
                global $wgMimeDetectorCommand;
 
                if ( $ext ) { # TODO:  make $ext default to false. Or better, remove it.
-                       wfDebug( __METHOD__.": WARNING: use of the \$ext parameter is deprecated. Use improveTypeFromExtension(\$mime, \$ext) instead.\n" );
+                       wfDebug( __METHOD__ . ": WARNING: use of the \$ext parameter is deprecated. Use improveTypeFromExtension(\$mime, \$ext) instead.\n" );
                }
 
                $m = null;
@@ -898,7 +897,7 @@ class MimeMagic {
                                $m = finfo_file( $mime_magic_resource, $file );
                                finfo_close( $mime_magic_resource );
                        } else {
-                               wfDebug( __METHOD__.": finfo_open failed on ".FILEINFO_MIME."!\n" );
+                               wfDebug( __METHOD__ . ": finfo_open failed on ".FILEINFO_MIME."!\n" );
                        }
                } elseif ( function_exists( "mime_content_type" ) ) {
 
@@ -911,9 +910,9 @@ class MimeMagic {
                        # Also note that this has been DEPRECATED in favor of the fileinfo extension by PECL, see above.
                        # see http://www.php.net/manual/en/ref.mime-magic.php for details.
 
-                       $m = mime_content_type($file);
+                       $m = mime_content_type( $file );
                } else {
-                       wfDebug( __METHOD__.": no magic mime detector found!\n" );
+                       wfDebug( __METHOD__ . ": no magic mime detector found!\n" );
                }
 
                if ( $m ) {
@@ -925,7 +924,7 @@ class MimeMagic {
                        if ( strpos( $m, 'unknown' ) !== false ) {
                                $m = null;
                        } else {
-                               wfDebug( __METHOD__.": magic mime type of $file: $m\n" );
+                               wfDebug( __METHOD__ . ": magic mime type of $file: $m\n" );
                                return $m;
                        }
                }
@@ -937,11 +936,11 @@ class MimeMagic {
                }
                if ( $ext ) {
                        if( $this->isRecognizableExtension( $ext ) ) {
-                               wfDebug( __METHOD__. ": refusing to guess mime type for .$ext file, we should have recognized it\n" );
+                               wfDebug( __METHOD__ . ": refusing to guess mime type for .$ext file, we should have recognized it\n" );
                        } else {
                                $m = $this->guessTypesForExtension( $ext );
                                if ( $m ) {
-                                       wfDebug( __METHOD__.": extension mime type of $file: $m\n" );
+                                       wfDebug( __METHOD__ . ": extension mime type of $file: $m\n" );
                                        return $m;
                                }
                        }
@@ -1066,7 +1065,7 @@ class MimeMagic {
 
                foreach ( $m as $mime ) {
                        foreach ( $this->mMediaTypes as $type => $codes ) {
-                               if ( in_array($mime, $codes, true ) ) {
+                               if ( in_array( $mime, $codes, true ) ) {
                                        return $type;
                                }
                        }
index 46af002..e35bf07 100644 (file)
@@ -67,7 +67,7 @@ class MWNamespace {
        public static function isMovable( $index ) {
                global $wgAllowImageMoving;
 
-               $result = !( $index < NS_MAIN || ( $index == NS_FILE && !$wgAllowImageMoving )  || $index == NS_CATEGORY );
+               $result = !( $index < NS_MAIN || ( $index == NS_FILE && !$wgAllowImageMoving ) || $index == NS_CATEGORY );
 
                /**
                 * @since 1.20
@@ -290,9 +290,9 @@ class MWNamespace {
         * @param $index Int: namespace index
         * @return bool
         */
-        public static function canTalk( $index ) {
+       public static function canTalk( $index ) {
                return $index >= NS_MAIN;
-        }
+       }
 
        /**
         * Does this namespace contain content, for the purposes of calculating
index 968acf6..577d610 100644 (file)
@@ -1275,7 +1275,7 @@ class OutputPage extends ContextSource {
         * @param  $level Int ResourceLoaderModule class constant
         */
        public function reduceAllowedModules( $type, $level ) {
-               $this->mAllowedModules[$type] = min( $this->getAllowedModules($type), $level );
+               $this->mAllowedModules[$type] = min( $this->getAllowedModules( $type ), $level );
        }
 
        /**
@@ -1873,7 +1873,7 @@ class OutputPage extends ContextSource {
                                        wfDebug( __METHOD__ . ": proxy caching with ESI; {$this->mLastModified} **\n", false );
                                        # start with a shorter timeout for initial testing
                                        # header( 'Surrogate-Control: max-age=2678400+2678400, content="ESI/1.0"');
-                                       $response->header( 'Surrogate-Control: max-age='.$wgSquidMaxage.'+'.$this->mSquidMaxage.', content="ESI/1.0"');
+                                       $response->header( 'Surrogate-Control: max-age=' . $wgSquidMaxage . '+' . $this->mSquidMaxage . ', content="ESI/1.0"' );
                                        $response->header( 'Cache-Control: s-maxage=0, must-revalidate, max-age=0' );
                                } else {
                                        # We'll purge the proxy cache for anons explicitly, but require end user agents
@@ -1883,7 +1883,7 @@ class OutputPage extends ContextSource {
                                        wfDebug( __METHOD__ . ": local proxy caching; {$this->mLastModified} **\n", false );
                                        # start with a shorter timeout for initial testing
                                        # header( "Cache-Control: s-maxage=2678400, must-revalidate, max-age=0" );
-                                       $response->header( 'Cache-Control: s-maxage='.$this->mSquidMaxage.', must-revalidate, max-age=0' );
+                                       $response->header( 'Cache-Control: s-maxage=' . $this->mSquidMaxage . ', must-revalidate, max-age=0' );
                                }
                        } else {
                                # We do want clients to cache if they can, but they *must* check for updates
@@ -1892,7 +1892,7 @@ class OutputPage extends ContextSource {
                                $response->header( 'Expires: ' . gmdate( 'D, d M Y H:i:s', 0 ) . ' GMT' );
                                $response->header( "Cache-Control: private, must-revalidate, max-age=0" );
                        }
-                       if($this->mLastModified) {
+                       if( $this->mLastModified ) {
                                $response->header( "Last-Modified: {$this->mLastModified}" );
                        }
                } else {
@@ -2272,7 +2272,7 @@ class OutputPage extends ContextSource {
 
                        $pageLang = $this->getTitle()->getPageLanguage();
                        $params = array(
-                               'id'   => 'wpTextbox1',
+                               'id' => 'wpTextbox1',
                                'name' => 'wpTextbox1',
                                'cols' => $this->getUser()->getOption( 'cols' ),
                                'rows' => $this->getUser()->getOption( 'rows' ),
@@ -3066,7 +3066,7 @@ $templates
                                        'http-equiv' => 'Content-Type',
                                        'content' => "$wgMimeType; charset=UTF-8"
                                ) );
-                               $tags['meta-content-style-type'] = Html::element( 'meta', array(  // bug 15835
+                               $tags['meta-content-style-type'] = Html::element( 'meta', array( // bug 15835
                                        'http-equiv' => 'Content-Style-Type',
                                        'content' => 'text/css'
                                ) );
@@ -3095,7 +3095,7 @@ $templates
                        );
                        $tags['meta-keywords'] = Html::element( 'meta', array(
                                'name' => 'keywords',
-                               'content' =>  preg_replace(
+                               'content' => preg_replace(
                                        array_keys( $strip ),
                                        array_values( $strip ),
                                        implode( ',', $this->mKeywords )
@@ -3629,7 +3629,7 @@ $templates
                                                '1.20'
                                        );
                                }
-                       }  else {
+                       } else {
                                $args = array();
                                $name = $spec;
                        }
index 856b1b8..9e937e4 100644 (file)
@@ -866,7 +866,7 @@ abstract class ReverseChronologicalPager extends IndexPager {
                if ( $this->mMonth ) {
                        $month = $this->mMonth + 1;
                        // For December, we want January 1 of the next year
-                       if ($month > 12) {
+                       if ( $month > 12 ) {
                                $month = 1;
                                $year++;
                        }
index 2dbc7ec..3be504a 100644 (file)
@@ -293,7 +293,7 @@ class PathRouter {
                        foreach ( $m as $matchKey => $matchValue ) {
                                if ( preg_match( '/^par\d+$/u', $matchKey ) ) {
                                        $n = intval( substr( $matchKey, 3 ) );
-                                       $data['$'.$n] = rawurldecode( $matchValue );
+                                       $data['$' . $n] = rawurldecode( $matchValue );
                                }
                        }
                        // If present give our $data array a $key as well
index c15c5b5..76e1760 100644 (file)
@@ -359,7 +359,7 @@ class Preferences {
                if ( $wgEnableEmail ) {
                        $helpMessages[] = $wgEmailConfirmToEdit
                                        ? 'prefs-help-email-required'
-                                       : 'prefs-help-email' ;
+                                       : 'prefs-help-email';
 
                        if( $wgEnableUserEmail ) {
                                // additional messages when users can send email to each other
@@ -891,7 +891,7 @@ class Preferences {
                        'max' => $watchlistdaysMax,
                        'section' => 'watchlist/displaywatchlist',
                        'help' => $context->msg( 'prefs-watchlist-days-max' )->numParams(
-                                                $watchlistdaysMax )->text(),
+                               $watchlistdaysMax )->text(),
                        'label-message' => 'prefs-watchlist-days',
                );
                $defaultPreferences['wllimit'] = array(
index 5d4b35c..7df6a50 100644 (file)
@@ -45,7 +45,7 @@ class PrefixSearch {
                // Find a Title which is not an interwiki and is in NS_MAIN
                $title = Title::newFromText( $search );
                if( $title && $title->getInterwiki() == '' ) {
-                       $ns = array($title->getNamespace());
+                       $ns = array( $title->getNamespace() );
                        if( $ns[0] == NS_MAIN ) {
                                $ns = $namespaces; // no explicit prefix, use default namespaces
                        }
index fe871b9..17e4372 100644 (file)
@@ -139,7 +139,7 @@ class ProtectionForm {
                                        if( !$wgUser->isAllowedAny( 'protect', 'editprotected' ) )
                                                continue;
                                } else {
-                                       if( !$wgUser->isAllowed($val) )
+                                       if( !$wgUser->isAllowed( $val ) )
                                                continue;
                                }
                                $this->mRestrictions[$action] = $val;
@@ -228,14 +228,14 @@ class ProtectionForm {
                }
 
                list( $cascadeSources, /* $restrictions */ ) = $this->mTitle->getCascadeProtectionSources();
-               if ( $cascadeSources && count($cascadeSources) > 0 ) {
+               if ( $cascadeSources && count( $cascadeSources ) > 0 ) {
                        $titles = '';
 
                        foreach ( $cascadeSources as $title ) {
                                $titles .= '* [[:' . $title->getPrefixedText() . "]]\n";
                        }
 
-                       $wgOut->wrapWikiMsg( "<div id=\"mw-protect-cascadeon\">\n$1\n" . $titles . "</div>", array( 'protect-cascadeon', count($cascadeSources) ) );
+                       $wgOut->wrapWikiMsg( "<div id=\"mw-protect-cascadeon\">\n$1\n" . $titles . "</div>", array( 'protect-cascadeon', count( $cascadeSources ) ) );
                }
 
                # Show an appropriate message if the user isn't allowed or able to change
@@ -284,7 +284,7 @@ class ProtectionForm {
                $expiry = array();
                foreach( $this->mApplicableTypes as $action ) {
                        $expiry[$action] = $this->getExpiry( $action );
-                       if( empty($this->mRestrictions[$action]) )
+                       if( empty( $this->mRestrictions[$action] ) )
                                continue; // unprotected
                        if ( !$expiry[$action] ) {
                                $this->show( array( 'protect_expiry_invalid' ) );
@@ -300,7 +300,7 @@ class ProtectionForm {
                #  to a semi-protected page.
                $edit_restriction = isset( $this->mRestrictions['edit'] ) ? $this->mRestrictions['edit'] : '';
                $this->mCascade = $wgRequest->getBool( 'mwProtect-cascade' );
-               if ($this->mCascade && ($edit_restriction != 'protect') &&
+               if ( $this->mCascade && ($edit_restriction != 'protect') &&
                        !User::groupHasPermission( $edit_restriction, 'protect' ) )
                        $this->mCascade = false;
 
@@ -412,14 +412,14 @@ class ProtectionForm {
                                wfMessage( 'protect-othertime-op' )->text(),
                                "othertime"
                        ) . "\n";
-                       foreach( explode(',', $scExpiryOptions) as $option ) {
-                               if ( strpos($option, ":") === false ) {
+                       foreach( explode( ',', $scExpiryOptions ) as $option ) {
+                               if ( strpos( $option, ":" ) === false ) {
                                        $show = $value = $option;
                                } else {
-                                       list($show, $value) = explode(":", $option);
+                                       list( $show, $value ) = explode( ":", $option );
                                }
-                               $show = htmlspecialchars($show);
-                               $value = htmlspecialchars($value);
+                               $show = htmlspecialchars( $show );
+                               $value = htmlspecialchars( $value );
                                $expiryFormOptions .= Xml::option( $show, $value, $this->mExpirySelection[$action] === $value ) . "\n";
                        }
                        # Add expiry dropdown
@@ -458,7 +458,7 @@ class ProtectionForm {
                        "</td></tr>";
                }
                # Give extensions a chance to add items to the form
-               wfRunHooks( 'ProtectionForm::buildForm', array($this->mArticle,&$out) );
+               wfRunHooks( 'ProtectionForm::buildForm', array( $this->mArticle, &$out ) );
 
                $out .= Xml::closeElement( 'tbody' ) . Xml::closeElement( 'table' );
 
@@ -569,7 +569,7 @@ class ProtectionForm {
                                if( !$wgUser->isAllowedAny( 'protect', 'editprotected' ) && !$this->disabled )
                                        continue;
                        } else {
-                               if( !$wgUser->isAllowed($key) && !$this->disabled )
+                               if( !$wgUser->isAllowed( $key ) && !$this->disabled )
                                        continue;
                        }
                        $levels[] = $key;
@@ -644,6 +644,6 @@ class ProtectionForm {
                $out->addHTML( Xml::element( 'h2', null, $protectLogPage->getName()->text() ) );
                LogEventsList::showLogExtract( $out, 'protect', $this->mTitle );
                # Let extensions add other relevant log extracts
-               wfRunHooks( 'ProtectionForm::showLogExtract', array($this->mArticle,$out) );
+               wfRunHooks( 'ProtectionForm::showLogExtract', array( $this->mArticle, $out ) );
        }
 }
index 349789f..1a147b1 100644 (file)
@@ -109,7 +109,7 @@ function wfProxyCheck() {
        if ( !$skip ) {
                $title = SpecialPage::getTitleFor( 'Blockme' );
                $iphash = md5( $ip . $wgProxyKey );
-               $url = wfExpandUrl( $title->getFullURL( 'ip='.$iphash ), PROTO_HTTP );
+               $url = wfExpandUrl( $title->getFullURL( 'ip=' . $iphash ), PROTO_HTTP );
 
                foreach ( $wgProxyPorts as $port ) {
                        $params = implode( ' ', array(
index 56df21e..f63e95c 100644 (file)
@@ -80,7 +80,7 @@ class RecentChange {
         * @var Title
         */
        var $mMovedToTitle = false;
-       var $numberofWatchingusers = 0 ; # Dummy to prevent error message in SpecialRecentchangeslinked
+       var $numberofWatchingusers = 0; # Dummy to prevent error message in SpecialRecentchangeslinked
        var $notificationtimestamp;
 
        # Factory methods
@@ -712,7 +712,7 @@ class RecentChange {
                        $trail = "curid=" . (int)( $this->mAttribs['rc_cur_id'] ) .
                                "&oldid=" . (int)( $this->mAttribs['rc_last_oldid'] );
                        if ( $forceCur ) {
-                               $trail .= '&diff=0' ;
+                               $trail .= '&diff=0';
                        } else {
                                $trail .= '&diff=' . (int)( $this->mAttribs['rc_this_oldid'] );
                        }
@@ -761,10 +761,10 @@ class RecentChange {
                        if ( $szdiff < -500 ) {
                                $szdiff = "\002$szdiff\002";
                        } elseif ( $szdiff >= 0 ) {
-                               $szdiff = '+' . $szdiff ;
+                               $szdiff = '+' . $szdiff;
                        }
                        // @todo i18n with parentheses in content language?
-                       $szdiff = '(' . $szdiff . ')' ;
+                       $szdiff = '(' . $szdiff . ')';
                } else {
                        $szdiff = '';
                }
@@ -800,7 +800,7 @@ class RecentChange {
                # see http://www.irssi.org/documentation/formats for some colour codes. prefix is \003,
                # no colour (\003) switches back to the term default
                $fullString = "$titleString\0034 $flag\00310 " .
-                                         "\00302$url\003 \0035*\003 \00303$user\003 \0035*\003 $szdiff \00310$comment\003\n";
+                       "\00302$url\003 \0035*\003 \00303$user\003 \0035*\003 $szdiff \00310$comment\003\n";
 
                return $fullString;
        }
index 5f62e4d..4bdce87 100644 (file)
@@ -254,9 +254,11 @@ class Revision implements IDBAccessObject {
                        $matchId = 'page_latest';
                }
                return self::loadFromConds( $db,
-                       array( "rev_id=$matchId",
-                                  'page_namespace' => $title->getNamespace(),
-                                  'page_title'     => $title->getDBkey() )
+                       array(
+                               "rev_id=$matchId",
+                               'page_namespace' => $title->getNamespace(),
+                               'page_title'     => $title->getDBkey()
+                       )
                );
        }
 
@@ -272,9 +274,11 @@ class Revision implements IDBAccessObject {
         */
        public static function loadFromTimestamp( $db, $title, $timestamp ) {
                return self::loadFromConds( $db,
-                       array( 'rev_timestamp'  => $db->timestamp( $timestamp ),
-                                  'page_namespace' => $title->getNamespace(),
-                                  'page_title'     => $title->getDBkey() )
+                       array(
+                               'rev_timestamp'  => $db->timestamp( $timestamp ),
+                               'page_namespace' => $title->getNamespace(),
+                               'page_title'     => $title->getDBkey()
+                       )
                );
        }
 
@@ -330,9 +334,11 @@ class Revision implements IDBAccessObject {
        public static function fetchRevision( $title ) {
                return self::fetchFromConds(
                        wfGetDB( DB_SLAVE ),
-                       array( 'rev_id=page_latest',
-                                  'page_namespace' => $title->getNamespace(),
-                                  'page_title'     => $title->getDBkey() )
+                       array(
+                               'rev_id=page_latest',
+                               'page_namespace' => $title->getNamespace(),
+                               'page_title'     => $title->getDBkey()
+                       )
                );
        }
 
@@ -496,7 +502,7 @@ class Revision implements IDBAccessObject {
                        if ( !isset( $row->rev_parent_id ) ) {
                                $this->mParentId = null;
                        } else {
-                               $this->mParentId  = intval( $row->rev_parent_id );
+                               $this->mParentId = intval( $row->rev_parent_id );
                        }
 
                        if ( !isset( $row->rev_len ) ) {
@@ -532,7 +538,7 @@ class Revision implements IDBAccessObject {
                        }
 
                        // Lazy extraction...
-                       $this->mText      = null;
+                       $this->mText = null;
                        if( isset( $row->old_text ) ) {
                                $this->mTextRow = $row;
                        } else {
@@ -557,8 +563,8 @@ class Revision implements IDBAccessObject {
                        if ( !empty( $row['content'] ) ) {
                                //@todo: when is that set? test with external store setup! check out insertOn() [dk]
                                if ( !empty( $row['text_id'] ) ) {
-                                       throw new MWException( "Text already stored in external store (id {$row['text_id']}), "
-                                                                                       . "can't serialize content object" );
+                                       throw new MWException( "Text already stored in external store (id {$row['text_id']}), " .
+                                               "can't serialize content object" );
                                }
 
                                $row['content_model'] = $row['content']->getModel();
@@ -615,12 +621,12 @@ class Revision implements IDBAccessObject {
                                } elseif ( $this->mTitle->getArticleID() !== $this->mPage ) {
                                        // Got different page IDs. This may be legit (e.g. during undeletion),
                                        // but it seems worth mentioning it in the log.
-                                       wfDebug( "Page ID " . $this->mPage . " mismatches the ID "
-                                                       . $this->mTitle->getArticleID() . " provided by the Title object." );
+                                       wfDebug( "Page ID " . $this->mPage . " mismatches the ID " .
+                                               $this->mTitle->getArticleID() . " provided by the Title object." );
                                }
                        }
 
-                       $this->mCurrent   = false;
+                       $this->mCurrent = false;
 
                        // If we still have no length, see it we have the text to figure it out
                        if ( !$this->mSize ) {
@@ -718,7 +724,7 @@ class Revision implements IDBAccessObject {
                                array( 'page', 'revision' ),
                                self::selectPageFields(),
                                array( 'page_id=rev_page',
-                                          'rev_id' => $this->mId ),
+                                       'rev_id' => $this->mId ),
                                __METHOD__ );
                        if ( $row ) {
                                $this->mTitle = Title::newFromRow( $row );
index 9cac308..b50eca8 100644 (file)
@@ -381,7 +381,7 @@ class Sanitizer {
                                'h2', 'h3', 'h4', 'h5', 'h6', 'cite', 'code', 'em', 's',
                                'strike', 'strong', 'tt', 'var', 'div', 'center',
                                'blockquote', 'ol', 'ul', 'dl', 'table', 'caption', 'pre',
-                               'ruby', 'rt' , 'rb' , 'rp', 'p', 'span', 'abbr', 'dfn',
+                               'ruby', 'rt', 'rb', 'rp', 'p', 'span', 'abbr', 'dfn',
                                'kbd', 'samp'
                        );
                        if ( $wgHtml5 ) {
@@ -604,9 +604,9 @@ class Sanitizer {
         */
        static function removeHTMLcomments( $text ) {
                wfProfileIn( __METHOD__ );
-               while (($start = strpos($text, '<!--')) !== false) {
-                       $end = strpos($text, '-->', $start + 4);
-                       if ($end === false) {
+               while ( ($start = strpos( $text, '<!--' ) ) !== false ) {
+                       $end = strpos( $text, '-->', $start + 4 );
+                       if ( $end === false ) {
                                # Unterminated comment; bail out
                                break;
                        }
@@ -615,22 +615,22 @@ class Sanitizer {
 
                        # Trim space and newline if the comment is both
                        # preceded and followed by a newline
-                       $spaceStart = max($start - 1, 0);
+                       $spaceStart = max( $start - 1, 0 );
                        $spaceLen = $end - $spaceStart;
-                       while (substr($text, $spaceStart, 1) === ' ' && $spaceStart > 0) {
+                       while ( substr( $text, $spaceStart, 1 ) === ' ' && $spaceStart > 0 ) {
                                $spaceStart--;
                                $spaceLen++;
                        }
-                       while (substr($text, $spaceStart + $spaceLen, 1) === ' ')
+                       while ( substr( $text, $spaceStart + $spaceLen, 1 ) === ' ' )
                                $spaceLen++;
-                       if (substr($text, $spaceStart, 1) === "\n" and substr($text, $spaceStart + $spaceLen, 1) === "\n") {
+                       if ( substr( $text, $spaceStart, 1 ) === "\n" and substr( $text, $spaceStart + $spaceLen, 1 ) === "\n" ) {
                                # Remove the comment, leading and trailing
                                # spaces, and leave only one newline.
-                               $text = substr_replace($text, "\n", $spaceStart, $spaceLen + 1);
+                               $text = substr_replace( $text, "\n", $spaceStart, $spaceLen + 1 );
                        }
                        else {
                                # Remove just the comment.
-                               $text = substr_replace($text, '', $start, $end - $start);
+                               $text = substr_replace( $text, '', $start, $end - $start );
                        }
                }
                wfProfileOut( __METHOD__ );
@@ -1059,10 +1059,10 @@ class Sanitizer {
         */
        static function escapeClass( $class ) {
                // Convert ugly stuff to underscores and kill underscores in ugly places
-               return rtrim(preg_replace(
-                       array('/(^[0-9\\-])|[\\x00-\\x20!"#$%&\'()*+,.\\/:;<=>?@[\\]^`{|}~]|\\xC2\\xA0/','/_+/'),
+               return rtrim( preg_replace(
+                       array( '/(^[0-9\\-])|[\\x00-\\x20!"#$%&\'()*+,.\\/:;<=>?@[\\]^`{|}~]|\\xC2\\xA0/', '/_+/' ),
                        '_',
-                       $class ), '_');
+                       $class ), '_' );
        }
 
        /**
@@ -1227,7 +1227,7 @@ class Sanitizer {
                        $ret = Sanitizer::normalizeEntity( $matches[1] );
                } elseif( $matches[2] != '' ) {
                        $ret = Sanitizer::decCharReference( $matches[2] );
-               } elseif( $matches[3] != ''  ) {
+               } elseif( $matches[3] != '' ) {
                        $ret = Sanitizer::hexCharReference( $matches[3] );
                }
                if( is_null( $ret ) ) {
@@ -1347,7 +1347,7 @@ class Sanitizer {
                        return Sanitizer::decodeEntity( $matches[1] );
                } elseif( $matches[2] != '' ) {
                        return  Sanitizer::decodeChar( intval( $matches[2] ) );
-               } elseif( $matches[3] != ''  ) {
+               } elseif( $matches[3] != '' ) {
                        return  Sanitizer::decodeChar( hexdec( $matches[3] ) );
                }
                # Last case should be an ampersand by itself
@@ -1736,8 +1736,8 @@ class Sanitizer {
                // Please note strings below are enclosed in brackets [], this make the
                // hyphen "-" a range indicator. Hence it is double backslashed below.
                // See bug 26948
-               $rfc5322_atext   = "a-z0-9!#$%&'*+\\-\/=?^_`{|}~" ;
-               $rfc1034_ldh_str = "a-z0-9\\-" ;
+               $rfc5322_atext   = "a-z0-9!#$%&'*+\\-\/=?^_`{|}~";
+               $rfc1034_ldh_str = "a-z0-9\\-";
 
                $HTML5_email_regexp = "/
                ^                      # start of string
@@ -1746,7 +1746,7 @@ class Sanitizer {
                [$rfc1034_ldh_str]+       # First domain part
                (\\.[$rfc1034_ldh_str]+)*  # Following part prefixed with a dot
                $                      # End of string
-               /ix" ; // case Insensitive, eXtended
+               /ix"; // case Insensitive, eXtended
 
                return (bool) preg_match( $HTML5_email_regexp, $addr );
        }
index 53739fb..7f4d634 100644 (file)
@@ -56,16 +56,16 @@ if ( $wgArticlePath === false ) {
        }
 }
 
-if ( !empty($wgActionPaths) && !isset($wgActionPaths['view']) ) {
+if ( !empty( $wgActionPaths ) && !isset( $wgActionPaths['view'] ) ) {
        # 'view' is assumed the default action path everywhere in the code
        # but is rarely filled in $wgActionPaths
        $wgActionPaths['view'] = $wgArticlePath;
 }
 
-if ( !empty($wgActionPaths) && !isset($wgActionPaths['view']) ) {
+if ( !empty( $wgActionPaths ) && !isset( $wgActionPaths['view'] ) ) {
        # 'view' is assumed the default action path everywhere in the code
        # but is rarely filled in $wgActionPaths
-       $wgActionPaths['view'] = $wgArticlePath ;
+       $wgActionPaths['view'] = $wgArticlePath;
 }
 
 if ( $wgStylePath === false ) $wgStylePath = "$wgScriptPath/skins";
@@ -353,9 +353,9 @@ if ( $wgAjaxUploadDestCheck ) {
 
 if ( $wgNewUserLog ) {
        # Add a new log type
-       $wgLogTypes[]                        = 'newusers';
-       $wgLogNames['newusers']              = 'newuserlogpage';
-       $wgLogHeaders['newusers']            = 'newuserlogpagetext';
+       $wgLogTypes[] = 'newusers';
+       $wgLogNames['newusers'] = 'newuserlogpage';
+       $wgLogHeaders['newusers'] = 'newuserlogpagetext';
        $wgLogActionsHandlers['newusers/newusers'] = 'NewUsersLogFormatter';
        $wgLogActionsHandlers['newusers/create'] = 'NewUsersLogFormatter';
        $wgLogActionsHandlers['newusers/create2'] = 'NewUsersLogFormatter';
index 4bbe9e1..7e96d45 100644 (file)
@@ -83,7 +83,7 @@
  * $conf->settings = array(
  *     'wgMergeSetting' = array(
  *             # Value that will be shared among all wikis:
- *             'default' => array(  NS_USER => true ),
+ *             'default' => array( NS_USER => true ),
  *
  *             # Leading '+' means merging the array of value with the defaults
  *             '+beta' => array( NS_HELP => true ),
@@ -205,7 +205,7 @@ class SiteConfiguration {
                                                        $retval = $thisSetting[$tag];
                                                }
                                                break 2;
-                                       } elseif( array_key_exists( "+$tag", $thisSetting ) && is_array($thisSetting["+$tag"]) ) {
+                                       } elseif( array_key_exists( "+$tag", $thisSetting ) && is_array( $thisSetting["+$tag"] ) ) {
                                                if( !isset( $retval ) ) {
                                                        $retval = array();
                                                }
@@ -216,7 +216,7 @@ class SiteConfiguration {
                                $suffix = $params['suffix'];
                                if( !is_null( $suffix ) ) {
                                        if( array_key_exists( $suffix, $thisSetting ) ) {
-                                               if ( isset($retval) && is_array($retval) && is_array($thisSetting[$suffix]) ) {
+                                               if ( isset( $retval ) && is_array( $retval ) && is_array( $thisSetting[$suffix] ) ) {
                                                        $retval = self::arrayMerge( $retval, $thisSetting[$suffix] );
                                                } else {
                                                        $retval = $thisSetting[$suffix];
@@ -509,9 +509,9 @@ class SiteConfiguration {
                $out = $array1;
                for( $i = 1; $i < func_num_args(); $i++ ) {
                        foreach( func_get_arg( $i ) as $key => $value ) {
-                               if ( isset($out[$key]) && is_array($out[$key]) && is_array($value) ) {
+                               if ( isset( $out[$key] ) && is_array( $out[$key] ) && is_array( $value ) ) {
                                        $out[$key] = self::arrayMerge( $out[$key], $value );
-                               } elseif ( !isset($out[$key]) || !$out[$key] && !is_numeric($key) ) {
+                               } elseif ( !isset( $out[$key] ) || !$out[$key] && !is_numeric( $key ) ) {
                                        // Values that evaluate to true given precedence, for the primary purpose of merging permissions arrays.
                                        $out[$key] = $value;
                                } elseif ( is_numeric( $key ) ) {
index 4889863..723ede4 100644 (file)
@@ -262,7 +262,7 @@ abstract class Skin extends ContextSource {
         * @return Title
         */
        public function getRelevantTitle() {
-               if ( isset($this->mRelevantTitle) ) {
+               if ( isset( $this->mRelevantTitle ) ) {
                        return $this->mRelevantTitle;
                }
                return $this->getTitle();
@@ -286,7 +286,7 @@ abstract class Skin extends ContextSource {
         * @return User
         */
        public function getRelevantUser() {
-               if ( isset($this->mRelevantUser) ) {
+               if ( isset( $this->mRelevantUser ) ) {
                        return $this->mRelevantUser;
                }
                $title = $this->getRelevantTitle();
@@ -435,7 +435,7 @@ abstract class Skin extends ContextSource {
                $colon = $this->msg( 'colon-separator' )->escaped();
 
                if ( !empty( $allCats['normal'] ) ) {
-                       $t = $embed . implode( "{$pop}{$embed}" , $allCats['normal'] ) . $pop;
+                       $t = $embed . implode( "{$pop}{$embed}", $allCats['normal'] ) . $pop;
 
                        $msg = $this->msg( 'pagecategories' )->numParams( count( $allCats['normal'] ) )->escaped();
                        $linkPage = wfMessage( 'pagecategorieslink' )->inContentLanguage()->text();
@@ -456,7 +456,7 @@ abstract class Skin extends ContextSource {
 
                        $s .= "<div id=\"mw-hidden-catlinks\" class=\"mw-hidden-catlinks$class\">" .
                                $this->msg( 'hidden-categories' )->numParams( count( $allCats['hidden'] ) )->escaped() .
-                               $colon . '<ul>' . $embed . implode( "{$pop}{$embed}" , $allCats['hidden'] ) . $pop . '</ul>' .
+                               $colon . '<ul>' . $embed . implode( "{$pop}{$embed}", $allCats['hidden'] ) . $pop . '</ul>' .
                                '</div>';
                }
 
@@ -499,7 +499,7 @@ abstract class Skin extends ContextSource {
 
                        # add our current element to the list
                        $eltitle = Title::newFromText( $element );
-                       $return .=  Linker::link( $eltitle, htmlspecialchars( $eltitle->getText() ) );
+                       $return .= Linker::link( $eltitle, htmlspecialchars( $eltitle->getText() ) );
                }
 
                return $return;
@@ -860,7 +860,7 @@ abstract class Skin extends ContextSource {
                if ( is_string( $icon ) ) {
                        $html = $icon;
                } else { // Assuming array
-                       $url = isset($icon["url"]) ? $icon["url"] : null;
+                       $url = isset( $icon["url"] ) ? $icon["url"] : null;
                        unset( $icon["url"] );
                        if ( isset( $icon["src"] ) && $withImage === 'withImage' ) {
                                $html = Html::element( 'img', $icon ); // do this the lazy way, just pass icon data as an attribute array
index 8642eca..c1c7219 100644 (file)
@@ -120,7 +120,7 @@ class LegacyTemplate extends BaseTemplate {
                }
 
                $s .= "\n<div id='content'>\n<div id='topbar'>\n" .
-                 "<table cellspacing='0' style='width: 100%;'>\n<tr>\n";
+                       "<table cellspacing='0' style='width: 100%;'>\n<tr>\n";
 
                if ( $this->getSkin()->qbSetting() == 0 ) {
                        $s .= "<td class='top' style='text-align: left; vertical-align: top;' rowspan='{$rows}'>\n" .
@@ -179,10 +179,10 @@ class LegacyTemplate extends BaseTemplate {
                $search = $wgRequest->getText( 'search' );
 
                $s = '<form id="searchform' . $this->searchboxes . '" name="search" class="inline" method="post" action="'
-                 . $this->getSkin()->escapeSearchLink() . "\">\n"
-                 . '<input type="text" id="searchInput' . $this->searchboxes . '" name="search" size="19" value="'
-                 . htmlspecialchars( substr( $search, 0, 256 ) ) . "\" />\n"
-                 . '<input type="submit" name="go" value="' . wfMessage( 'searcharticle' )->text() . '" />';
+                       . $this->getSkin()->escapeSearchLink() . "\">\n"
+                       . '<input type="text" id="searchInput' . $this->searchboxes . '" name="search" size="19" value="'
+                       . htmlspecialchars( substr( $search, 0, 256 ) ) . "\" />\n"
+                       . '<input type="submit" name="go" value="' . wfMessage( 'searcharticle' )->text() . '" />';
 
                if ( $wgUseTwoButtonsSearchForm ) {
                        $s .= '&#160;<input type="submit" name="fulltext" value="' . wfMessage( 'searchbutton' )->text() . "\" />\n";
@@ -263,7 +263,7 @@ class LegacyTemplate extends BaseTemplate {
                                }
                                $s = $wgLang->pipeList( array(
                                        $s,
-                                       '<a href="' . htmlspecialchars( $title->getLocalURL( 'variant=' . $code ) ) . '" lang="' . $code . '" hreflang="' . $code .  '">' . htmlspecialchars( $varname ) . '</a>'
+                                       '<a href="' . htmlspecialchars( $title->getLocalURL( 'variant=' . $code ) ) . '" lang="' . $code . '" hreflang="' . $code . '">' . htmlspecialchars( $varname ) . '</a>'
                                ) );
                        }
                }
index a673a65..86972ee 100644 (file)
@@ -219,7 +219,7 @@ class SkinTemplate extends Skin {
                if ( $subpagestr !== '' ) {
                        $subpagestr = '<span class="subpages">' . $subpagestr . '</span>';
                }
-               $tpl->set( 'subtitle',  $subpagestr . $out->getSubtitle() );
+               $tpl->set( 'subtitle', $subpagestr . $out->getSubtitle() );
 
                $undelete = $this->getUndeleteLink();
                if ( $undelete === '' ) {
@@ -403,7 +403,7 @@ class SkinTemplate extends Skin {
                        $pageLang = $title->getPageViewLanguage();
                        $realBodyAttribs['lang'] = $pageLang->getHtmlCode();
                        $realBodyAttribs['dir'] = $pageLang->getDir();
-                       $realBodyAttribs['class'] = 'mw-content-'.$pageLang->getDir();
+                       $realBodyAttribs['class'] = 'mw-content-' . $pageLang->getDir();
                }
 
                $out->mBodytext = Html::rawElement( 'div', $realBodyAttribs, $out->mBodytext );
@@ -1051,7 +1051,7 @@ class SkinTemplate extends Skin {
                }
 
                // Equiv to SkinTemplateContentActions
-               wfRunHooks( 'SkinTemplateNavigation::Universal', array( &$this,  &$content_navigation ) );
+               wfRunHooks( 'SkinTemplateNavigation::Universal', array( &$this, &$content_navigation ) );
 
                // Setup xml ids and tooltip info
                foreach ( $content_navigation as $section => &$links ) {
index 338b50d..3b3a5ee 100644 (file)
@@ -1278,7 +1278,7 @@ class SpecialMytalk extends RedirectSpecialArticle {
  */
 class SpecialMycontributions extends RedirectSpecialPage {
        function __construct() {
-               parent::__construct(  'Mycontributions' );
+               parent::__construct( 'Mycontributions' );
                $this->mAllowedRedirectParams = array( 'limit', 'namespace', 'tagfilter',
                        'offset', 'dir', 'year', 'month', 'feed' );
        }
index fd5d52c..add7efc 100644 (file)
@@ -95,7 +95,7 @@ class SpecialPageFactory {
                'Preferences'               => 'SpecialPreferences',
                'Contributions'             => 'SpecialContributions',
                'Listgrouprights'           => 'SpecialListGroupRights',
-               'Listusers'                 => 'SpecialListUsers' ,
+               'Listusers'                 => 'SpecialListUsers',
                'Listadmins'                => 'SpecialListAdmins',
                'Listbots'                  => 'SpecialListBots',
                'Activeusers'               => 'SpecialActiveUsers',
index d0ead9a..c01cdd0 100644 (file)
@@ -76,7 +76,7 @@ abstract class SqlDataUpdate extends DataUpdate {
 
                // NOTE: nested transactions are not supported, only start a transaction if none is open
                if ( $this->mDb->trxLevel() === 0 ) {
-                       $this->mDb->begin( get_class( $this ) . '::beginTransaction'  );
+                       $this->mDb->begin( get_class( $this ) . '::beginTransaction' );
                        $this->mHasTransaction = true;
                }
        }
index 098fb0b..f5fd195 100644 (file)
@@ -318,7 +318,7 @@ class SquidPurgeClient {
                                return 'done';
                        }
                default:
-                       throw new MWException( __METHOD__.': unexpected state' );
+                       throw new MWException( __METHOD__ . ': unexpected state' );
                }
        }
 
@@ -373,7 +373,7 @@ class SquidPurgeClient {
         * @param $msg string
         */
        protected function log( $msg ) {
-               wfDebugLog( 'squid', __CLASS__." ($this->host): $msg\n" );
+               wfDebugLog( 'squid', __CLASS__ . " ($this->host): $msg\n" );
        }
 }
 
@@ -429,14 +429,14 @@ class SquidPurgeClientPool {
                        $numReady = socket_select( $readSockets, $writeSockets, $exceptSockets, $timeout );
                        wfRestoreWarnings();
                        if ( $numReady === false ) {
-                               wfDebugLog( 'squid', __METHOD__.': Error in stream_select: ' .
+                               wfDebugLog( 'squid', __METHOD__ . ': Error in stream_select: ' .
                                        socket_strerror( socket_last_error() ) . "\n" );
                                break;
                        }
                        // Check for timeout, use 1% tolerance since we aimed at having socket_select()
                        // exit at precisely the overall timeout
                        if ( microtime( true ) - $startTime > $this->timeout * 0.99 ) {
-                               wfDebugLog( 'squid', __CLASS__.": timeout ({$this->timeout}s)\n" );
+                               wfDebugLog( 'squid', __CLASS__ . ": timeout ({$this->timeout}s)\n" );
                                break;
                        } elseif ( !$numReady ) {
                                continue;
index 2553f54..4298aee 100644 (file)
@@ -176,10 +176,10 @@ class Status {
                if ( count( $this->errors ) == 0 ) {
                        if ( $this->ok ) {
                                $this->fatal( 'internalerror_info',
-                                       __METHOD__." called for a good result, this is incorrect\n" );
+                                       __METHOD__ . " called for a good result, this is incorrect\n" );
                        } else {
                                $this->fatal( 'internalerror_info',
-                                       __METHOD__.": Invalid result object: no error text but not OK\n" );
+                                       __METHOD__ . ": Invalid result object: no error text but not OK\n" );
                        }
                }
                if ( count( $this->errors ) == 1 ) {
@@ -190,7 +190,7 @@ class Status {
                                $s = wfMessage( $longContext, "* $s\n" )->plain();
                        }
                } else {
-                       $s = '* '. implode("\n* ",
+                       $s = '* '. implode( "\n* ",
                                $this->getErrorMessageArray( $this->errors ) ) . "\n";
                        if ( $longContext ) {
                                $s = wfMessage( $longContext, $s )->plain();
@@ -216,7 +216,7 @@ class Status {
                                $msg = $error['message'];
                        } elseif ( isset( $error['message'] ) && isset( $error['params'] ) ) {
                                $msg = wfMessage( $error['message'],
-                                       array_map( 'wfEscapeWikiText', $this->cleanParams( $error['params'] ) )  );
+                                       array_map( 'wfEscapeWikiText', $this->cleanParams( $error['params'] ) ) );
                        } else {
                                $msgName = array_shift( $error );
                                $msg = wfMessage( $msgName,
index 54a85dc..6647de4 100644 (file)
@@ -135,12 +135,12 @@ class StringUtils {
                $m = array();
 
                while ( $inputPos < strlen( $subject ) &&
-                 preg_match( "!($encStart)|($encEnd)!S$flags", $subject, $m, PREG_OFFSET_CAPTURE, $inputPos ) )
+                       preg_match( "!($encStart)|($encEnd)!S$flags", $subject, $m, PREG_OFFSET_CAPTURE, $inputPos ) )
                {
                        $tokenOffset = $m[0][1];
                        if ( $m[1][0] != '' ) {
                                if ( $foundStart &&
-                                 $strcmp( $endDelim, substr( $subject, $tokenOffset, $endLength ) ) == 0 )
+                                       $strcmp( $endDelim, substr( $subject, $tokenOffset, $endLength ) ) == 0 )
                                {
                                        # An end match is present at the same location
                                        $tokenType = 'end';
@@ -432,7 +432,7 @@ class ReplacementArray {
         * @param $from string
         */
        function removePair( $from ) {
-               unset($this->data[$from]);
+               unset( $this->data[$from] );
                $this->fss = false;
        }
 
index cc0adb7..8a1e758 100644 (file)
@@ -118,7 +118,7 @@ class StubObject {
                }
 
                if ( get_class( $GLOBALS[$this->mGlobal] ) != $this->mClass ) {
-                       $fname = __METHOD__.'-'.$this->mGlobal;
+                       $fname = __METHOD__ . '-' . $this->mGlobal;
                        wfProfileIn( $fname );
                        $caller = wfGetCaller( $level );
                        if ( ++$recursionLevel > 2 ) {
index 4271555..e0585f1 100644 (file)
@@ -149,7 +149,7 @@ class Title {
                $t->mDbkeyform = str_replace( ' ', '_', $filteredText );
                $t->mDefaultNamespace = $defaultNamespace;
 
-               static $cachedcount = 0 ;
+               static $cachedcount = 0;
                if ( $t->secureAndSplit() ) {
                        if ( $defaultNamespace == NS_MAIN ) {
                                if ( $cachedcount >= self::CACHE_MAX ) {
@@ -1849,7 +1849,7 @@ class Title {
                        $ns = $this->mNamespace == NS_MAIN ?
                                wfMessage( 'nstab-main' )->text() : $this->getNsText();
                        $errors[] = $this->mNamespace == NS_MEDIAWIKI ?
-                               array( 'protectedinterface' ) : array( 'namespaceprotected',  $ns );
+                               array( 'protectedinterface' ) : array( 'namespaceprotected', $ns );
                }
 
                return $errors;
@@ -2343,9 +2343,12 @@ class Title {
 
                if ( !isset( $this->mTitleProtection ) ) {
                        $dbr = wfGetDB( DB_SLAVE );
-                       $res = $dbr->select( 'protected_titles', '*',
+                       $res = $dbr->select(
+                               'protected_titles',
+                               array( 'pt_user', 'pt_reason', 'pt_expiry', 'pt_create_perm' ),
                                array( 'pt_namespace' => $this->getNamespace(), 'pt_title' => $this->getDBkey() ),
-                               __METHOD__ );
+                               __METHOD__
+                       );
 
                        // fetchRow returns false if there are no rows.
                        $this->mTitleProtection = $dbr->fetchRow( $res );
@@ -2735,7 +2738,7 @@ class Title {
 
                                $res = $dbr->select(
                                        'page_restrictions',
-                                       '*',
+                                       array( 'pr_type', 'pr_expiry', 'pr_level', 'pr_cascade' ),
                                        array( 'pr_page' => $this->getArticleID() ),
                                        __METHOD__
                                );
@@ -2777,6 +2780,10 @@ class Title {
         * Purge expired restrictions from the page_restrictions table
         */
        static function purgeExpiredRestrictions() {
+               if ( wfReadOnly() ) {
+                       return;
+               }
+
                $dbw = wfGetDB( DB_MASTER );
                $dbw->delete(
                        'page_restrictions',
@@ -4035,12 +4042,11 @@ class Title {
 
                $dbr = wfGetDB( DB_SLAVE );
 
-               $res = $dbr->select( 'categorylinks', '*',
-                       array(
-                               'cl_from' => $titleKey,
-                       ),
-                       __METHOD__,
-                       array()
+               $res = $dbr->select(
+                       'categorylinks',
+                       'cl_to',
+                       array( 'cl_from' => $titleKey ),
+                       __METHOD__
                );
 
                if ( $res->numRows() > 0 ) {
diff --git a/includes/UIDGenerator.php b/includes/UIDGenerator.php
new file mode 100644 (file)
index 0000000..6134db2
--- /dev/null
@@ -0,0 +1,349 @@
+<?php
+/**
+ * This file deals with UID generation.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ * @file
+ * @author Aaron Schulz
+ */
+
+/**
+ * Class for getting statistically unique IDs
+ *
+ * @since 1.21
+ */
+class UIDGenerator {
+       /** @var UIDGenerator */
+       protected static $instance = null;
+
+       protected $nodeId32; // string; node ID in binary (32 bits)
+       protected $nodeId48; // string; node ID in binary (48 bits)
+
+       protected $lockFile88; // string; local file path
+       protected $lockFile128; // string; local file path
+
+       /** @var Array */
+       protected $fileHandles = array(); // cache file handles
+
+       const QUICK_RAND = 1; // get randomness from fast and unsecure sources
+
+       protected function __construct() {
+               $idFile = wfTempDir() . '/mw-' . __CLASS__ . '-UID-nodeid';
+               $nodeId = is_file( $idFile ) ? file_get_contents( $idFile ) : '';
+               // Try to get some ID that uniquely identifies this machine (RFC 4122)...
+               if ( !preg_match( '/^[0-9a-f]{12}$/i', $nodeId ) ) {
+                       wfSuppressWarnings();
+                       if ( wfIsWindows() ) {
+                               // http://technet.microsoft.com/en-us/library/bb490913.aspx
+                               $csv = trim( wfShellExec( 'getmac /NH /FO CSV' ) );
+                               $line = substr( $csv, 0, strcspn( $csv, "\n" ) );
+                               $info = str_getcsv( $line );
+                               $nodeId = isset( $info[0] ) ? str_replace( '-', '', $info[0] ) : '';
+                       } elseif ( is_executable( '/sbin/ifconfig' ) ) { // Linux/BSD/Solaris/OS X
+                               // See http://linux.die.net/man/8/ifconfig
+                               $m = array();
+                               preg_match( '/\s([0-9a-f]{2}(:[0-9a-f]{2}){5})\s/', wfShellExec( '/sbin/ifconfig -a' ), $m );
+                               $nodeId = isset( $m[1] ) ? str_replace( ':', '', $m[1] ) : '';
+                       }
+                       wfRestoreWarnings();
+                       if ( !preg_match( '/^[0-9a-f]{12}$/i', $nodeId ) ) {
+                               $nodeId = MWCryptRand::generateHex( 12, true );
+                               $nodeId[1] = dechex( hexdec( $nodeId[1] ) | 0x1 ); // set multicast bit
+                       }
+                       file_put_contents( $idFile, $nodeId ); // cache
+               }
+               $this->nodeId32 = wfBaseConvert( substr( sha1( $nodeId ), 0, 8 ), 16, 2, 32 );
+               $this->nodeId48 = wfBaseConvert( $nodeId, 16, 2, 48 );
+               // If different processes run as different users, they may have different temp dirs.
+               // This is dealt with by initializing the clock sequence number and counters randomly.
+               $this->lockFile88 = wfTempDir() . '/mw-' . __CLASS__ . '-UID-88';
+               $this->lockFile128 = wfTempDir() . '/mw-' . __CLASS__ . '-UID-128';
+       }
+
+       /**
+        * @return UIDGenerator
+        */
+       protected static function singleton() {
+               if ( self::$instance === null ) {
+                       self::$instance = new self();
+               }
+               return self::$instance;
+       }
+
+       /**
+        * Get a statistically unique 88-bit unsigned integer ID string.
+        * The bits of the UID are prefixed with the time (down to the millisecond).
+        *
+        * These IDs are suitable as values for the shard key of distributed data.
+        * If a column uses these as values, it should be declared UNIQUE to handle collisions.
+        * New rows almost always have higher UIDs, which makes B-TREE updates on INSERT fast.
+        * They can also be stored "DECIMAL(27) UNSIGNED" or BINARY(11) in MySQL.
+        *
+        * UID generation is serialized on each server (as the node ID is for the whole machine).
+        *
+        * @param $base integer Specifies a base other than 10
+        * @return string Number
+        * @throws MWException
+        */
+       public static function newTimestampedUID88( $base = 10 ) {
+               if ( !is_integer( $base ) || $base > 36 || $base < 2 ) {
+                       throw new MWException( "Base must an integer be between 2 and 36" );
+               }
+               $gen = self::singleton();
+               $time = $gen->getTimestampAndDelay( 'lockFile88', 1, 1024 );
+               return wfBaseConvert( $gen->getTimestampedID88( $time ), 2, $base );
+       }
+
+       /**
+        * @param $time array (UIDGenerator::millitime(), clock sequence)
+        * @return string 88 bits
+        */
+       protected function getTimestampedID88( array $info ) {
+               list( $time, $counter ) = $info;
+               // Take the 46 MSBs of "milliseconds since epoch"
+               $id_bin = $this->millisecondsSinceEpochBinary( $time );
+               // Add a 10 bit counter resulting in 56 bits total
+               $id_bin .= str_pad( decbin( $counter ), 10, '0', STR_PAD_LEFT );
+               // Add the 32 bit node ID resulting in 88 bits total
+               $id_bin .= $this->nodeId32;
+               // Convert to a 1-27 digit integer string
+               if ( strlen( $id_bin ) !== 88 ) {
+                       throw new MWException( "Detected overflow for millisecond timestamp." );
+               }
+               return $id_bin;
+       }
+
+       /**
+        * Get a statistically unique 128-bit unsigned integer ID string.
+        * The bits of the UID are prefixed with the time (down to the millisecond).
+        *
+        * These IDs are suitable as globally unique IDs, without any enforced uniqueness.
+        * New rows almost always have higher UIDs, which makes B-TREE updates on INSERT fast.
+        * They can also be stored as "DECIMAL(39) UNSIGNED" or BINARY(16) in MySQL.
+        *
+        * UID generation is serialized on each server (as the node ID is for the whole machine).
+        *
+        * @param $base integer Specifies a base other than 10
+        * @return string Number
+        * @throws MWException
+        */
+       public static function newTimestampedUID128( $base = 10 ) {
+               if ( !is_integer( $base ) || $base > 36 || $base < 2 ) {
+                       throw new MWException( "Base must be an integer between 2 and 36" );
+               }
+               $gen = self::singleton();
+               $time = $gen->getTimestampAndDelay( 'lockFile128', 16384, 1048576 );
+               return wfBaseConvert( $gen->getTimestampedID128( $time ), 2, $base );
+       }
+
+       /**
+        * @param $info array (UIDGenerator::milltime(), counter, clock sequence)
+        * @return string 128 bits
+        */
+       protected function getTimestampedID128( array $info ) {
+               list( $time, $counter, $clkSeq ) = $info;
+               // Take the 46 MSBs of "milliseconds since epoch"
+               $id_bin = $this->millisecondsSinceEpochBinary( $time );
+               // Add a 20 bit counter resulting in 66 bits total
+               $id_bin .= str_pad( decbin( $counter ), 20, '0', STR_PAD_LEFT );
+               // Add a 14 bit clock sequence number resulting in 80 bits total
+               $id_bin .= str_pad( decbin( $clkSeq ), 14, '0', STR_PAD_LEFT );
+               // Add the 48 bit node ID resulting in 128 bits total
+               $id_bin .= $this->nodeId48;
+               // Convert to a 1-39 digit integer string
+               if ( strlen( $id_bin ) !== 128 ) {
+                       throw new MWException( "Detected overflow for millisecond timestamp." );
+               }
+               return $id_bin;
+       }
+
+       /**
+        * Return an RFC4122 compliant v4 UUID
+        *
+        * @param $flags integer Bitfield (supports UIDGenerator::QUICK_RAND)
+        * @return string
+        * @throws MWException
+        */
+       public static function newUUIDv4( $flags = 0 ) {
+               $hex = ( $flags & self::QUICK_RAND )
+                       ? wfRandomString( 31 )
+                       : MWCryptRand::generateHex( 31 );
+
+               return sprintf( '%s-%s-%s-%s-%s',
+                       // "time_low" (32 bits)
+                       substr( $hex, 0, 8 ),
+                       // "time_mid" (16 bits)
+                       substr( $hex, 8, 4 ),
+                       // "time_hi_and_version" (16 bits)
+                       '4' . substr( $hex, 12, 3 ),
+                       // "clk_seq_hi_res (8 bits, variant is binary 10x) and "clk_seq_low" (8 bits)
+                       dechex( 0x8 | ( hexdec( $hex[15] ) & 0x3 ) ) . $hex[16] . substr( $hex, 17, 2 ),
+                       // "node" (48 bits)
+                       substr( $hex, 19, 12 )
+               );
+       }
+
+       /**
+        * Return an RFC4122 compliant v4 UUID
+        *
+        * @param $flags integer Bitfield (supports UIDGenerator::QUICK_RAND)
+        * @return string 32 hex characters with no hyphens
+        * @throws MWException
+        */
+       public static function newRawUUIDv4( $flags = 0 ) {
+               return str_replace( '-', '', self::newUUIDv4( $flags ) );
+       }
+
+       /**
+        * Get a (time,counter,clock sequence) where (time,counter) is higher
+        * than any previous (time,counter) value for the given clock sequence.
+        * This is useful for making UIDs sequential on a per-node bases.
+        *
+        * @param $lockFile string Name of a local lock file
+        * @param $clockSeqSize integer The number of possible clock sequence values
+        * @param $counterSize integer The number of possible counter values
+        * @return Array (result of UIDGenerator::millitime(), counter, clock sequence)
+        * @throws MWException
+        */
+       protected function getTimestampAndDelay( $lockFile, $clockSeqSize, $counterSize ) {
+               // Get the UID lock file handle
+               if ( isset( $this->fileHandles[$lockFile] ) ) {
+                       $handle = $this->fileHandles[$lockFile];
+               } else {
+                       $handle = fopen( $this->$lockFile, 'cb+' );
+                       $this->fileHandles[$lockFile] = $handle ?: null; // cache
+               }
+               // Acquire the UID lock file
+               if ( $handle === false ) {
+                       throw new MWException( "Could not open '{$this->$lockFile}'." );
+               } elseif ( !flock( $handle, LOCK_EX ) ) {
+                       throw new MWException( "Could not acquire '{$this->$lockFile}'." );
+               }
+               // Get the current timestamp, clock sequence number, last time, and counter
+               rewind( $handle );
+               $data = explode( ' ', fgets( $handle ) ); // "<clk seq> <sec> <msec> <counter> <offset>"
+               $clockChanged = false; // clock set back significantly?
+               if ( count( $data ) == 5 ) { // last UID info already initialized
+                       $clkSeq = (int) $data[0] % $clockSeqSize;
+                       $prevTime = array( (int) $data[1], (int) $data[2] );
+                       $offset = (int) $data[4] % $counterSize; // random counter offset
+                       $counter = 0; // counter for UIDs with the same timestamp
+                       // Delay until the clock reaches the time of the last ID.
+                       // This detects any microtime() drift among processes.
+                       $time = $this->timeWaitUntil( $prevTime );
+                       if ( !$time ) { // too long to delay?
+                               $clockChanged = true; // bump clock sequence number
+                               $time = self::millitime();
+                       } elseif ( $time == $prevTime ) {
+                               // Bump the counter if there are timestamp collisions
+                               $counter = (int) $data[3] % $counterSize;
+                               if ( ++$counter >= $counterSize ) { // sanity (starts at 0)
+                                       flock( $handle, LOCK_UN ); // abort
+                                       throw new MWException( "Counter overflow for timestamp value." );
+                               }
+                       }
+               } else { // last UID info not initialized
+                       $clkSeq = mt_rand( 0, $clockSeqSize - 1 );
+                       $counter = 0;
+                       $offset = mt_rand( 0, $counterSize - 1 );
+                       $time = self::millitime();
+               }
+               // microtime() and gettimeofday() can drift from time() at least on Windows.
+               // The drift is immediate for processes running while the system clock changes.
+               // time() does not have this problem. See https://bugs.php.net/bug.php?id=42659.
+               if ( abs( time() - $time[0] ) >= 2 ) {
+                       // We don't want processes using too high or low timestamps to avoid duplicate
+                       // UIDs and clock sequence number churn. This process should just be restarted.
+                       flock( $handle, LOCK_UN ); // abort
+                       throw new MWException( "Process clock is outdated or drifted." );
+               }
+               // If microtime() is synced and a clock change was detected, then the clock went back
+               if ( $clockChanged ) {
+                       // Bump the clock sequence number and also randomize the counter offset,
+                       // which is useful for UIDs that do not include the clock sequence number.
+                       $clkSeq = ( $clkSeq + 1 ) % $clockSeqSize;
+                       $offset = mt_rand( 0, $counterSize - 1 );
+                       trigger_error( "Clock was set back; sequence number incremented." );
+               }
+               // Update the (clock sequence number, timestamp, counter)
+               ftruncate( $handle, 0 );
+               rewind( $handle );
+               fwrite( $handle, "{$clkSeq} {$time[0]} {$time[1]} {$counter} {$offset}" );
+               fflush( $handle );
+               // Release the UID lock file
+               flock( $handle, LOCK_UN );
+
+               return array( $time, ( $counter + $offset ) % $counterSize, $clkSeq );
+       }
+
+       /**
+        * Wait till the current timestamp reaches $time and return the current
+        * timestamp. This returns false if it would have to wait more than 10ms.
+        *
+        * @param $time array Result of UIDGenerator::millitime()
+        * @return Array|bool UIDGenerator::millitime() result or false
+        */
+       protected function timeWaitUntil( array $time ) {
+               do {
+                       $ct = self::millitime();
+                       if ( $ct >= $time ) { // http://php.net/manual/en/language.operators.comparison.php
+                               return $ct; // current timestamp is higher than $time
+                       }
+               } while ( ( ( $time[0] - $ct[0] )*1000 + ( $time[1] - $ct[1] ) ) <= 10 );
+
+               return false;
+       }
+
+       /**
+        * @param $time array Result of UIDGenerator::millitime()
+        * @return string 46 MSBs of "milliseconds since epoch" in binary (rolls over in 4201)
+        */
+       protected function millisecondsSinceEpochBinary( array $time ) {
+               list( $sec, $msec ) = $time;
+               if ( PHP_INT_SIZE >= 8 ) { // 64 bit integers
+                       $ts = ( 1000 * $sec + $msec );
+                       $id_bin = str_pad( decbin( $ts % pow( 2, 46 ) ), 46, '0', STR_PAD_LEFT );
+               } elseif ( extension_loaded( 'gmp' ) ) {
+                       $ts = gmp_mod( // wrap around
+                               gmp_add( gmp_mul( (string) $sec, (string) 1000 ), (string) $msec ),
+                               gmp_pow( '2', '46' )
+                       );
+                       $id_bin = str_pad( gmp_strval( $ts, 2 ), 46, '0', STR_PAD_LEFT );
+               } elseif ( extension_loaded( 'bcmath' ) ) {
+                       $ts = bcmod( // wrap around
+                               bcadd( bcmul( $sec, 1000 ), $msec ),
+                               bcpow( 2, 46 )
+                       );
+                       $id_bin = wfBaseConvert( $ts, 10, 2, 46 );
+               } else {
+                       throw new MWException( 'bcmath or gmp extension required for 32 bit machines.' );
+               }
+               return $id_bin;
+       }
+
+       /**
+        * @return Array (current time in seconds, milliseconds since then)
+        */
+       protected static function millitime() {
+               list( $msec, $sec ) = explode( ' ', microtime() );
+               return array( (int) $sec, (int) ( $msec * 1000 ) );
+       }
+
+       function __destruct() {
+               array_map( 'fclose', $this->fileHandles );
+       }
+}
index 3e49cd0..c2af93c 100644 (file)
@@ -1451,7 +1451,7 @@ class User {
                        // But this is a crappy hack and should die.
                        return false;
                }
-               return !$this->isAllowed('noratelimit');
+               return !$this->isAllowed( 'noratelimit' );
        }
 
        /**
@@ -2284,7 +2284,7 @@ class User {
         * @return Int User's current value for the option
         * @see getOption()
         */
-       public function getIntOption( $oname, $defaultOverride=0 ) {
+       public function getIntOption( $oname, $defaultOverride = 0 ) {
                $val = $this->getOption( $oname );
                if( $val == '' ) {
                        $val = $defaultOverride;
@@ -2620,7 +2620,7 @@ class User {
                        if( $this->getId() ) {
                                $dbw->insert( 'user_groups',
                                        array(
-                                               'ug_user'  => $this->getID(),
+                                               'ug_user' => $this->getID(),
                                                'ug_group' => $group,
                                        ),
                                        __METHOD__,
@@ -2645,13 +2645,13 @@ class User {
                        $dbw = wfGetDB( DB_MASTER );
                        $dbw->delete( 'user_groups',
                                array(
-                                       'ug_user'  => $this->getID(),
+                                       'ug_user' => $this->getID(),
                                        'ug_group' => $group,
                                ), __METHOD__ );
                        // Remember that the user was in this group
                        $dbw->insert( 'user_former_groups',
                                array(
-                                       'ufg_user'  => $this->getID(),
+                                       'ufg_user' => $this->getID(),
                                        'ufg_group' => $group,
                                ),
                                __METHOD__,
@@ -2874,6 +2874,10 @@ class User {
         * the next change of any watched page.
         */
        public function clearAllNotifications() {
+               if ( wfReadOnly() ) {
+                       return;
+               }
+
                global $wgUseEnotif, $wgShowUpdatedMarker;
                if ( !$wgUseEnotif && !$wgShowUpdatedMarker ) {
                        $this->setNewtalk( false );
@@ -3264,7 +3268,7 @@ class User {
        public function getPageRenderingHash() {
                wfDeprecated( __METHOD__, '1.17' );
 
-               global $wgUseDynamicDates, $wgRenderHashAppend, $wgLang, $wgContLang;
+               global $wgRenderHashAppend, $wgLang, $wgContLang;
                if( $this->mHash ) {
                        return $this->mHash;
                }
@@ -3275,9 +3279,6 @@ class User {
 
                $confstr =        $this->getOption( 'math' );
                $confstr .= '!' . $this->getStubThreshold();
-               if ( $wgUseDynamicDates ) { # This is wrong (bug 24714)
-                       $confstr .= '!' . $this->getDatePreference();
-               }
                $confstr .= '!' . ( $this->getOption( 'numberheadings' ) ? '1' : '' );
                $confstr .= '!' . $wgLang->getCode();
                $confstr .= '!' . $this->getOption( 'thumbsize' );
@@ -4058,7 +4059,7 @@ class User {
                        $groups = array_merge_recursive(
                                $groups, $this->changeableByGroup( $addergroup )
                        );
-                       $groups['add']    = array_unique( $groups['add'] );
+                       $groups['add'] = array_unique( $groups['add'] );
                        $groups['remove'] = array_unique( $groups['remove'] );
                        $groups['add-self'] = array_unique( $groups['add-self'] );
                        $groups['remove-self'] = array_unique( $groups['remove-self'] );
index 324e7ce..7d11342 100644 (file)
@@ -136,10 +136,10 @@ class UserMailer {
                global $wgSMTP, $wgServer;
 
                $msgid = uniqid( wfWikiID() . ".", true ); /* true required for cygwin */
-               if ( is_array($wgSMTP) && isset($wgSMTP['IDHost']) && $wgSMTP['IDHost'] ) {
+               if ( is_array( $wgSMTP ) && isset( $wgSMTP['IDHost'] ) && $wgSMTP['IDHost'] ) {
                        $domain = $wgSMTP['IDHost'];
                } else {
-                       $url = wfParseUrl($wgServer);
+                       $url = wfParseUrl( $wgServer );
                        $domain = $url['host'];
                }
                return "<$msgid@$domain>";
@@ -340,7 +340,7 @@ class UserMailer {
                        #
                        # PHP mail()
                        #
-                       if( count($to) > 1 ) {
+                       if( count( $to ) > 1 ) {
                                $headers['To'] = 'undisclosed-recipients:;';
                        }
                        $headers = self::arrayToHeaderString( $headers, $endl );
@@ -517,9 +517,9 @@ class EmailNotification {
                                                        array( /* SET */
                                                                'wl_notificationtimestamp' => $dbw->timestamp( $timestamp )
                                                        ), array( /* WHERE */
-                                                               'wl_user'      => $watchers,
+                                                               'wl_user' => $watchers,
                                                                'wl_namespace' => $title->getNamespace(),
-                                                               'wl_title'     => $title->getDBkey(),
+                                                               'wl_title' => $title->getDBkey(),
                                                        ), $fname
                                                );
                                                $dbw->commit( $fname );
@@ -710,16 +710,16 @@ class EmailNotification {
                        if ( !$wgEnotifImpersonal ) {
                                // For personal mail, also show a link to the diff of all changes
                                // since last visited.
-                               $keys['$NEWPAGE'] .= "\n\n" .  wfMessage( 'enotif_lastvisited',
+                               $keys['$NEWPAGE'] .= "\n\n" . wfMessage( 'enotif_lastvisited',
                                        $this->title->getCanonicalUrl( 'diff=0&oldid=' . $this->oldid ) )
                                        ->inContentLanguage()->text();
                        }
-                       $keys['$OLDID']   = $this->oldid;
+                       $keys['$OLDID'] = $this->oldid;
                        // @deprecated Remove in MediaWiki 1.23.
                        $keys['$CHANGEDORCREATED'] = wfMessage( 'changed' )->inContentLanguage()->text();
                } else {
                        # clear $OLDID placeholder in the message template
-                       $keys['$OLDID']   = '';
+                       $keys['$OLDID'] = '';
                        $keys['$NEWPAGE'] = '';
                        // @deprecated Remove in MediaWiki 1.23.
                        $keys['$CHANGEDORCREATED'] = wfMessage( 'created' )->inContentLanguage()->text();
@@ -771,13 +771,13 @@ class EmailNotification {
                {
                        $editorAddress = new MailAddress( $this->editor );
                        if ( $wgEnotifFromEditor ) {
-                               $this->from    = $editorAddress;
+                               $this->from = $editorAddress;
                        } else {
-                               $this->from    = $adminAddress;
+                               $this->from = $adminAddress;
                                $this->replyto = $editorAddress;
                        }
                } else {
-                       $this->from    = $adminAddress;
+                       $this->from = $adminAddress;
                        $this->replyto = new MailAddress( $wgNoReplyAddress );
                }
        }
index ffdc285..240ebc7 100644 (file)
@@ -162,22 +162,22 @@ class WatchedItem {
                // if there's already an entry for this page
                $dbw = wfGetDB( DB_MASTER );
                $dbw->insert( 'watchlist',
-                 array(
-                       'wl_user' => $this->getUserId(),
-                       'wl_namespace' => MWNamespace::getSubject($this->getTitleNs()),
-                       'wl_title' => $this->getTitleDBkey(),
-                       'wl_notificationtimestamp' => null
-                 ), __METHOD__, 'IGNORE' );
+                       array(
+                               'wl_user' => $this->getUserId(),
+                               'wl_namespace' => MWNamespace::getSubject( $this->getTitleNs() ),
+                               'wl_title' => $this->getTitleDBkey(),
+                               'wl_notificationtimestamp' => null
+                       ), __METHOD__, 'IGNORE' );
 
                // Every single watched page needs now to be listed in watchlist;
                // namespace:page and namespace_talk:page need separate entries:
                $dbw->insert( 'watchlist',
-                 array(
-                       'wl_user' => $this->getUserId(),
-                       'wl_namespace' => MWNamespace::getTalk($this->getTitleNs()),
-                       'wl_title' => $this->getTitleDBkey(),
-                       'wl_notificationtimestamp' => null
-                 ), __METHOD__, 'IGNORE' );
+                       array(
+                               'wl_user' => $this->getUserId(),
+                               'wl_namespace' => MWNamespace::getTalk( $this->getTitleNs() ),
+                               'wl_title' => $this->getTitleDBkey(),
+                               'wl_notificationtimestamp' => null
+                       ), __METHOD__, 'IGNORE' );
 
                $this->watched = true;
 
@@ -197,7 +197,7 @@ class WatchedItem {
                $dbw->delete( 'watchlist',
                        array(
                                'wl_user' => $this->getUserId(),
-                               'wl_namespace' => MWNamespace::getSubject($this->getTitleNs()),
+                               'wl_namespace' => MWNamespace::getSubject( $this->getTitleNs() ),
                                'wl_title' => $this->getTitleDBkey(),
                        ), __METHOD__
                );
@@ -212,7 +212,7 @@ class WatchedItem {
                $dbw->delete( 'watchlist',
                        array(
                                'wl_user' => $this->getUserId(),
-                               'wl_namespace' => MWNamespace::getTalk($this->getTitleNs()),
+                               'wl_namespace' => MWNamespace::getTalk( $this->getTitleNs() ),
                                'wl_title' => $this->getTitleDBkey(),
                        ), __METHOD__
                );
index 594226b..cd43ffb 100644 (file)
@@ -128,7 +128,7 @@ class WebRequest {
                                global $wgVariantArticlePath, $wgContLang;
                                if( $wgVariantArticlePath ) {
                                        $router->add( $wgVariantArticlePath,
-                                               array( 'variant' => '$2'),
+                                               array( 'variant' => '$2' ),
                                                array( '$2' => $wgContLang->getVariants() )
                                        );
                                }
@@ -144,7 +144,7 @@ class WebRequest {
                                // Also reported when ini_get('cgi.fix_pathinfo')==false
                                $matches['title'] = substr( $_SERVER['ORIG_PATH_INFO'], 1 );
 
-                       } elseif ( isset( $_SERVER['PATH_INFO'] ) && ($_SERVER['PATH_INFO'] != '') ) {
+                       } elseif ( isset( $_SERVER['PATH_INFO'] ) && $_SERVER['PATH_INFO'] != '' ) {
                                // Regular old PATH_INFO yay
                                $matches['title'] = substr( $_SERVER['PATH_INFO'], 1 );
                        }
@@ -565,9 +565,9 @@ class WebRequest {
         *
         * @return Array
         */
-        public function getQueryValues() {
+       public function getQueryValues() {
                return $_GET;
-        }
+       }
 
        /**
         * Get the HTTP method used for this request.
@@ -619,7 +619,7 @@ class WebRequest {
                        global $wgCookiePrefix;
                        $prefix = $wgCookiePrefix;
                }
-               return $this->getGPCVal( $_COOKIE, $prefix . $key , $default );
+               return $this->getGPCVal( $_COOKIE, $prefix . $key, $default );
        }
 
        /**
@@ -849,7 +849,7 @@ class WebRequest {
                } else {
                        foreach ( $_SERVER as $name => $value ) {
                                if ( substr( $name, 0, 5 ) === 'HTTP_' ) {
-                                       $name = str_replace( '_', '-',  substr( $name, 5 ) );
+                                       $name = str_replace( '_', '-', substr( $name, 5 ) );
                                        $this->headers[$name] = $value;
                                } elseif ( $name === 'CONTENT_LENGTH' ) {
                                        $this->headers['CONTENT-LENGTH'] = $value;
index f00e055..37dbef4 100644 (file)
@@ -52,7 +52,7 @@ class WebResponse {
         */
        public function setcookie( $name, $value, $expire = 0, $prefix = null, $domain = null, $forceSecure = null ) {
                global $wgCookiePath, $wgCookiePrefix, $wgCookieDomain;
-               global $wgCookieSecure,$wgCookieExpiration, $wgCookieHttpOnly;
+               global $wgCookieSecure, $wgCookieExpiration, $wgCookieHttpOnly;
                if ( $expire == 0 ) {
                        $expire = time() + $wgCookieExpiration;
                }
index 247f810..48767d0 100644 (file)
@@ -27,7 +27,7 @@
 # This must be done before any globals are set by the code
 if ( ini_get( 'register_globals' ) ) {
        if ( isset( $_REQUEST['GLOBALS'] ) || isset( $_FILES['GLOBALS'] ) ) {
-               die( '<a href="http://www.hardened-php.net/globals-problem">$GLOBALS overwrite vulnerability</a>');
+               die( '<a href="http://www.hardened-php.net/globals-problem">$GLOBALS overwrite vulnerability</a>' );
        }
        $verboten = array(
                'GLOBALS',
@@ -62,7 +62,7 @@ if ( ini_get( 'register_globals' ) ) {
 # points and when $wgOut gets disabled or overridden.
 header( 'X-Content-Type-Options: nosniff' );
 
-$wgRequestTime = microtime(true);
+$wgRequestTime = microtime( true );
 # getrusage() does not exist on the Microsoft Windows platforms, catching this
 if ( function_exists ( 'getrusage' ) ) {
        $wgRUstart = getrusage();
@@ -80,11 +80,15 @@ define( 'MEDIAWIKI', true );
 
 # Full path to working directory.
 # Makes it possible to for example to have effective exclude path in apc.
-# Also doesn't break installations using symlinked includes, like
-# __DIR__ would do.
+# __DIR__ breaks symlinked includes, but realpath() returns false
+# if we don't have permissions on parent directories.
 $IP = getenv( 'MW_INSTALL_PATH' );
 if ( $IP === false ) {
-       $IP = realpath( '.' );
+       if( realpath( '.' ) ) {
+               $IP = realpath( '.' );
+       } else {
+               $IP = dirname( __DIR__ );
+       }
 }
 
 if ( isset( $_SERVER['MW_COMPILED'] ) ) {
@@ -119,7 +123,7 @@ if ( defined( 'MW_CONFIG_CALLBACK' ) ) {
        MWFunction::call( MW_CONFIG_CALLBACK );
 } else {
        if ( !defined( 'MW_CONFIG_FILE' ) ) {
-               define('MW_CONFIG_FILE', MWInit::interpretedPath( 'LocalSettings.php' ) );
+               define( 'MW_CONFIG_FILE', MWInit::interpretedPath( 'LocalSettings.php' ) );
        }
 
        # LocalSettings.php is the per site customization file. If it does not exist
index 0114cce..fa23072 100644 (file)
@@ -42,7 +42,7 @@ class WikiFilePage extends WikiPage {
 
        public function getActionOverrides() {
                $overrides = parent::getActionOverrides();
-               $overrides[ 'revert' ] = 'RevertFileAction';
+               $overrides['revert'] = 'RevertFileAction';
                return $overrides;
        }
 
index 49a944b..6048294 100644 (file)
@@ -23,7 +23,7 @@
 /**
  * Abstract class for type hinting (accepts WikiPage, Article, ImagePage, CategoryPage)
  */
-abstract class Page {}
+interface Page {}
 
 /**
  * Class representing a MediaWiki article and history.
@@ -33,7 +33,7 @@ abstract class Page {}
  *
  * @internal documentation reviewed 15 Mar 2010
  */
-class WikiPage extends Page implements IDBAccessObject {
+class WikiPage implements Page, IDBAccessObject {
        // Constants for $mDataLoadedFrom and related
 
        /**
@@ -2274,9 +2274,14 @@ class WikiPage extends Page implements IDBAccessObject {
 
                $encodedExpiry = array();
                $protectDescription = '';
+               # Some bots may parse IRC lines, which are generated from log entries which contain plain
+               # protect description text. Keep them in old format to avoid breaking compatibility.
+               # TODO: Fix protection log to store structured description and format it on-the-fly.
+               $protectDescriptionLog = '';
                foreach ( $limit as $action => $restrictions ) {
                        $encodedExpiry[$action] = $dbw->encodeExpiry( $expiry[$action] );
                        if ( $restrictions != '' ) {
+                               $protectDescriptionLog .= $wgContLang->getDirMark() . "[$action=$restrictions] (";
                                # $action is one of $wgRestrictionTypes = array( 'create', 'edit', 'move', 'upload' ).
                                # All possible message keys are listed here for easier grepping:
                                # * restriction-create
@@ -2307,8 +2312,10 @@ class WikiPage extends Page implements IDBAccessObject {
                                $protectDescription .= wfMessage( 'protect-summary-desc' )
                                        ->params( $actionText, $restrictionsText, $expiryText )
                                        ->inContentLanguage()->text();
+                               $protectDescriptionLog .= $expiryText . ') ';
                        }
                }
+               $protectDescriptionLog = trim( $protectDescriptionLog );
 
                if ( $id ) { // Protection of existing page
                        if ( !wfRunHooks( 'ArticleProtect', array( &$this, &$user, $limit, $reason ) ) ) {
@@ -2350,7 +2357,7 @@ class WikiPage extends Page implements IDBAccessObject {
                                )->inContentLanguage()->text()
                        );
                        if ( $reason ) {
-                               $editComment .= ": $reason";
+                               $editComment .= wfMessage( 'colon-separator' )->inContentLanguage()->text() . $reason;
                        }
                        if ( $protectDescription ) {
                                $editComment .= wfMessage( 'word-separator' )->inContentLanguage()->text();
@@ -2413,7 +2420,7 @@ class WikiPage extends Page implements IDBAccessObject {
                if ( $logAction == 'unprotect' ) {
                        $logParams = array();
                } else {
-                       $logParams = array( $protectDescription, $cascade ? 'cascade' : '' );
+                       $logParams = array( $protectDescriptionLog, $cascade ? 'cascade' : '' );
                }
 
                // Update the protection log
@@ -3027,10 +3034,10 @@ class WikiPage extends Page implements IDBAccessObject {
                $removeFields = array( 'cat_pages = cat_pages - 1' );
 
                if ( $ns == NS_CATEGORY ) {
-                       $addFields[]    = 'cat_subcats = cat_subcats + 1';
+                       $addFields[] = 'cat_subcats = cat_subcats + 1';
                        $removeFields[] = 'cat_subcats = cat_subcats - 1';
                } elseif ( $ns == NS_FILE ) {
-                       $addFields[]    = 'cat_files = cat_files + 1';
+                       $addFields[] = 'cat_files = cat_files + 1';
                        $removeFields[] = 'cat_files = cat_files - 1';
                }
 
@@ -3308,7 +3315,7 @@ class PoolWorkArticleView extends PoolCounterWork {
         * @param $content Content|String: content to parse or null to load it; may also be given as a wikitext string, for BC
         */
        function __construct( Page $page, ParserOptions $parserOptions, $revid, $useParserCache, $content = null ) {
-               if ( is_string($content) ) { // BC: old style call
+               if ( is_string( $content ) ) { // BC: old style call
                        $modelId = $page->getRevision()->getContentModel();
                        $format = $page->getRevision()->getContentFormat();
                        $content = ContentHandler::makeContent( $content, $page->getTitle(), $modelId, $format );
index 7c451bb..158a6b5 100644 (file)
@@ -86,7 +86,7 @@ class Xml {
         * @param $contents String: NULL to make an open tag only; '' for a contentless closed tag (default)
         * @return string
         */
-       public static function elementClean( $element, $attribs = array(), $contents = '') {
+       public static function elementClean( $element, $attribs = array(), $contents = '' ) {
                global $wgContLang;
                if( $attribs ) {
                        $attribs = array_map( array( 'UtfNormal', 'cleanUp' ), $attribs );
@@ -192,7 +192,7 @@ class Xml {
                } elseif( $encMonth ) {
                        $thisMonth = intval( gmdate( 'n' ) );
                        $thisYear = intval( gmdate( 'Y' ) );
-                       if( intval($encMonth) > $thisMonth ) {
+                       if( intval( $encMonth ) > $thisMonth ) {
                                $thisYear--;
                        }
                        $encYear = $thisYear;
@@ -500,7 +500,7 @@ class Xml {
                                } elseif ( substr( $value, 0, 1) == '*' && substr( $value, 1, 1) != '*' ) {
                                        // A new group is starting ...
                                        $value = trim( substr( $value, 1 ) );
-                                       if( $optgroup ) $options .= self::closeElement('optgroup');
+                                       if( $optgroup ) $options .= self::closeElement( 'optgroup' );
                                        $options .= self::openElement( 'optgroup', array( 'label' => $value ) );
                                        $optgroup = true;
                                } elseif ( substr( $value, 0, 2) == '**' ) {
@@ -509,13 +509,13 @@ class Xml {
                                        $options .= self::option( $value, $value, $selected === $value );
                                } else {
                                        // groupless reason list
-                                       if( $optgroup ) $options .= self::closeElement('optgroup');
+                                       if( $optgroup ) $options .= self::closeElement( 'optgroup' );
                                        $options .= self::option( $value, $value, $selected === $value );
                                        $optgroup = false;
                                }
                        }
 
-                       if( $optgroup ) $options .= self::closeElement('optgroup');
+                       if( $optgroup ) $options .= self::closeElement( 'optgroup' );
 
                $attribs = array();
 
@@ -636,10 +636,10 @@ class Xml {
                } elseif ( is_null( $value ) ) {
                        $s = 'null';
                } elseif ( is_int( $value ) || is_float( $value ) ) {
-                       $s = strval($value);
+                       $s = strval( $value );
                } elseif ( is_array( $value ) && // Make sure it's not associative.
-                                       array_keys($value) === range( 0, count($value) - 1 ) ||
-                                       count($value) == 0
+                                       array_keys( $value ) === range( 0, count( $value ) - 1 ) ||
+                                       count( $value ) == 0
                                ) {
                        $s = '[';
                        foreach ( $value as $elt ) {
@@ -764,7 +764,7 @@ class Xml {
                foreach( $fields as $labelmsg => $input ) {
                        $id = "mw-$labelmsg";
                        $form .= Xml::openElement( 'tr', array( 'id' => $id ) );
-                       $form .= Xml::tags( 'td', array('class' => 'mw-label'), wfMessage( $labelmsg )->parse() );
+                       $form .= Xml::tags( 'td', array( 'class' => 'mw-label' ), wfMessage( $labelmsg )->parse() );
                        $form .= Xml::openElement( 'td', array( 'class' => 'mw-input' ) ) . $input . Xml::closeElement( 'td' );
                        $form .= Xml::closeElement( 'tr' );
                }
index ccdf2bb..fc36b1f 100644 (file)
@@ -181,7 +181,7 @@ class ZipDirectoryReader {
         * Throw an error, and log a debug message
         */
        function error( $code, $debugMessage ) {
-               wfDebug( __CLASS__.": Fatal error: $debugMessage\n" );
+               wfDebug( __CLASS__ . ": Fatal error: $debugMessage\n" );
                throw new ZipDirectoryReaderError( $code );
        }
 
@@ -220,7 +220,7 @@ class ZipDirectoryReader {
                if ( $structSize + $this->eocdr['file comment length'] != strlen( $block ) - $sigPos ) {
                        $this->error( 'zip-bad', 'trailing bytes after the end of the file comment' );
                }
-               if (   $this->eocdr['disk'] !== 0
+               if ( $this->eocdr['disk'] !== 0
                        || $this->eocdr['CD start disk'] !== 0 )
                {
                        $this->error( 'zip-unsupported', 'more than one disk (in EOCDR)' );
@@ -262,7 +262,7 @@ class ZipDirectoryReader {
         * may replace the regular "end of central directory record" in ZIP64 files.
         */
        function readZip64EndOfCentralDirectoryRecord() {
-               if (   $this->eocdr64Locator['eocdr64 start disk'] != 0
+               if ( $this->eocdr64Locator['eocdr64 start disk'] != 0
                        || $this->eocdr64Locator['number of disks'] != 0 )
                {
                        $this->error( 'zip-unsupported', 'more than one disk (in EOCDR64 locator)' );
@@ -286,7 +286,7 @@ class ZipDirectoryReader {
                if ( $data['signature'] !== "PK\x06\x06" ) {
                        $this->error( 'zip-bad', 'wrong signature on Zip64 end of central directory record' );
                }
-               if (   $data['disk'] !== 0
+               if ( $data['disk'] !== 0
                        || $data['CD start disk'] !== 0 )
                {
                        $this->error( 'zip-unsupported', 'more than one disk (in EOCDR64)' );
@@ -327,7 +327,7 @@ class ZipDirectoryReader {
                $offset = $this->eocdr['CD offset'];
                $numEntries = $this->eocdr['CD entries total'];
                $endPos = $this->eocdr['position'];
-               if (   $size == 0xffffffff
+               if ( $size == 0xffffffff
                        || $offset == 0xffffffff
                        || $numEntries == 0xffff )
                {
@@ -395,7 +395,7 @@ class ZipDirectoryReader {
                        $data += $this->unpack( $block, $variableInfo, $pos );
                        $pos += $this->getStructSize( $variableInfo );
 
-                       if (   $this->zip64 && (
+                       if ( $this->zip64 && (
                                   $data['compressed size'] == 0xffffffff
                                || $data['uncompressed size'] == 0xffffffff
                                || $data['local header offset'] == 0xffffffff ) )
@@ -618,7 +618,7 @@ class ZipDirectoryReader {
                                        $pos += $fieldSize;
                                        break;
                                default:
-                                       throw new MWException( __METHOD__.": invalid type \"$typeName\"" );
+                                       throw new MWException( __METHOD__ . ": invalid type \"$typeName\"" );
                                }
                        } else {
                                // Unsigned little-endian integer
index a1d1c3a..d26228a 100644 (file)
@@ -23,7 +23,7 @@
  */
 
 /**
- * This class handles printing the history page for an article.  In order to
+ * This class handles printing the history page for an article. In order to
  * be efficient, it uses timestamps rather than offsets for paging, to avoid
  * costly LIMIT,offset queries.
  *
@@ -132,7 +132,7 @@ class HistoryAction extends FormlessAction {
                                array( 'delete', 'move' ),
                                $this->getTitle(),
                                '',
-                               array(  'lim' => 10,
+                               array( 'lim' => 10,
                                        'conds' => array( "log_action != 'revision'" ),
                                        'showIfEmpty' => false,
                                        'msgKey' => array( 'moveddeleted-notice' )
@@ -515,7 +515,7 @@ class HistoryPager extends ReverseChronologicalPager {
        function submitButton( $message, $attributes = array() ) {
                # Disable submit button if history has 1 revision only
                if ( $this->getNumRows() > 1 ) {
-                       return Xml::submitButton( $message , $attributes );
+                       return Xml::submitButton( $message, $attributes );
                } else {
                        return '';
                }
@@ -609,7 +609,7 @@ class HistoryPager extends ReverseChronologicalPager {
                                ? $this->parentLens[$row->rev_parent_id]
                                : 0;
                        $sDiff = ChangesList::showCharacterDifference( $prevSize, $rev->getSize() );
-                       $fSize = Linker::formatRevisionSize($rev->getSize());
+                       $fSize = Linker::formatRevisionSize( $rev->getSize() );
                        $s .= ' <span class="mw-changeslist-separator">. .</span> ' . "$fSize $sDiff";
                }
 
@@ -617,7 +617,7 @@ class HistoryPager extends ReverseChronologicalPager {
                $s2 = Linker::revComment( $rev, false, true );
 
                if ( $notificationtimestamp && ( $row->rev_timestamp >= $notificationtimestamp ) ) {
-                       $s2 .= ' <span class="updatedmarker">' .  $this->msg( 'updatedmarker' )->escaped() . '</span>';
+                       $s2 .= ' <span class="updatedmarker">' . $this->msg( 'updatedmarker' )->escaped() . '</span>';
                        $classes[] = 'mw-history-line-updated';
                }
 
@@ -671,7 +671,7 @@ class HistoryPager extends ReverseChronologicalPager {
                        $s .= ' <span class="mw-changeslist-separator">. .</span> ' . $s2;
                }
 
-               wfRunHooks( 'PageHistoryLineEnding', array( $this, &$row , &$s, &$classes ) );
+               wfRunHooks( 'PageHistoryLineEnding', array( $this, &$row, &$s, &$classes ) );
 
                $attribs = array();
                if ( $classes ) {
index 1cca95c..acb8c00 100644 (file)
@@ -274,6 +274,11 @@ class InfoAction extends FormlessAction {
                        $pageInfo['header-basic'][] = array(
                                $this->msg( 'pageinfo-watchers' ), $lang->formatNum( $pageCounts['watchers'] )
                        );
+               } elseif ( $wgUnwatchedPageThreshold !== false ) {
+                       $pageInfo['header-basic'][] = array(
+                               $this->msg( 'pageinfo-watchers' ),
+                               $this->msg( 'pageinfo-few-watchers' )->numParams( $wgUnwatchedPageThreshold )
+                       );
                }
 
                // Redirects to this page
index 71cb397..da6ba1e 100644 (file)
@@ -204,7 +204,7 @@ class RawAction extends FormlessAction {
                                        $oldid = $this->page->getLatest();
                                }
                                $prev = $this->getTitle()->getPreviousRevisionId( $oldid );
-                               $oldid = $prev ? $prev : -1 ;
+                               $oldid = $prev ? $prev : -1;
                                break;
                        case 'cur':
                                $oldid = 0;
index 5621b7c..abb43e8 100644 (file)
@@ -66,7 +66,15 @@ abstract class ApiBase extends ContextSource {
        const LIMIT_SML1 = 50; // Slow query, std user limit
        const LIMIT_SML2 = 500; // Slow query, bot/sysop limit
 
+       /**
+        * getAllowedParams() flag: When set, the result could take longer to generate,
+        * but should be more thorough. E.g. get the list of generators for ApiSandBox extension
+        * @since 1.21
+        */
+       const GET_VALUES_FOR_HELP = 1;
+
        private $mMainModule, $mModuleName, $mModulePrefix;
+       private $mSlaveDB = null;
        private $mParamCache = array();
 
        /**
@@ -127,6 +135,16 @@ abstract class ApiBase extends ContextSource {
                return $this->mModuleName;
        }
 
+
+       /**
+        * Get the module manager, or null if this module has no sub-modules
+        * @since 1.21
+        * @return ApiModuleManager
+        */
+       public function getModuleManager() {
+               return null;
+       }
+
        /**
         * Get parameter prefix (usually two letters or an empty string).
         * @return string
@@ -258,6 +276,8 @@ abstract class ApiBase extends ContextSource {
                        }
                        $msg = $lnPrfx . implode( $lnPrfx, $msg ) . "\n";
 
+                       $msg .= $this->makeHelpArrayToString( $lnPrfx, false, $this->getHelpUrls() );
+
                        if ( $this->isReadMode() ) {
                                $msg .= "\nThis module requires read rights";
                        }
@@ -301,8 +321,6 @@ abstract class ApiBase extends ContextSource {
                                        }
                                }
                        }
-
-                       $msg .= $this->makeHelpArrayToString( $lnPrfx, "Help page", $this->getHelpUrls() );
                }
 
                return $msg;
@@ -348,7 +366,7 @@ abstract class ApiBase extends ContextSource {
         * @return string or false
         */
        public function makeHelpMsgParameters() {
-               $params = $this->getFinalParams();
+               $params = $this->getFinalParams( ApiBase::GET_VALUES_FOR_HELP );
                if ( $params ) {
 
                        $paramsDescription = $this->getFinalParamDescription();
@@ -496,15 +514,22 @@ abstract class ApiBase extends ContextSource {
         * value) or (parameter name) => (array with PARAM_* constants as keys)
         * Don't call this function directly: use getFinalParams() to allow
         * hooks to modify parameters as needed.
+        *
+        * Some derived classes may choose to handle an integer $flags parameter
+        * in the overriding methods. Callers of this method can pass zero or
+        * more OR-ed flags like GET_VALUES_FOR_HELP.
+        *
         * @return array|bool
         */
-       protected function getAllowedParams() {
+       protected function getAllowedParams( /* $flags = 0 */ ) {
+               // int $flags is not declared because it causes "Strict standards"
+               // warning. Most derived classes do not implement it.
                return false;
        }
 
        /**
         * Returns an array of parameter descriptions.
-        * Don't call this functon directly: use getFinalParamDescription() to
+        * Don't call this function directly: use getFinalParamDescription() to
         * allow hooks to modify descriptions as needed.
         * @return array|bool False on no parameter descriptions
         */
@@ -516,11 +541,13 @@ abstract class ApiBase extends ContextSource {
         * Get final list of parameters, after hooks have had a chance to
         * tweak it as needed.
         *
+        * @param $flags int Zero or more flags like GET_VALUES_FOR_HELP
         * @return array|Bool False on no parameters
+        * @since 1.21 $flags param added
         */
-       public function getFinalParams() {
-               $params = $this->getAllowedParams();
-               wfRunHooks( 'APIGetAllowedParams', array( &$this, &$params ) );
+       public function getFinalParams( $flags = 0 ) {
+               $params = $this->getAllowedParams( $flags );
+               wfRunHooks( 'APIGetAllowedParams', array( &$this, &$params, $flags ) );
                return $params;
        }
 
@@ -1303,8 +1330,8 @@ abstract class ApiBase extends ContextSource {
                // uploadMsgs
                'invalid-file-key' => array( 'code' => 'invalid-file-key', 'info' => 'Not a valid file key' ),
                'nouploadmodule' => array( 'code' => 'nouploadmodule', 'info' => 'No upload module set' ),
-               'uploaddisabled' => array( 'code' => 'uploaddisabled', 'info' => 'Uploads are not enabled.  Make sure $wgEnableUploads is set to true in LocalSettings.php and the PHP ini setting file_uploads is true' ),
-               'copyuploaddisabled' => array( 'code' => 'copyuploaddisabled', 'info' => 'Uploads by URL is not enabled.  Make sure $wgAllowCopyUploads is set to true in LocalSettings.php.' ),
+               'uploaddisabled' => array( 'code' => 'uploaddisabled', 'info' => 'Uploads are not enabled. Make sure $wgEnableUploads is set to true in LocalSettings.php and the PHP ini setting file_uploads is true' ),
+               'copyuploaddisabled' => array( 'code' => 'copyuploaddisabled', 'info' => 'Uploads by URL is not enabled. Make sure $wgAllowCopyUploads is set to true in LocalSettings.php.' ),
                'copyuploadbaddomain' => array( 'code' => 'copyuploadbaddomain', 'info' => 'Uploads by URL are not allowed from this domain.' ),
 
                'filename-tooshort' => array( 'code' => 'filename-tooshort', 'info' => 'The filename is too short' ),
@@ -1640,10 +1667,16 @@ abstract class ApiBase extends ContextSource {
        }
 
        /**
+        * Gets a default slave database connection object
         * @return DatabaseBase
         */
        protected function getDB() {
-               return wfGetDB( DB_SLAVE, 'api' );
+               if ( !isset( $this->mSlaveDB ) ) {
+                       $this->profileDBIn();
+                       $this->mSlaveDB = wfGetDB( DB_SLAVE, 'api' );
+                       $this->profileDBOut();
+               }
+               return $this->mSlaveDB;
        }
 
        /**
index 8f71b16..2e4155a 100644 (file)
  */
 class ApiBlock extends ApiBase {
 
-       public function __construct( $main, $action ) {
-               parent::__construct( $main, $action );
-       }
-
        /**
         * Blocks the user specified in the parameters for the given expiry, with the
         * given reason, and with all other settings provided in the params. If the block
index 863b70b..6b894c1 100644 (file)
 
 class ApiComparePages extends ApiBase {
 
-       public function __construct( $main, $action ) {
-               parent::__construct( $main, $action );
-       }
-
        public function execute() {
                $params = $this->extractRequestParams();
 
index cfa8035..422524d 100644 (file)
  */
 class ApiDelete extends ApiBase {
 
-       public function __construct( $main, $action ) {
-               parent::__construct( $main, $action );
-       }
-
        /**
         * Extracts the title, token, and reason from the request parameters and invokes
         * the local delete() function with these as arguments. It does not make use of
index ebcfa01..e5ef3b7 100644 (file)
  */
 class ApiDisabled extends ApiBase {
 
-       public function __construct( $main, $action ) {
-               parent::__construct( $main, $action );
-       }
-
        public function execute() {
                $this->dieUsage( "The \"{$this->getModuleName()}\" module has been disabled.", 'moduledisabled' );
        }
index 74d3e14..f6e0679 100644 (file)
  */
 class ApiEditPage extends ApiBase {
 
-       public function __construct( $query, $moduleName ) {
-               parent::__construct( $query, $moduleName );
-       }
-
        public function execute() {
                $user = $this->getUser();
                $params = $this->extractRequestParams();
index ba8edc0..5a5c572 100644 (file)
  */
 class ApiEmailUser extends ApiBase {
 
-       public function __construct( $main, $action ) {
-               parent::__construct( $main, $action );
-       }
-
        public function execute() {
                $params = $this->extractRequestParams();
 
index f740cf8..826171b 100644 (file)
  */
 class ApiExpandTemplates extends ApiBase {
 
-       public function __construct( $main, $action ) {
-               parent::__construct( $main, $action );
-       }
-
        public function execute() {
                // Cache may vary on $wgUser because ParserOptions gets data from it
                $this->getMain()->setCacheMode( 'anon-public-user-private' );
index 2f02674..015a992 100644 (file)
  */
 class ApiFeedContributions extends ApiBase {
 
-       public function __construct( $main, $action ) {
-               parent::__construct( $main, $action );
-       }
-
        /**
         * This module uses a custom feed wrapper printer.
         *
index 7a91641..a3b4682 100644 (file)
  */
 class ApiFeedWatchlist extends ApiBase {
 
-       public function __construct( $main, $action ) {
-               parent::__construct( $main, $action );
-       }
-
        /**
         * This module uses a custom feed wrapper printer.
         *
index 1e463e5..9520dc7 100644 (file)
@@ -37,10 +37,6 @@ class ApiFileRevert extends ApiBase {
 
        protected $params;
 
-       public function __construct( $main, $action ) {
-               parent::__construct( $main, $action );
-       }
-
        public function execute() {
                $this->params = $this->extractRequestParams();
                // Extract the file and archiveName from the request parameters
@@ -73,8 +69,8 @@ class ApiFileRevert extends ApiBase {
        protected function checkPermissions( $user ) {
                $title = $this->file->getTitle();
                $permissionErrors = array_merge(
-                       $title->getUserPermissionsErrors( 'edit' , $user ),
-                       $title->getUserPermissionsErrors( 'upload' , $user )
+                       $title->getUserPermissionsErrors( 'edit', $user ),
+                       $title->getUserPermissionsErrors( 'upload', $user )
                );
 
                if ( $permissionErrors ) {
index f280a29..1b2e02c 100644 (file)
  */
 class ApiFormatDbg extends ApiFormatBase {
 
-       public function __construct( $main, $format ) {
-               parent::__construct( $main, $format );
-       }
-
        public function getMimeType() {
                // This looks like it should be text/plain, but IE7 is so
                // brain-damaged it tries to parse text/plain as HTML if it
index db66083..62253e1 100644 (file)
  */
 class ApiFormatDump extends ApiFormatBase {
 
-       public function __construct( $main, $format ) {
-               parent::__construct( $main, $format );
-       }
-
        public function getMimeType() {
                // This looks like it should be text/plain, but IE7 is so
                // brain-damaged it tries to parse text/plain as HTML if it
index bee1ac9..78023af 100644 (file)
  */
 class ApiFormatNone extends ApiFormatBase {
 
-       public function __construct( $main, $format ) {
-               parent::__construct( $main, $format );
-       }
-
        public function getMimeType() {
                return 'text/plain';
        }
index 99a047a..b2d1f04 100644 (file)
  */
 class ApiFormatPhp extends ApiFormatBase {
 
-       public function __construct( $main, $format ) {
-               parent::__construct( $main, $format );
-       }
-
        public function getMimeType() {
                return 'application/vnd.php.serialized';
        }
index 3e1f592..4130e70 100644 (file)
  */
 class ApiFormatTxt extends ApiFormatBase {
 
-       public function __construct( $main, $format ) {
-               parent::__construct( $main, $format );
-       }
-
        public function getMimeType() {
                // This looks like it should be text/plain, but IE7 is so
                // brain-damaged it tries to parse text/plain as HTML if it
index fd1b327..62b69bb 100644 (file)
  */
 class ApiFormatWddx extends ApiFormatBase {
 
-       public function __construct( $main, $format ) {
-               parent::__construct( $main, $format );
-       }
-
        public function getMimeType() {
                return 'text/xml';
        }
index 8dbeae4..b4e8e33 100644 (file)
@@ -36,10 +36,6 @@ class ApiFormatXml extends ApiFormatBase {
        private $mIncludeNamespace = false;
        private $mXslt = null;
 
-       public function __construct( $main, $format ) {
-               parent::__construct( $main, $format );
-       }
-
        public function getMimeType() {
                return 'text/xml';
        }
@@ -92,7 +88,7 @@ class ApiFormatXml extends ApiFormatBase {
         *
         * @par Example:
         * @verbatim
-        * name='root',  value = array( '_element'=>'page', 'x', 'y', 'z')
+        * name='root', value = array( '_element'=>'page', 'x', 'y', 'z')
         * @endverbatim
         * creates:
         * @verbatim
@@ -105,7 +101,7 @@ class ApiFormatXml extends ApiFormatBase {
         *
         * @par Example:
         * @verbatim
-        * name='root',  value = array( '*'=>'text', 'lang'=>'en', 'id'=>10)
+        * name='root', value = array( '*'=>'text', 'lang'=>'en', 'id'=>10)
         * @endverbatim
         * creates:
         * @verbatim
index 28bb2e9..9cafc5b 100644 (file)
  */
 class ApiHelp extends ApiBase {
 
-       public function __construct( $main, $action ) {
-               parent::__construct( $main, $action );
-       }
-
        /**
         * Module for displaying help
         */
@@ -47,43 +43,62 @@ class ApiHelp extends ApiBase {
                }
 
                $this->getMain()->setHelp();
-
                $result = $this->getResult();
-               $queryObj = new ApiQuery( $this->getMain(), 'query' );
-               $r = array();
-               if ( is_array( $params['modules'] ) ) {
-                       $modArr = $this->getMain()->getModules();
 
-                       foreach ( $params['modules'] as $m ) {
-                               if ( !isset( $modArr[$m] ) ) {
-                                       $r[] = array( 'name' => $m, 'missing' => '' );
-                                       continue;
-                               }
-                               $module = new $modArr[$m]( $this->getMain(), $m );
-
-                               $r[] = $this->buildModuleHelp( $module, 'action' );
-                       }
+               if ( is_array( $params['modules'] ) ) {
+                       $modules = $params['modules'];
+               } else {
+                       $modules = array();
                }
 
                if ( is_array( $params['querymodules'] ) ) {
-                       $qmodArr = $queryObj->getModules();
+                       $queryModules = $params['querymodules'];
+                       foreach ( $queryModules as $m ) {
+                               $modules[] = 'query+' . $m;
+                       }
+               } else {
+                       $queryModules = array();
+               }
 
-                       foreach ( $params['querymodules'] as $qm ) {
-                               if ( !isset( $qmodArr[$qm] ) ) {
-                                       $r[] = array( 'name' => $qm, 'missing' => '' );
-                                       continue;
+               $r = array();
+               foreach ( $modules as $m ) {
+                       // sub-modules could be given in the form of "name[+name[+name...]]"
+                       $subNames = explode( '+', $m );
+                       if ( count( $subNames ) === 1 ) {
+                               // In case the '+' was typed into URL, it resolves as a space
+                               $subNames = explode( ' ', $m );
+                       }
+                       $module = $this->getMain();
+                       for ( $i = 0; $i < count( $subNames ); $i++ ) {
+                               $subs = $module->getModuleManager();
+                               if ( $subs === null ) {
+                                       $module = null;
+                               } else {
+                                       $module = $subs->getModule( $subNames[$i] );
                                }
-                               $module = new $qmodArr[$qm]( $this, $qm );
-                               $type = $queryObj->getModuleType( $qm );
-
-                               if ( $type === null ) {
-                                       $r[] = array( 'name' => $qm, 'missing' => '' );
-                                       continue;
+                               if ( $module === null ) {
+                                       if ( count( $subNames ) === 2
+                                                       && $i === 1
+                                                       && $subNames[0] === 'query'
+                                                       && in_array( $subNames[1], $queryModules )
+                                       ) {
+                                               // Legacy: This is one of the renamed 'querymodule=...' parameters,
+                                               // do not use '+' notation in the output, use submodule's name instead.
+                                               $name = $subNames[1];
+                                       } else {
+                                               $name = implode( '+', array_slice( $subNames, 0, $i + 1 ) );
+                                       }
+                                       $r[] = array( 'name' => $name, 'missing' => '' );
+                                       break;
+                               } else {
+                                       $type = $subs->getModuleGroup( $subNames[$i] );
                                }
-
+                       }
+                       if ( $module !== null ) {
                                $r[] = $this->buildModuleHelp( $module, $type );
                        }
                }
+
                $result->setIndexedTagName( $r, 'module' );
                $result->addValue( null, $this->getModuleName(), $r );
        }
@@ -118,15 +133,16 @@ class ApiHelp extends ApiBase {
                                ApiBase::PARAM_ISMULTI => true
                        ),
                        'querymodules' => array(
-                               ApiBase::PARAM_ISMULTI => true
+                               ApiBase::PARAM_ISMULTI => true,
+                               ApiBase::PARAM_DEPRECATED => true
                        ),
                );
        }
 
        public function getParamDescription() {
                return array(
-                       'modules' => 'List of module names (value of the action= parameter)',
-                       'querymodules' => 'List of query module names (value of prop=, meta= or list= parameter)',
+                       'modules' => 'List of module names (value of the action= parameter). Can specify submodules with a \'+\'',
+                       'querymodules' => 'Use modules=query+value instead. List of query module names (value of prop=, meta= or list= parameter)',
                );
        }
 
@@ -138,9 +154,8 @@ class ApiHelp extends ApiBase {
                return array(
                        'api.php?action=help' => 'Whole help page',
                        'api.php?action=help&modules=protect' => 'Module (action) help page',
-                       'api.php?action=help&querymodules=categorymembers' => 'Query (list) modules help page',
-                       'api.php?action=help&querymodules=info' => 'Query (prop) modules help page',
-                       'api.php?action=help&querymodules=siteinfo' => 'Query (meta) modules help page',
+                       'api.php?action=help&modules=query+categorymembers' => 'Help for the query/categorymembers module',
+                       'api.php?action=help&modules=login|query+info' => 'Help for the login and query/info modules',
                );
        }
 
index f5636bd..408805e 100644 (file)
  */
 class ApiImport extends ApiBase {
 
-       public function __construct( $main, $action ) {
-               parent::__construct( $main, $action );
-       }
-
        public function execute() {
                $user = $this->getUser();
                $params = $this->extractRequestParams();
@@ -150,7 +146,7 @@ class ApiImport extends ApiBase {
 
        public function getDescription() {
                return array(
-                       'Import a page from another wiki, or an XML file.' ,
+                       'Import a page from another wiki, or an XML file.',
                        'Note that the HTTP POST must be done as a file upload (i.e. using multipart/form-data) when',
                        'sending a file for the "xml" parameter.'
                );
index 00dd625..2ba92a6 100644 (file)
  */
 class ApiLogout extends ApiBase {
 
-       public function __construct( $main, $action ) {
-               parent::__construct( $main, $action );
-       }
-
        public function execute() {
                $user = $this->getUser();
                $oldName = $user->getName();
index 70c31c1..953cec8 100644 (file)
@@ -131,8 +131,9 @@ class ApiMain extends ApiBase {
         */
        private $mPrinter;
 
-       private $mModules, $mModuleNames, $mFormats, $mFormatNames;
-       private $mResult, $mAction, $mEnableWrite;
+       private $mModuleMgr, $mResult;
+       private $mAction;
+       private $mEnableWrite;
        private $mInternalMode, $mSquidMaxage, $mModule;
 
        private $mCacheMode = 'private';
@@ -180,12 +181,11 @@ class ApiMain extends ApiBase {
                        }
                }
 
-               global $wgAPIModules; // extension modules
-               $this->mModules = $wgAPIModules + self::$Modules;
-
-               $this->mModuleNames = array_keys( $this->mModules );
-               $this->mFormats = self::$Formats;
-               $this->mFormatNames = array_keys( $this->mFormats );
+               global $wgAPIModules;
+               $this->mModuleMgr = new ApiModuleManager( $this );
+               $this->mModuleMgr->addModules( self::$Modules, 'action' );
+               $this->mModuleMgr->addModules( $wgAPIModules, 'action' );
+               $this->mModuleMgr->addModules( self::$Formats, 'format' );
 
                $this->mResult = new ApiResult( $this );
                $this->mEnableWrite = $enableWrite;
@@ -332,10 +332,11 @@ class ApiMain extends ApiBase {
         * @return ApiFormatBase
         */
        public function createPrinterByName( $format ) {
-               if ( !isset( $this->mFormats[$format] ) ) {
+               $printer = $this->mModuleMgr->getModule( $format, 'format' );
+               if ( $printer === null ) {
                        $this->dieUsage( "Unrecognized format: {$format}", 'unknown_format' );
                }
-               return new $this->mFormats[$format] ( $this, $format );
+               return $printer;
        }
 
        /**
@@ -604,7 +605,7 @@ class ApiMain extends ApiBase {
                if ( !isset ( $this->mPrinter ) ) {
                        // The printer has not been created yet. Try to manually get formatter value.
                        $value = $this->getRequest()->getVal( 'format', self::API_DEFAULT_FORMAT );
-                       if ( !in_array( $value, $this->mFormatNames ) ) {
+                       if ( !$this->mModuleMgr->isDefined( $value, 'format' ) ) {
                                $value = self::API_DEFAULT_FORMAT;
                        }
 
@@ -700,9 +701,10 @@ class ApiMain extends ApiBase {
         */
        protected function setupModule() {
                // Instantiate the module requested by the user
-               $module = new $this->mModules[$this->mAction] ( $this, $this->mAction );
-               $this->mModule = $module;
-
+               $module = $this->mModuleMgr->getModule( $this->mAction, 'action' );
+               if ( $module === null ) {
+                       $this->dieUsage( 'The API requires a valid action parameter', 'unknown_action' );
+               }
                $moduleParams = $module->extractRequestParams();
 
                // Die if token required, but not provided (unless there is a gettoken parameter)
@@ -814,6 +816,7 @@ class ApiMain extends ApiBase {
        protected function executeAction() {
                $params = $this->setupExecuteAction();
                $module = $this->setupModule();
+               $this->mModule = $module;
 
                $this->checkExecutePermissions( $module );
 
@@ -933,7 +936,7 @@ class ApiMain extends ApiBase {
        protected function printResult( $isError ) {
                global $wgDebugAPI;
                if( $wgDebugAPI !== false ) {
-                       $this->getResult()->setWarning( 'SECURITY WARNING: $wgDebugAPI is enabled' );
+                       $this->setWarning( 'SECURITY WARNING: $wgDebugAPI is enabled' );
                }
 
                $this->getResult()->cleanUpUTF8();
@@ -971,11 +974,11 @@ class ApiMain extends ApiBase {
                return array(
                        'format' => array(
                                ApiBase::PARAM_DFLT => ApiMain::API_DEFAULT_FORMAT,
-                               ApiBase::PARAM_TYPE => $this->mFormatNames
+                               ApiBase::PARAM_TYPE => $this->mModuleMgr->getNames( 'format' )
                        ),
                        'action' => array(
                                ApiBase::PARAM_DFLT => 'help',
-                               ApiBase::PARAM_TYPE => $this->mModuleNames
+                               ApiBase::PARAM_TYPE => $this->mModuleMgr->getNames( 'action' )
                        ),
                        'maxlag'  => array(
                                ApiBase::PARAM_TYPE => 'integer'
@@ -1092,7 +1095,7 @@ class ApiMain extends ApiBase {
                        '    Victor Vasiliev - vasilvv at gee mail dot com',
                        '    Bryan Tong Minh - bryan . tongminh @ gmail . com',
                        '    Sam Reed - sam @ reedyboy . net',
-                       '    Yuri Astrakhan "<Firstname><Lastname>@gmail.com" (creator, lead developer Sep 2006-Sep 2007)',
+                       '    Yuri Astrakhan "<Firstname><Lastname>@gmail.com" (creator, lead developer Sep 2006-Sep 2007, 2012)',
                        '',
                        'Please send your comments, suggestions and questions to mediawiki-api@lists.wikimedia.org',
                        'or file a bug report at https://bugzilla.wikimedia.org/'
@@ -1143,8 +1146,9 @@ class ApiMain extends ApiBase {
 
                $astriks = str_repeat( '*** ', 14 );
                $msg .= "\n\n$astriks Modules  $astriks\n\n";
-               foreach ( array_keys( $this->mModules ) as $moduleName ) {
-                       $module = new $this->mModules[$moduleName] ( $this, $moduleName );
+
+               foreach ( $this->mModuleMgr->getNames( 'action' ) as $name ) {
+                       $module = $this->mModuleMgr->getModule( $name );
                        $msg .= self::makeHelpMsgHeader( $module, 'action' );
 
                        $msg2 = $module->makeHelpMsg();
@@ -1162,8 +1166,8 @@ class ApiMain extends ApiBase {
                }
 
                $msg .= "\n$astriks Formats  $astriks\n\n";
-               foreach ( array_keys( $this->mFormats ) as $formatName ) {
-                       $module = $this->createPrinterByName( $formatName );
+               foreach ( $this->mModuleMgr->getNames( 'format' ) as $name ) {
+                       $module = $this->mModuleMgr->getModule( $name );
                        $msg .= self::makeHelpMsgHeader( $module, 'format' );
                        $msg2 = $module->makeHelpMsg();
                        if ( $msg2 !== false ) {
@@ -1215,45 +1219,57 @@ class ApiMain extends ApiBase {
                return false;
        }
 
+       /**
+        * Overrides to return this instance's module manager.
+        * @return ApiModuleManager
+        */
+       public function getModuleManager() {
+               return $this->mModuleMgr;
+       }
+
        /**
         * Add or overwrite a module in this ApiMain instance. Intended for use by extending
         * classes who wish to add their own modules to their lexicon or override the
         * behavior of inherent ones.
         *
-        * @param $mdlName String The identifier for this module.
-        * @param $mdlClass String The class where this module is implemented.
+        * @deprecated since 1.21, Use getModuleManager()->addModule() instead.
+        * @param $name string The identifier for this module.
+        * @param $class ApiBase The class where this module is implemented.
         */
-       protected function addModule( $mdlName, $mdlClass ) {
-               $this->mModules[$mdlName] = $mdlClass;
+       protected function addModule( $name, $class ) {
+               $this->getModuleManager()->addModule( $name, 'action', $class );
        }
 
        /**
         * Add or overwrite an output format for this ApiMain. Intended for use by extending
         * classes who wish to add to or modify current formatters.
         *
-        * @param $fmtName string The identifier for this format.
-        * @param $fmtClass ApiFormatBase The class implementing this format.
+        * @deprecated since 1.21, Use getModuleManager()->addModule() instead.
+        * @param $name string The identifier for this format.
+        * @param $class ApiFormatBase The class implementing this format.
         */
-       protected function addFormat( $fmtName, $fmtClass ) {
-               $this->mFormats[$fmtName] = $fmtClass;
+       protected function addFormat( $name, $class ) {
+               $this->getModuleManager->addModule( $name, 'format', $class );
        }
 
        /**
         * Get the array mapping module names to class names
+        * @deprecated since 1.21, Use getModuleManager()'s methods instead.
         * @return array
         */
        function getModules() {
-               return $this->mModules;
+               return $this->getModuleManager()->getNamesWithClasses( 'action' );
        }
 
        /**
         * Returns the list of supported formats in form ( 'format' => 'ClassName' )
         *
         * @since 1.18
+        * @deprecated since 1.21, Use getModuleManager()'s methods instead.
         * @return array
         */
        public function getFormats() {
-               return $this->mFormats;
+               return $this->getModuleManager()->getNamesWithClasses( 'format' );
        }
 }
 
diff --git a/includes/api/ApiModuleManager.php b/includes/api/ApiModuleManager.php
new file mode 100644 (file)
index 0000000..db1d36d
--- /dev/null
@@ -0,0 +1,171 @@
+<?php
+/**
+ *
+ *
+ * Created on Dec 27, 2012
+ *
+ * Copyright © 2012 Yuri Astrakhan "<Firstname><Lastname>@gmail.com"
+ *
+ * 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
+ * @since 1.21
+ */
+
+/**
+ * This class holds a list of modules and handles instantiation
+ *
+ * @since 1.21
+ * @ingroup API
+ */
+class ApiModuleManager extends ContextSource {
+
+       private $mParent;
+       private $mInstances = array();
+       private $mGroups = array();
+       private $mModules = array();
+
+       /**
+        * Construct new module manager
+        * @param ApiBase $parentModule Parent module instance will be used during instantiation
+        */
+       public function __construct( ApiBase $parentModule ) {
+               $this->mParent = $parentModule;
+       }
+
+       /**
+        * Add a list of modules to the manager
+        * @param array $modules A map of ModuleName => ModuleClass
+        * @param string $group Which group modules belong to (action,format,...)
+        */
+       public function addModules( array $modules, $group ) {
+               foreach ( $modules as $name => $class ) {
+                       $this->addModule( $name, $group, $class );
+               }
+       }
+
+       /**
+        * Add or overwrite a module in this ApiMain instance. Intended for use by extending
+        * classes who wish to add their own modules to their lexicon or override the
+        * behavior of inherent ones.
+        *
+        * @param $group string Name of the module group
+        * @param $name string The identifier for this module.
+        * @param $class string The class where this module is implemented.
+        */
+       public function addModule( $name, $group, $class ) {
+               $this->mGroups[$group] = null;
+               $this->mModules[$name] = array( $group, $class );
+       }
+
+       /**
+        * Get module instance by name, or instantiate it if it does not exist
+        * @param $moduleName string module name
+        * @param $group string optionally validate that the module is in a specific group
+        * @param $ignoreCache bool if true, force-creates a new instance and does not cache it
+        * @return mixed the new module instance, or null if failed
+        */
+       public function getModule( $moduleName, $group = null, $ignoreCache = false ) {
+               if ( !isset( $this->mModules[$moduleName] ) ) {
+                       return null;
+               }
+               $grpCls = $this->mModules[$moduleName];
+               if ( $group !== null && $grpCls[0] !== $group ) {
+                       return null;
+               }
+               if ( !$ignoreCache && isset( $this->mInstances[$moduleName] ) ) {
+                       // already exists
+                       return $this->mInstances[$moduleName];
+               } else {
+                       // new instance
+                       $class = $grpCls[1];
+                       $instance = new $class ( $this->mParent, $moduleName );
+                       if ( !$ignoreCache ) {
+                               // cache this instance in case it is needed later
+                               $this->mInstances[$moduleName] = $instance;
+                       }
+                       return $instance;
+               }
+       }
+
+       /**
+        * Get an array of modules in a specific group or all if no group is set.
+        * @param string $group optional group filter
+        * @return array list of module names
+        */
+       public function getNames( $group = null ) {
+               if ( $group === null ) {
+                       return array_keys( $this->mModules );
+               }
+               $result = array();
+               foreach ( $this->mModules as $name => $grpCls ) {
+                       if ( $grpCls[0] === $group ) {
+                               $result[] = $name;
+                       }
+               }
+               return $result;
+       }
+
+       /**
+        * Create an array of (moduleName => moduleClass) for a specific group or for all.
+        * @param string $group name of the group to get or null for all
+        * @return array name=>class map
+        */
+       public function getNamesWithClasses( $group = null ) {
+               $result = array();
+               foreach ( $this->mModules as $name => $grpCls ) {
+                       if ( $group === null || $grpCls[0] === $group ) {
+                               $result[$name] = $grpCls[1];
+                       }
+               }
+               return $result;
+       }
+
+       /**
+        * Returns true if the specific module is defined at all or in a specific group.
+        * @param string $moduleName module name
+        * @param string $group group name to check against, or null to check all groups,
+        * @return boolean true if defined
+        */
+       public function isDefined( $moduleName, $group = null ) {
+               if ( isset( $this->mModules[$moduleName] ) ) {
+                       return $group === null || $this->mModules[$moduleName][0] === $group;
+               } else {
+                       return false;
+               }
+       }
+
+       /**
+        * Returns the group name for the given module
+        * @param string $moduleName
+        * @return string group name or null if missing
+        */
+       public function getModuleGroup( $moduleName ) {
+               if ( isset( $this->mModules[$moduleName] ) ) {
+                       return $this->mModules[$moduleName][0];
+               } else {
+                       return null;
+               }
+       }
+
+       /**
+        * Get a list of groups this manager contains.
+        * @return array
+        */
+       public function getGroups() {
+               return array_keys( $this->mGroups );
+       }
+}
index bbf4089..3f54fee 100644 (file)
  */
 class ApiMove extends ApiBase {
 
-       public function __construct( $main, $action ) {
-               parent::__construct( $main, $action );
-       }
-
        public function execute() {
                $user = $this->getUser();
                $params = $this->extractRequestParams();
index 6403bd6..caf361a 100644 (file)
  */
 class ApiOpenSearch extends ApiBase {
 
-       public function __construct( $main, $action ) {
-               parent::__construct( $main, $action );
-       }
-
        public function getCustomPrinter() {
                return $this->getMain()->createPrinterByName( 'json' );
        }
index eff05de..faebcdc 100644 (file)
  */
 class ApiOptions extends ApiBase {
 
-       public function __construct( $main, $action ) {
-               parent::__construct( $main, $action );
-       }
-
        /**
         * Changes preferences of the current user.
         */
index e2f4dae..3945104 100644 (file)
@@ -4,7 +4,7 @@
  *
  * Created on Sep 24, 2006
  *
- * Copyright © 2006 Yuri Astrakhan "<Firstname><Lastname>@gmail.com"
+ * Copyright © 2006, 2013 Yuri Astrakhan "<Firstname><Lastname>@gmail.com"
  *
  * 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 second instance for all their work.
  *
  * @ingroup API
+ * @since 1.21 derives from ApiBase instead of ApiQueryBase
  */
-class ApiPageSet extends ApiQueryBase {
+class ApiPageSet extends ApiBase {
 
-       private $mAllPages; // [ns][dbkey] => page_id or negative when missing
-       private $mTitles, $mGoodTitles, $mMissingTitles, $mInvalidTitles;
-       private $mMissingPageIDs, $mRedirectTitles, $mSpecialTitles;
-       private $mNormalizedTitles, $mInterwikiTitles;
-       private $mResolveRedirects, $mPendingRedirectIDs;
-       private $mConvertTitles, $mConvertedTitles;
-       private $mGoodRevIDs, $mMissingRevIDs;
-       private $mFakePageId;
+       /**
+        * Constructor flag: The new instance of ApiPageSet will ignore the 'generator=' parameter
+        * @since 1.21
+        */
+       const DISABLE_GENERATORS = 1;
 
-       private $mRequestedPageFields;
+       private $mDbSource, $mParams;
+       private $mResolveRedirects, $mConvertTitles, $mAllowGenerator;
+
+       private $mAllPages = array(); // [ns][dbkey] => page_id or negative when missing
+       private $mTitles = array();
+       private $mGoodTitles = array();
+       private $mMissingTitles = array();
+       private $mInvalidTitles = array();
+       private $mMissingPageIDs = array();
+       private $mRedirectTitles = array();
+       private $mSpecialTitles = array();
+       private $mNormalizedTitles = array();
+       private $mInterwikiTitles = array();
+       private $mPendingRedirectIDs = array();
+       private $mConvertedTitles = array();
+       private $mGoodRevIDs = array();
+       private $mMissingRevIDs = array();
+       private $mFakePageId = -1;
+       private $mCacheMode = 'public';
+       private $mRequestedPageFields = array();
 
        /**
         * Constructor
-        * @param $query ApiBase
-        * @param $resolveRedirects bool Whether redirects should be resolved
-        * @param $convertTitles bool
-        */
-       public function __construct( $query, $resolveRedirects = false, $convertTitles = false ) {
-               parent::__construct( $query, 'query' );
-
-               $this->mAllPages = array();
-               $this->mTitles = array();
-               $this->mGoodTitles = array();
-               $this->mMissingTitles = array();
-               $this->mInvalidTitles = array();
-               $this->mMissingPageIDs = array();
-               $this->mRedirectTitles = array();
-               $this->mNormalizedTitles = array();
-               $this->mInterwikiTitles = array();
-               $this->mGoodRevIDs = array();
-               $this->mMissingRevIDs = array();
-               $this->mSpecialTitles = array();
-
-               $this->mRequestedPageFields = array();
-               $this->mResolveRedirects = $resolveRedirects;
-               if ( $resolveRedirects ) {
-                       $this->mPendingRedirectIDs = array();
-               }
+        * @param $dbSource ApiBase Module implementing getDB().
+        *        Allows PageSet to reuse existing db connection from the shared state like ApiQuery.
+        * @param $flags int Zero or more flags like DISABLE_GENERATORS
+        * @since 1.21 accepts $flags instead of two boolean values
+        */
+       public function __construct( ApiBase $dbSource, $flags = 0 ) {
+               parent::__construct( $dbSource->getMain(), $dbSource->getModuleName() );
+               $this->mDbSource = $dbSource;
+               $this->mAllowGenerator = ( $flags & ApiPageSet::DISABLE_GENERATORS ) == 0;
 
-               $this->mConvertTitles = $convertTitles;
-               $this->mConvertedTitles = array();
+               $this->profileIn();
+               $this->mParams = $this->extractRequestParams();
+               $this->mResolveRedirects = $this->mParams['redirects'];
+               $this->mConvertTitles = $this->mParams['converttitles'];
+               $this->profileOut();
+       }
 
-               $this->mFakePageId = - 1;
+       /**
+        * Populate the PageSet from the request parameters.
+        */
+       public function execute() {
+               $this->profileIn();
+
+               $generatorName = $this->mAllowGenerator ? $this->mParams['generator'] : null;
+               if ( isset( $generatorName ) ) {
+                       $dbSource = $this->mDbSource;
+                       $isQuery = $dbSource instanceof ApiQuery;
+                       if ( !$isQuery ) {
+                               // If the parent container of this pageset is not ApiQuery, we must create it to run generator
+                               $dbSource = $this->getMain()->getModuleManager()->getModule( 'query' );
+                               // Enable profiling for query module because it will be used for db sql profiling
+                               $dbSource->profileIn();
+                       }
+                       $generator = $dbSource->getModuleManager()->getModule( $generatorName, null, true );
+                       if ( $generator === null ) {
+                               $this->dieUsage( 'Unknown generator=' . $generatorName, 'badgenerator' );
+                       }
+                       if ( !$generator instanceof ApiQueryGeneratorBase ) {
+                               $this->dieUsage( "Module $generatorName cannot be used as a generator", 'badgenerator' );
+                       }
+                       // Create a temporary pageset to store generator's output,
+                       // add any additional fields generator may need, and execute pageset to populate titles/pageids
+                       $tmpPageSet = new ApiPageSet( $dbSource, ApiPageSet::DISABLE_GENERATORS );
+                       $generator->setGeneratorMode( $tmpPageSet );
+                       $this->mCacheMode = $generator->getCacheMode( $generator->extractRequestParams() );
+                       $generator->requestExtraData( $tmpPageSet );
+                       $tmpPageSet->execute();
+
+                       // populate this pageset with the generator output
+                       $this->profileOut();
+                       $generator->profileIn();
+                       $generator->executeGenerator( $this );
+                       wfRunHooks( 'APIQueryGeneratorAfterExecute', array( &$generator, &$this ) );
+                       $this->resolvePendingRedirects();
+                       $generator->profileOut();
+                       $this->profileIn();
+
+                       if ( !$isQuery ) {
+                               // If this pageset is not part of the query, we called profileIn() above
+                               $dbSource->profileOut();
+                       }
+               } else {
+                       // Only one of the titles/pageids/revids is allowed at the same time
+                       $dataSource = null;
+                       if ( isset( $this->mParams['titles'] ) ) {
+                               $dataSource = 'titles';
+                       }
+                       if ( isset( $this->mParams['pageids'] ) ) {
+                               if ( isset( $dataSource ) ) {
+                                       $this->dieUsage( "Cannot use 'pageids' at the same time as '$dataSource'", 'multisource' );
+                               }
+                               $dataSource = 'pageids';
+                       }
+                       if ( isset( $this->mParams['revids'] ) ) {
+                               if ( isset( $dataSource ) ) {
+                                       $this->dieUsage( "Cannot use 'revids' at the same time as '$dataSource'", 'multisource' );
+                               }
+                               $dataSource = 'revids';
+                       }
+                       // Populate page information with the original user input
+                       switch( $dataSource ) {
+                               case 'titles':
+                                       $this->initFromTitles( $this->mParams['titles'] );
+                                       break;
+                               case 'pageids':
+                                       $this->initFromPageIds( $this->mParams['pageids'] );
+                                       break;
+                               case 'revids':
+                                       if ( $this->mResolveRedirects ) {
+                                               $this->setWarning( 'Redirect resolution cannot be used together with the revids= parameter. ' .
+                                                       'Any redirects the revids= point to have not been resolved.' );
+                                       }
+                                       $this->mResolveRedirects = false;
+                                       $this->initFromRevIDs( $this->mParams['revids'] );
+                                       break;
+                               default:
+                                       // Do nothing - some queries do not need any of the data sources.
+                                       break;
+                       }
+               }
+               $this->profileOut();
        }
 
        /**
@@ -93,8 +181,8 @@ class ApiPageSet extends ApiQueryBase {
        }
 
        /**
-        * Request an additional field from the page table. Must be called
-        * before execute()
+        * Request an additional field from the page table.
+        * Must be called before execute()
         * @param $fieldName string Field name
         */
        public function requestField( $fieldName ) {
@@ -207,13 +295,38 @@ class ApiPageSet extends ApiQueryBase {
 
        /**
         * Get a list of redirect resolutions - maps a title to its redirect
-        * target.
-        * @return array prefixed_title (string) => Title object
+        * target, as an array of output-ready arrays
+        * @return array
         */
        public function getRedirectTitles() {
                return $this->mRedirectTitles;
        }
 
+       /**
+        * Get a list of redirect resolutions - maps a title to its redirect
+        * target.
+        * @param $result ApiResult
+        * @return array of prefixed_title (string) => Title object
+        * @since 1.21
+        */
+       public function getRedirectTitlesAsResult( $result = null ) {
+               $values = array();
+               foreach ( $this->getRedirectTitles() as $titleStrFrom => $titleTo ) {
+                       $r = array(
+                               'from' => strval( $titleStrFrom ),
+                               'to' => $titleTo->getPrefixedText(),
+                       );
+                       if ( $titleTo->getFragment() !== '' ) {
+                               $r['tofragment'] = $titleTo->getFragment();
+                       }
+                       $values[] = $r;
+               }
+               if ( !empty( $values ) && $result ) {
+                       $result->setIndexedTagName( $values, 'r' );
+               }
+               return $values;
+       }
+
        /**
         * Get a list of title normalizations - maps a title to its normalized
         * version.
@@ -223,6 +336,27 @@ class ApiPageSet extends ApiQueryBase {
                return $this->mNormalizedTitles;
        }
 
+       /**
+        * Get a list of title normalizations - maps a title to its normalized
+        * version in the form of result array.
+        * @param $result ApiResult
+        * @return array of raw_prefixed_title (string) => prefixed_title (string)
+        * @since 1.21
+        */
+       public function getNormalizedTitlesAsResult( $result = null  ) {
+               $values = array();
+               foreach ( $this->getNormalizedTitles() as $rawTitleStr => $titleStr ) {
+                       $values[] = array(
+                               'from' => $rawTitleStr,
+                               'to' => $titleStr
+                       );
+               }
+               if ( !empty( $values ) && $result ) {
+                       $result->setIndexedTagName( $values, 'n' );
+               }
+               return $values;
+       }
+
        /**
         * Get a list of title conversions - maps a title to its converted
         * version.
@@ -232,6 +366,27 @@ class ApiPageSet extends ApiQueryBase {
                return $this->mConvertedTitles;
        }
 
+       /**
+        * Get a list of title conversions - maps a title to its converted
+        * version as a result array.
+        * @param $result ApiResult
+        * @return array of (from, to) strings
+        * @since 1.21
+        */
+       public function getConvertedTitlesAsResult( $result = null ) {
+               $values = array();
+               foreach ( $this->getConvertedTitles() as $rawTitleStr => $titleStr ) {
+                       $values[] = array(
+                               'from' => $rawTitleStr,
+                               'to' => $titleStr
+                       );
+               }
+               if ( !empty( $values ) && $result ) {
+                       $result->setIndexedTagName( $values, 'c' );
+               }
+               return $values;
+       }
+
        /**
         * Get a list of interwiki titles - maps a title to its interwiki
         * prefix.
@@ -241,6 +396,33 @@ class ApiPageSet extends ApiQueryBase {
                return $this->mInterwikiTitles;
        }
 
+       /**
+        * Get a list of interwiki titles - maps a title to its interwiki
+        * prefix as result.
+        * @param $result ApiResult
+        * @param $iwUrl boolean
+        * @return array raw_prefixed_title (string) => interwiki_prefix (string)
+        * @since 1.21
+        */
+       public function getInterwikiTitlesAsResult( $result = null, $iwUrl = false ) {
+               $values = array();
+               foreach ( $this->getInterwikiTitles() as $rawTitleStr => $interwikiStr ) {
+                       $item = array(
+                               'title' => $rawTitleStr,
+                               'iw' => $interwikiStr,
+                       );
+                       if ( $iwUrl ) {
+                               $title = Title::newFromText( $rawTitleStr );
+                               $item['url'] = $title->getFullURL( '', false, PROTO_CURRENT );
+                       }
+                       $values[] = $item;
+               }
+               if ( !empty( $values ) && $result ) {
+                       $result->setIndexedTagName( $values, 'i' );
+               }
+               return $values;
+       }
+
        /**
         * Get the list of revision IDs (requested with the revids= parameter)
         * @return array revID (int) => pageID (int)
@@ -257,6 +439,25 @@ class ApiPageSet extends ApiQueryBase {
                return $this->mMissingRevIDs;
        }
 
+       /**
+        * Revision IDs that were not found in the database as result array.
+        * @param $result ApiResult
+        * @return array of revision IDs
+        * @since 1.21
+        */
+       public function getMissingRevisionIDsAsResult( $result = null ) {
+               $values = array();
+               foreach ( $this->getMissingRevisionIDs() as $revid ) {
+                       $values[$revid] = array(
+                               'revid' => $revid
+                       );
+               }
+               if ( !empty( $values ) && $result ) {
+                       $result->setIndexedTagName( $values, 'rev' );
+               }
+               return $values;
+       }
+
        /**
         * Get the list of titles with negative namespace
         * @return array Title
@@ -273,53 +474,6 @@ class ApiPageSet extends ApiQueryBase {
                return count( $this->getRevisionIDs() );
        }
 
-       /**
-        * Populate the PageSet from the request parameters.
-        */
-       public function execute() {
-               $this->profileIn();
-               $params = $this->extractRequestParams();
-
-               // Only one of the titles/pageids/revids is allowed at the same time
-               $dataSource = null;
-               if ( isset( $params['titles'] ) ) {
-                       $dataSource = 'titles';
-               }
-               if ( isset( $params['pageids'] ) ) {
-                       if ( isset( $dataSource ) ) {
-                               $this->dieUsage( "Cannot use 'pageids' at the same time as '$dataSource'", 'multisource' );
-                       }
-                       $dataSource = 'pageids';
-               }
-               if ( isset( $params['revids'] ) ) {
-                       if ( isset( $dataSource ) ) {
-                               $this->dieUsage( "Cannot use 'revids' at the same time as '$dataSource'", 'multisource' );
-                       }
-                       $dataSource = 'revids';
-               }
-
-               switch ( $dataSource ) {
-                       case 'titles':
-                               $this->initFromTitles( $params['titles'] );
-                               break;
-                       case 'pageids':
-                               $this->initFromPageIds( $params['pageids'] );
-                               break;
-                       case 'revids':
-                               if ( $this->mResolveRedirects ) {
-                                       $this->setWarning( 'Redirect resolution cannot be used together with the revids= parameter. ' .
-                                       'Any redirects the revids= point to have not been resolved.' );
-                               }
-                               $this->mResolveRedirects = false;
-                               $this->initFromRevIDs( $params['revids'] );
-                               break;
-                       default:
-                               // Do nothing - some queries do not need any of the data sources.
-                               break;
-               }
-               $this->profileOut();
-       }
-
        /**
         * Populate this PageSet from a list of Titles
         * @param $titles array of Title objects
@@ -385,12 +539,11 @@ class ApiPageSet extends ApiQueryBase {
        }
 
        /**
-        * Resolve redirects, if applicable
+        * Do not use, does nothing, will be removed
+        * @deprecated 1.21
         */
        public function finishPageSetGeneration() {
-               $this->profileIn();
-               $this->resolvePendingRedirects();
-               $this->profileOut();
+               wfDeprecated( __METHOD__, '1.21' );
        }
 
        /**
@@ -437,7 +590,7 @@ class ApiPageSet extends ApiQueryBase {
         * @param $pageids array of page IDs
         */
        private function initFromPageIds( $pageids ) {
-               if ( !count( $pageids ) ) {
+               if ( !$pageids ) {
                        return;
                }
 
@@ -447,7 +600,7 @@ class ApiPageSet extends ApiQueryBase {
                $pageids = self::getPositiveIntegers( $pageids );
 
                $res = null;
-               if ( count( $pageids ) ) {
+               if ( !empty( $pageids ) ) {
                        $set = array(
                                'page_id' => $pageids
                        );
@@ -499,7 +652,7 @@ class ApiPageSet extends ApiQueryBase {
                                $this->processDbRow( $row );
 
                                // Need gender information
-                               if( MWNamespace::hasGenderDistinction( $row->page_namespace ) ) {
+                               if ( MWNamespace::hasGenderDistinction( $row->page_namespace ) ) {
                                        $usernames[] = $row->page_title;
                                }
                        }
@@ -518,7 +671,7 @@ class ApiPageSet extends ApiQueryBase {
                                                $this->mTitles[] = $title;
 
                                                // need gender information
-                                               if( MWNamespace::hasGenderDistinction( $ns ) ) {
+                                               if ( MWNamespace::hasGenderDistinction( $ns ) ) {
                                                        $usernames[] = $dbkey;
                                                }
                                        }
@@ -544,7 +697,7 @@ class ApiPageSet extends ApiQueryBase {
         * @param $revids array of revision IDs
         */
        private function initFromRevIDs( $revids ) {
-               if ( !count( $revids ) ) {
+               if ( !$revids ) {
                        return;
                }
 
@@ -555,14 +708,14 @@ class ApiPageSet extends ApiQueryBase {
 
                $revids = self::getPositiveIntegers( $revids );
 
-               if ( count( $revids ) ) {
+               if ( !empty( $revids ) ) {
                        $tables = array( 'revision', 'page' );
                        $fields = array( 'rev_id', 'rev_page' );
                        $where = array( 'rev_id' => $revids, 'rev_page = page_id' );
 
                        // Get pageIDs data from the `page` table
                        $this->profileDBIn();
-                       $res = $db->select( $tables, $fields, $where,  __METHOD__ );
+                       $res = $db->select( $tables, $fields, $where, __METHOD__ );
                        foreach ( $res as $row ) {
                                $revid = intval( $row->rev_id );
                                $pageid = intval( $row->rev_page );
@@ -669,6 +822,23 @@ class ApiPageSet extends ApiQueryBase {
                return $lb;
        }
 
+       /**
+        * Get the cache mode for the data generated by this module.
+        * All PageSet users should take into account whether this returns a more-restrictive
+        * cache mode than the using module itself. For possible return values and other
+        * details about cache modes, see ApiMain::setCacheMode()
+        *
+        * Public caching will only be allowed if *all* the modules that supply
+        * data for a given request return a cache mode of public.
+        *
+        * @param $params
+        * @return string
+        * @since 1.21
+        */
+       public function getCacheMode( $params = null ) {
+               return $this->mCacheMode;
+       }
+
        /**
         * Given an array of title strings, convert them into Title objects.
         * Alternativelly, an array of Title objects may be given.
@@ -742,6 +912,14 @@ class ApiPageSet extends ApiQueryBase {
                return $linkBatch;
        }
 
+       /**
+        * Get the database connection (read-only)
+        * @return DatabaseBase
+        */
+       protected function getDB() {
+               return $this->mDbSource->getDB();
+       }
+
        /**
         * Returns the input array of integers with all values < 0 removed
         *
@@ -752,7 +930,7 @@ class ApiPageSet extends ApiQueryBase {
                // bug 25734 API: possible issue with revids validation
                // It seems with a load of revision rows, MySQL gets upset
                // Remove any < 0 integers, as they can't be valid
-               foreach( $array as $i => $int ) {
+               foreach ( $array as $i => $int ) {
                        if ( $int < 0 ) {
                                unset( $array[$i] );
                        }
@@ -761,8 +939,8 @@ class ApiPageSet extends ApiQueryBase {
                return $array;
        }
 
-       public function getAllowedParams() {
-               return array(
+       public function getAllowedParams( $flags = 0 ) {
+               $result = array(
                        'titles' => array(
                                ApiBase::PARAM_ISMULTI => true
                        ),
@@ -773,15 +951,48 @@ class ApiPageSet extends ApiQueryBase {
                        'revids' => array(
                                ApiBase::PARAM_TYPE => 'integer',
                                ApiBase::PARAM_ISMULTI => true
-                       )
+                       ),
+                       'redirects' => false,
+                       'converttitles' => false,
                );
+               if ( $this->mAllowGenerator ) {
+                       $result['generator'] = array(
+                               ApiBase::PARAM_TYPE => $this->getGenerators() );
+               }
+               return $result;
+       }
+
+       private static $generators = null;
+
+       /**
+        * Get an array of all available generators
+        * @return array
+        */
+       private function getGenerators() {
+               if ( self::$generators === null ) {
+                       $query = $this->mDbSource;
+                       if ( !( $query instanceof ApiQuery ) ) {
+                               // If the parent container of this pageset is not ApiQuery,
+                               // we must create it to get module manager
+                               $query = $this->getMain()->getModuleManager()->getModule( 'query' );
+                       }
+                       $gens = array_keys( $query->getGenerators() );
+                       sort( $gens );
+                       self::$generators = $gens;
+               }
+               return self::$generators;
        }
 
        public function getParamDescription() {
                return array(
                        'titles' => 'A list of titles to work on',
                        'pageids' => 'A list of page IDs to work on',
-                       'revids' => 'A list of revision IDs to work on'
+                       'revids' => 'A list of revision IDs to work on',
+                       'generator' => array( 'Get the list of pages to work on by executing the specified query module.',
+                               'NOTE: generator parameter names must be prefixed with a \'g\', see examples' ),
+                       'redirects' => 'Automatically resolve redirects',
+                       'converttitles' => array( 'Convert titles to other variants if necessary. Only works if the wiki\'s content language supports variant conversion.',
+                               'Languages that support variant conversion include ' . implode( ', ', LanguageConverter::$languagesWithVariants ) ),
                );
        }
 
@@ -789,6 +1000,7 @@ class ApiPageSet extends ApiQueryBase {
                return array_merge( parent::getPossibleErrors(), array(
                        array( 'code' => 'multisource', 'info' => "Cannot use 'pageids' at the same time as 'dataSource'" ),
                        array( 'code' => 'multisource', 'info' => "Cannot use 'revids' at the same time as 'dataSource'" ),
+                       array( 'code' => 'badgenerator', 'info' => 'Module $generatorName cannot be used as a generator' ),
                ) );
        }
 }
index 42c490e..6978a75 100644 (file)
@@ -42,42 +42,13 @@ class ApiParamInfo extends ApiBase {
        public function execute() {
                // Get parameters
                $params = $this->extractRequestParams();
-               $result = $this->getResult();
+               $resultObj = $this->getResult();
 
                $res = array();
-               if ( is_array( $params['modules'] ) ) {
-                       $modules = $this->getMain()->getModules();
-                       $res['modules'] = array();
-                       foreach ( $params['modules'] as $mod ) {
-                               if ( !isset( $modules[$mod] ) ) {
-                                       $res['modules'][] = array( 'name' => $mod, 'missing' => '' );
-                                       continue;
-                               }
-                               $obj = new $modules[$mod]( $this->getMain(), $mod );
 
-                               $item = $this->getClassInfo( $obj );
-                               $item['name'] = $mod;
-                               $res['modules'][] = $item;
-                       }
-                       $result->setIndexedTagName( $res['modules'], 'module' );
-               }
+               $this->addModulesInfo( $params, 'modules', $res, $resultObj );
 
-               if ( is_array( $params['querymodules'] ) ) {
-                       $queryModules = $this->queryObj->getModules();
-                       $res['querymodules'] = array();
-                       foreach ( $params['querymodules'] as $qm ) {
-                               if ( !isset( $queryModules[$qm] ) ) {
-                                       $res['querymodules'][] = array( 'name' => $qm, 'missing' => '' );
-                                       continue;
-                               }
-                               $obj = new $queryModules[$qm]( $this, $qm );
-                               $item = $this->getClassInfo( $obj );
-                               $item['name'] = $qm;
-                               $item['querytype'] = $this->queryObj->getModuleType( $qm );
-                               $res['querymodules'][] = $item;
-                       }
-                       $result->setIndexedTagName( $res['querymodules'], 'module' );
-               }
+               $this->addModulesInfo( $params, 'querymodules', $res, $resultObj );
 
                if ( $params['mainmodule'] ) {
                        $res['mainmodule'] = $this->getClassInfo( $this->getMain() );
@@ -88,29 +59,50 @@ class ApiParamInfo extends ApiBase {
                        $res['pagesetmodule'] = $this->getClassInfo( $pageSet );
                }
 
-               if ( is_array( $params['formatmodules'] ) ) {
-                       $formats = $this->getMain()->getFormats();
-                       $res['formatmodules'] = array();
-                       foreach ( $params['formatmodules'] as $f ) {
-                               if ( !isset( $formats[$f] ) ) {
-                                       $res['formatmodules'][] = array( 'name' => $f, 'missing' => '' );
-                                       continue;
-                               }
-                               $obj = new $formats[$f]( $this, $f );
-                               $item = $this->getClassInfo( $obj );
-                               $item['name'] = $f;
-                               $res['formatmodules'][] = $item;
+               $this->addModulesInfo( $params, 'formatmodules', $res, $resultObj );
+
+               $resultObj->addValue( null, $this->getModuleName(), $res );
+       }
+
+       /**
+        * If the type is requested in parameters, adds a section to res with module info.
+        * @param array $params user parameters array
+        * @param string $type parameter name
+        * @param array $res store results in this array
+        * @param array $resultObj results object to set indexed tag.
+        */
+       private function addModulesInfo( $params, $type, &$res, $resultObj ) {
+               if ( !is_array( $params[$type] ) ) {
+                       return;
+               }
+               $isQuery = ( $type === 'querymodules' );
+               if ( $isQuery ) {
+                       $mgr = $this->queryObj->getModuleManager();
+               } else {
+                       $mgr = $this->getMain()->getModuleManager();
+               }
+               $res[$type] = array();
+               foreach ( $params[$type] as $mod ) {
+                       if ( !$mgr->isDefined( $mod ) ) {
+                               $res[$type][] = array( 'name' => $mod, 'missing' => '' );
+                               continue;
+                       }
+                       $obj = $mgr->getModule( $mod );
+                       $item = $this->getClassInfo( $obj );
+                       $item['name'] = $mod;
+                       if ( $isQuery ) {
+                               $item['querytype'] = $mgr->getModuleGroup( $mod );
                        }
-                       $result->setIndexedTagName( $res['formatmodules'], 'module' );
+                       $res[$type][] = $item;
                }
-               $result->addValue( null, $this->getModuleName(), $res );
+               $resultObj->setIndexedTagName( $res[$type], 'module' );
        }
 
        /**
         * @param $obj ApiBase
         * @return ApiResult
         */
-       function getClassInfo( $obj ) {
+       private function getClassInfo( $obj ) {
                $result = $this->getResult();
                $retval['classname'] = get_class( $obj );
                $retval['description'] = implode( "\n", (array)$obj->getFinalDescription() );
@@ -133,7 +125,7 @@ class ApiParamInfo extends ApiBase {
                        $retval['generator'] = '';
                }
 
-               $allowedParams = $obj->getFinalParams();
+               $allowedParams = $obj->getFinalParams( ApiBase::GET_VALUES_FOR_HELP );
                if ( !is_array( $allowedParams ) ) {
                        return $retval;
                }
@@ -150,7 +142,7 @@ class ApiParamInfo extends ApiBase {
                        if ( is_string( $examples ) ) {
                                $examples = array( $examples );
                        }
-                       foreach( $examples as $k => $v ) {
+                       foreach ( $examples as $k => $v ) {
                                if ( strlen( $retval['examples'] ) ) {
                                        $retval['examples'] .= ' ';
                                }
@@ -181,7 +173,7 @@ class ApiParamInfo extends ApiBase {
                        }
 
                        //handle shorthand
-                       if( !is_array( $p ) ) {
+                       if ( !is_array( $p ) ) {
                                $p = array(
                                        ApiBase::PARAM_DFLT => $p,
                                );
@@ -208,11 +200,11 @@ class ApiParamInfo extends ApiBase {
 
                        if ( isset( $p[ApiBase::PARAM_DFLT] ) ) {
                                $type = $p[ApiBase::PARAM_TYPE];
-                               if( $type === 'boolean' ) {
+                               if ( $type === 'boolean' ) {
                                        $a['default'] = ( $p[ApiBase::PARAM_DFLT] ? 'true' : 'false' );
-                               } elseif( $type === 'string' ) {
+                               } elseif ( $type === 'string' ) {
                                        $a['default'] = strval( $p[ApiBase::PARAM_DFLT] );
-                               } elseif( $type === 'integer' ) {
+                               } elseif ( $type === 'integer' ) {
                                        $a['default'] = intval( $p[ApiBase::PARAM_DFLT] );
                                } else {
                                        $a['default'] = $p[ApiBase::PARAM_DFLT];
@@ -319,11 +311,11 @@ class ApiParamInfo extends ApiBase {
        }
 
        public function getAllowedParams() {
-               $modules = array_keys( $this->getMain()->getModules() );
+               $modules = $this->getMain()->getModuleManager()->getNames( 'action' );
                sort( $modules );
-               $querymodules = array_keys( $this->queryObj->getModules() );
+               $querymodules = $this->queryObj->getModuleManager()->getNames();
                sort( $querymodules );
-               $formatmodules = array_keys( $this->getMain()->getFormats() );
+               $formatmodules = $this->getMain()->getModuleManager()->getNames( 'format' );
                sort( $formatmodules );
                return array(
                        'modules' => array(
index e86c91c..b81e5c7 100644 (file)
@@ -36,10 +36,6 @@ class ApiParse extends ApiBase {
        /** @var Content $pstContent */
        private $pstContent = null;
 
-       public function __construct( $main, $action ) {
-               parent::__construct( $main, $action );
-       }
-
        public function execute() {
                // The data is hot but user-dependent, like page views, so we set vary cookies
                $this->getMain()->setCacheMode( 'anon-public-user-private' );
@@ -105,7 +101,7 @@ class ApiParse extends ApiBase {
                                if ( $rev->isCurrent() ) {
                                        // May get from/save to parser cache
                                        $p_result = $this->getParsedContent( $pageObj, $popts,
-                                               $pageid, isset( $prop['wikitext'] ) ) ;
+                                               $pageid, isset( $prop['wikitext'] ) );
                                } else { // This is an old revision, so get the text differently
                                        $this->content = $rev->getContent( Revision::FOR_THIS_USER, $this->getUser() );
 
@@ -161,7 +157,7 @@ class ApiParse extends ApiBase {
 
                                // Potentially cached
                                $p_result = $this->getParsedContent( $pageObj, $popts, $pageid,
-                                       isset( $prop['wikitext'] ) ) ;
+                                       isset( $prop['wikitext'] ) );
                        }
                } else { // Not $oldid, $pageid, $page. Hence based on $text
                        $titleObj = Title::newFromText( $title );
index 336068f..4d4fbba 100644 (file)
  */
 class ApiPatrol extends ApiBase {
 
-       public function __construct( $main, $action ) {
-               parent::__construct( $main, $action );
-       }
-
        /**
         * Patrols the article or provides the reason the patrol failed.
         */
index fa6da52..95fdbce 100644 (file)
  */
 class ApiProtect extends ApiBase {
 
-       public function __construct( $main, $action ) {
-               parent::__construct( $main, $action );
-       }
-
        public function execute() {
                global $wgRestrictionLevels;
                $params = $this->extractRequestParams();
index e1ba759..bd92077 100644 (file)
  */
 class ApiPurge extends ApiBase {
 
-       public function __construct( $main, $action ) {
-               parent::__construct( $main, $action );
+       private $mPageSet;
+
+       /**
+        * Add all items from $values into the result
+        * @param $result array output
+        * @param $values array values to add
+        * @param $flag string the name of the boolean flag to mark this element
+        * @param $name string if given, name of the value
+        */
+       private static function addValues( array &$result, $values, $flag = null, $name = null ) {
+               foreach ( $values as $val ) {
+                       if( $val instanceof Title ) {
+                               $v = array();
+                               ApiQueryBase::addTitleInfo( $v, $val );
+                       } elseif( $name !== null ) {
+                               $v = array( $name => $val );
+                       } else {
+                               $v = $val;
+                       }
+                       if( $flag !== null ) {
+                               $v[$flag] = '';
+                       }
+                       $result[] = $v;
+               }
        }
 
        /**
         * Purges the cache of a page
         */
        public function execute() {
-               $user = $this->getUser();
                $params = $this->extractRequestParams();
-               if ( !$user->isAllowed( 'purge' ) && !$this->getMain()->isInternalMode() &&
-                               !$this->getRequest()->wasPosted() ) {
-                       $this->dieUsageMsg( array( 'mustbeposted', $this->getModuleName() ) );
-               }
 
                $forceLinkUpdate = $params['forcelinkupdate'];
-               $pageSet = new ApiPageSet( $this );
+               $pageSet = $this->getPageSet();
                $pageSet->execute();
 
                $result = array();
-               foreach( $pageSet->getInvalidTitles() as $title ) {
+               self::addValues( $result, $pageSet->getInvalidTitles(), 'invalid', 'title' );
+               self::addValues( $result, $pageSet->getSpecialTitles(), 'special', 'title' );
+               self::addValues( $result, $pageSet->getMissingPageIDs(), 'missing', 'pageid' );
+               self::addValues( $result, $pageSet->getMissingRevisionIDs(), 'missing', 'revid' );
+               self::addValues( $result, $pageSet->getMissingTitles(), 'missing' );
+               self::addValues( $result, $pageSet->getInterwikiTitlesAsResult() );
+
+               foreach ( $pageSet->getGoodTitles() as $title ) {
                        $r = array();
-                       $r['title'] = $title;
-                       $r['invalid'] = '';
-                       $result[] = $r;
-               }
-               foreach( $pageSet->getMissingPageIDs() as $p ) {
-                       $page = array();
-                       $page['pageid'] = $p;
-                       $page['missing'] = '';
-                       $result[] = $page;
-               }
-               foreach( $pageSet->getMissingRevisionIDs() as $r ) {
-                       $rev = array();
-                       $rev['revid'] = $r;
-                       $rev['missing'] = '';
-                       $result[] = $rev;
-               }
-
-               foreach ( $pageSet->getTitles() as $title ) {
-                       $r = array();
-
                        ApiQueryBase::addTitleInfo( $r, $title );
-                       if ( !$title->exists() ) {
-                               $r['missing'] = '';
-                               $result[] = $r;
-                               continue;
-                       }
-
                        $page = WikiPage::factory( $title );
                        $page->doPurge(); // Directly purge and skip the UI part of purge().
                        $r['purged'] = '';
 
-                       if( $forceLinkUpdate ) {
-                               if ( !$user->pingLimiter() ) {
+                       if ( $forceLinkUpdate ) {
+                               if ( !$this->getUser()->pingLimiter() ) {
                                        global $wgEnableParserCache;
 
                                        $popts = $page->makeParserOptions( 'canonical' );
@@ -116,24 +114,52 @@ class ApiPurge extends ApiBase {
                $apiResult = $this->getResult();
                $apiResult->setIndexedTagName( $result, 'page' );
                $apiResult->addValue( null, $this->getModuleName(), $result );
+
+               $values = $pageSet->getNormalizedTitlesAsResult( $apiResult );
+               if ( $values ) {
+                       $apiResult->addValue( null, 'normalized', $values );
+               }
+               $values = $pageSet->getConvertedTitlesAsResult( $apiResult );
+               if ( $values ) {
+                       $apiResult->addValue( null, 'converted', $values );
+               }
+               $values = $pageSet->getRedirectTitlesAsResult( $apiResult );
+               if ( $values ) {
+                       $apiResult->addValue( null, 'redirects', $values );
+               }
+       }
+
+       /**
+        * Get a cached instance of an ApiPageSet object
+        * @return ApiPageSet
+        */
+       private function getPageSet() {
+               if ( !isset( $this->mPageSet ) ) {
+                       $this->mPageSet = new ApiPageSet( $this );
+               }
+               return $this->mPageSet;
        }
 
        public function isWriteMode() {
                return true;
        }
 
-       public function getAllowedParams() {
-               $psModule = new ApiPageSet( $this );
-               return $psModule->getAllowedParams() + array(
-                       'forcelinkupdate' => false,
-               );
+       public function mustBePosted() {
+               // Anonymous users are not allowed a non-POST request
+               return !$this->getUser()->isAllowed( 'purge' );
+       }
+
+       public function getAllowedParams( $flags = 0 ) {
+               $result = array( 'forcelinkupdate' => false );
+               if ( $flags ) {
+                       $result += $this->getPageSet()->getFinalParams( $flags );
+               }
+               return $result;
        }
 
        public function getParamDescription() {
-               $psModule = new ApiPageSet( $this );
-               return $psModule->getParamDescription() + array(
-                       'forcelinkupdate' => 'Update the links tables',
-               );
+               return $this->getPageSet()->getParamDescription()
+                       + array( 'forcelinkupdate' => 'Update the links tables' );
        }
 
        public function getResultProperties() {
@@ -157,9 +183,14 @@ class ApiPurge extends ApiBase {
                                        ApiBase::PROP_NULLABLE => true
                                ),
                                'invalid' => 'boolean',
+                               'special' => 'boolean',
                                'missing' => 'boolean',
                                'purged' => 'boolean',
-                               'linkupdate' => 'boolean'
+                               'linkupdate' => 'boolean',
+                               'iw' => array(
+                                       ApiBase::PROP_TYPE => 'string',
+                                       ApiBase::PROP_NULLABLE => true
+                               ),
                        )
                );
        }
@@ -171,10 +202,9 @@ class ApiPurge extends ApiBase {
        }
 
        public function getPossibleErrors() {
-               $psModule = new ApiPageSet( $this );
                return array_merge(
                        parent::getPossibleErrors(),
-                       $psModule->getPossibleErrors()
+                       $this->getPageSet()->getPossibleErrors()
                );
        }
 
index e5e6ca4..619d1ca 100644 (file)
  */
 class ApiQuery extends ApiBase {
 
-       private $mPropModuleNames, $mListModuleNames, $mMetaModuleNames;
-
-       /**
-        * @var ApiPageSet
-        */
-       private $mPageSet;
-
-       private $params, $redirects, $convertTitles, $iwUrl;
-
        /**
         * List of Api Query prop modules
         * @var array
         */
-       private $mQueryPropModules = array(
+       private static $QueryPropModules = array(
                'categories' => 'ApiQueryCategories',
                'categoryinfo' => 'ApiQueryCategoryInfo',
                'duplicatefiles' => 'ApiQueryDuplicateFiles',
@@ -71,7 +62,7 @@ class ApiQuery extends ApiBase {
         * List of Api Query list modules
         * @var array
         */
-       private $mQueryListModules = array(
+       private static $QueryListModules = array(
                'allcategories' => 'ApiQueryAllCategories',
                'allimages' => 'ApiQueryAllImages',
                'alllinks' => 'ApiQueryAllLinks',
@@ -105,7 +96,7 @@ class ApiQuery extends ApiBase {
         * List of Api Query meta modules
         * @var array
         */
-       private $mQueryMetaModules = array(
+       private static $QueryMetaModules = array(
                'allmessages' => 'ApiQueryAllMessages',
                'siteinfo' => 'ApiQuerySiteinfo',
                'userinfo' => 'ApiQueryUserInfo',
@@ -144,10 +135,15 @@ class ApiQuery extends ApiBase {
                'watchlistraw' => 'ApiQueryWatchlistRaw',
        );
 
-       private $mSlaveDB = null;
-       private $mNamedDB = array();
+       /**
+        * @var ApiPageSet
+        */
+       private $mPageSet;
 
-       protected $mAllowedGenerators;
+       private $params;
+       private $iwUrl;
+       private $mNamedDB = array();
+       private $mModuleMgr;
 
        /**
         * @param $main ApiMain
@@ -156,43 +152,34 @@ class ApiQuery extends ApiBase {
        public function __construct( $main, $action ) {
                parent::__construct( $main, $action );
 
-               // Allow custom modules to be added in LocalSettings.php
-               global $wgAPIPropModules, $wgAPIListModules, $wgAPIMetaModules, $wgAPIGeneratorModules;
-               self::appendUserModules( $this->mQueryPropModules, $wgAPIPropModules );
-               self::appendUserModules( $this->mQueryListModules, $wgAPIListModules );
-               self::appendUserModules( $this->mQueryMetaModules, $wgAPIMetaModules );
-               self::appendUserModules( $this->mQueryGenerators, $wgAPIGeneratorModules );
-
-               $this->mPropModuleNames = array_keys( $this->mQueryPropModules );
-               $this->mListModuleNames = array_keys( $this->mQueryListModules );
-               $this->mMetaModuleNames = array_keys( $this->mQueryMetaModules );
-               $this->mAllowedGenerators = array_keys( $this->mQueryGenerators );
-       }
+               $this->mModuleMgr = new ApiModuleManager( $this );
 
-       /**
-        * Helper function to append any add-in modules to the list
-        * @param $modules array Module array
-        * @param $newModules array Module array to add to $modules
-        */
-       private static function appendUserModules( &$modules, $newModules ) {
-               if ( is_array( $newModules ) ) {
-                       foreach ( $newModules as $moduleName => $moduleClass ) {
-                               $modules[$moduleName] = $moduleClass;
+               // Allow custom modules to be added in LocalSettings.php
+               global $wgAPIPropModules, $wgAPIListModules, $wgAPIMetaModules;
+               $this->mModuleMgr->addModules( self::$QueryPropModules, 'prop' );
+               $this->mModuleMgr->addModules( $wgAPIPropModules, 'prop' );
+               $this->mModuleMgr->addModules( self::$QueryListModules, 'list' );
+               $this->mModuleMgr->addModules( $wgAPIListModules, 'list' );
+               $this->mModuleMgr->addModules( self::$QueryMetaModules, 'meta' );
+               $this->mModuleMgr->addModules( $wgAPIMetaModules, 'meta' );
+
+               global $wgAPIGeneratorModules;
+               if ( is_array( $wgAPIGeneratorModules ) ) {
+                       foreach ( $wgAPIGeneratorModules as $moduleName => $moduleClass ) {
+                               $this->mQueryGenerators[$moduleName] = $moduleClass;
                        }
                }
+
+               // Create PageSet that will process titles/pageids/revids/generator
+               $this->mPageSet = new ApiPageSet( $this );
        }
 
        /**
-        * Gets a default slave database connection object
-        * @return DatabaseBase
+        * Overrides to return this instance's module manager.
+        * @return ApiModuleManager
         */
-       public function getDB() {
-               if ( !isset( $this->mSlaveDB ) ) {
-                       $this->profileDBIn();
-                       $this->mSlaveDB = wfGetDB( DB_SLAVE, 'api' );
-                       $this->profileDBOut();
-               }
-               return $this->mSlaveDB;
+       public function getModuleManager() {
+               return $this->mModuleMgr;
        }
 
        /**
@@ -224,10 +211,12 @@ class ApiQuery extends ApiBase {
 
        /**
         * Get the array mapping module names to class names
+        * @deprecated since 1.21, use getModuleManager()'s methods instead
         * @return array array(modulename => classname)
         */
        public function getModules() {
-               return array_merge( $this->mQueryPropModules, $this->mQueryListModules, $this->mQueryMetaModules );
+               wfDeprecated( __METHOD__, '1.21' );
+               return $this->getModuleManager()->getNamesWithClasses();
        }
 
        /**
@@ -240,23 +229,12 @@ class ApiQuery extends ApiBase {
 
        /**
         * Get whether the specified module is a prop, list or a meta query module
+        * @deprecated since 1.21, use getModuleManager()->getModuleGroup()
         * @param $moduleName string Name of the module to find type for
         * @return mixed string or null
         */
        function getModuleType( $moduleName ) {
-               if ( isset( $this->mQueryPropModules[$moduleName] ) ) {
-                       return 'prop';
-               }
-
-               if ( isset( $this->mQueryListModules[$moduleName] ) ) {
-                       return 'list';
-               }
-
-               if ( isset( $this->mQueryMetaModules[$moduleName] ) ) {
-                       return 'meta';
-               }
-
-               return null;
+               return $this->getModuleManager()->getModuleGroup( $moduleName );
        }
 
        /**
@@ -286,34 +264,25 @@ class ApiQuery extends ApiBase {
         */
        public function execute() {
                $this->params = $this->extractRequestParams();
-               $this->redirects = $this->params['redirects'];
-               $this->convertTitles = $this->params['converttitles'];
                $this->iwUrl = $this->params['iwurl'];
 
-               // Create PageSet
-               $this->mPageSet = new ApiPageSet( $this, $this->redirects, $this->convertTitles );
-
                // Instantiate requested modules
                $modules = array();
-               $this->instantiateModules( $modules, 'prop', $this->mQueryPropModules );
-               $this->instantiateModules( $modules, 'list', $this->mQueryListModules );
-               $this->instantiateModules( $modules, 'meta', $this->mQueryMetaModules );
-
-               $cacheMode = 'public';
-
-               // If given, execute generator to substitute user supplied data with generated data.
-               if ( isset( $this->params['generator'] ) ) {
-                       $generator = $this->newGenerator( $this->params['generator'] );
-                       $params = $generator->extractRequestParams();
-                       $cacheMode = $this->mergeCacheMode( $cacheMode,
-                               $generator->getCacheMode( $params ) );
-                       $this->executeGeneratorModule( $generator, $modules );
-               } else {
-                       // Append custom fields and populate page/revision information
-                       $this->addCustomFldsToPageSet( $modules, $this->mPageSet );
-                       $this->mPageSet->execute();
+               $this->instantiateModules( $modules, 'prop' );
+               $this->instantiateModules( $modules, 'list' );
+               $this->instantiateModules( $modules, 'meta' );
+
+               // Query modules may optimize data requests through the $this->getPageSet()
+               // object by adding extra fields from the page table.
+               // This function will gather all the extra request fields from the modules.
+               foreach ( $modules as $module ) {
+                       $module->requestExtraData( $this->mPageSet );
                }
 
+               // Populate page/revision information
+               $this->mPageSet->execute();
+               $cacheMode = $this->mPageSet->getCacheMode();
+
                // Record page information (title, namespace, if exists, etc)
                $this->outputGeneralPageInfo();
 
@@ -357,33 +326,15 @@ class ApiQuery extends ApiBase {
                return $cacheMode;
        }
 
-       /**
-        * Query modules may optimize data requests through the $this->getPageSet() object
-        * by adding extra fields from the page table.
-        * This function will gather all the extra request fields from the modules.
-        * @param $modules array of module objects
-        * @param $pageSet ApiPageSet
-        */
-       private function addCustomFldsToPageSet( $modules, $pageSet ) {
-               // Query all requested modules.
-               /**
-                * @var $module ApiQueryBase
-                */
-               foreach ( $modules as $module ) {
-                       $module->requestExtraData( $pageSet );
-               }
-       }
-
        /**
         * Create instances of all modules requested by the client
         * @param $modules Array to append instantiated modules to
         * @param $param string Parameter name to read modules from
-        * @param $moduleList Array array(modulename => classname)
         */
-       private function instantiateModules( &$modules, $param, $moduleList ) {
+       private function instantiateModules( &$modules, $param ) {
                if ( isset( $this->params[$param] ) ) {
                        foreach ( $this->params[$param] as $moduleName ) {
-                               $modules[] = new $moduleList[$moduleName] ( $this, $moduleName );
+                               $modules[] = $this->mModuleMgr->getModule( $moduleName );
                        }
                }
        }
@@ -401,85 +352,25 @@ class ApiQuery extends ApiBase {
                // more than 380K. The maximum revision size is in the megabyte range,
                // and the maximum result size must be even higher than that.
 
-               // Title normalizations
-               $normValues = array();
-               foreach ( $pageSet->getNormalizedTitles() as $rawTitleStr => $titleStr ) {
-                       $normValues[] = array(
-                               'from' => $rawTitleStr,
-                               'to' => $titleStr
-                       );
+               $values = $pageSet->getNormalizedTitlesAsResult( $result );
+               if ( $values ) {
+                       $result->addValue( 'query', 'normalized', $values );
                }
-
-               if ( count( $normValues ) ) {
-                       $result->setIndexedTagName( $normValues, 'n' );
-                       $result->addValue( 'query', 'normalized', $normValues );
+               $values = $pageSet->getConvertedTitlesAsResult( $result );
+               if ( $values ) {
+                       $result->addValue( 'query', 'converted', $values );
                }
-
-               // Title conversions
-               $convValues = array();
-               foreach ( $pageSet->getConvertedTitles() as $rawTitleStr => $titleStr ) {
-                       $convValues[] = array(
-                               'from' => $rawTitleStr,
-                               'to' => $titleStr
-                       );
+               $values = $pageSet->getInterwikiTitlesAsResult( $result, $this->iwUrl );
+               if ( $values ) {
+                       $result->addValue( 'query', 'interwiki', $values );
                }
-
-               if ( count( $convValues ) ) {
-                       $result->setIndexedTagName( $convValues, 'c' );
-                       $result->addValue( 'query', 'converted', $convValues );
-               }
-
-               // Interwiki titles
-               $intrwValues = array();
-               foreach ( $pageSet->getInterwikiTitles() as $rawTitleStr => $interwikiStr ) {
-                       $item = array(
-                               'title' => $rawTitleStr,
-                               'iw' => $interwikiStr,
-                       );
-                       if ( $this->iwUrl ) {
-                               $title = Title::newFromText( $rawTitleStr );
-                               $item['url'] = wfExpandUrl( $title->getFullURL(), PROTO_CURRENT );
-                       }
-                       $intrwValues[] = $item;
-               }
-
-               if ( count( $intrwValues ) ) {
-                       $result->setIndexedTagName( $intrwValues, 'i' );
-                       $result->addValue( 'query', 'interwiki', $intrwValues );
-               }
-
-               // Show redirect information
-               $redirValues = array();
-               /**
-                * @var $titleTo Title
-                */
-               foreach ( $pageSet->getRedirectTitles() as $titleStrFrom => $titleTo ) {
-                       $r = array(
-                               'from' => strval( $titleStrFrom ),
-                               'to' => $titleTo->getPrefixedText(),
-                       );
-                       if ( $titleTo->getFragment() !== '' ) {
-                               $r['tofragment'] = $titleTo->getFragment();
-                       }
-                       $redirValues[] = $r;
-               }
-
-               if ( count( $redirValues ) ) {
-                       $result->setIndexedTagName( $redirValues, 'r' );
-                       $result->addValue( 'query', 'redirects', $redirValues );
+               $values = $pageSet->getRedirectTitlesAsResult( $result );
+               if ( $values ) {
+                       $result->addValue( 'query', 'redirects', $values );
                }
-
-               // Missing revision elements
-               $missingRevIDs = $pageSet->getMissingRevisionIDs();
-               if ( count( $missingRevIDs ) ) {
-                       $revids = array();
-                       foreach ( $missingRevIDs as $revid ) {
-                               $revids[$revid] = array(
-                                       'revid' => $revid
-                               );
-                       }
-                       $result->setIndexedTagName( $revids, 'rev' );
-                       $result->addValue( 'query', 'badrevids', $revids );
+               $values = $pageSet->getMissingRevisionIDsAsResult( $result );
+               if ( $values ) {
+                       $result->addValue( 'query', 'badrevids', $values );
                }
 
                // Page elements
@@ -544,8 +435,8 @@ class ApiQuery extends ApiBase {
        }
 
        /**
-        * @param  $pageSet ApiPageSet Pages to be exported
-        * @param  $result ApiResult Result to output to
+        * @param $pageSet ApiPageSet Pages to be exported
+        * @param $result ApiResult Result to output to
         */
        private function doExport( $pageSet, $result ) {
                $exportTitles = array();
@@ -588,80 +479,29 @@ class ApiQuery extends ApiBase {
                $result->enableSizeCheck();
        }
 
-       /**
-        * Create a generator object of the given type and return it
-        * @param $generatorName string Module name
-        * @return ApiQueryGeneratorBase
-        */
-       public function newGenerator( $generatorName ) {
-               // Find class that implements requested generator
-               if ( isset( $this->mQueryListModules[$generatorName] ) ) {
-                       $className = $this->mQueryListModules[$generatorName];
-               } elseif ( isset( $this->mQueryPropModules[$generatorName] ) ) {
-                       $className = $this->mQueryPropModules[$generatorName];
-               } else {
-                       ApiBase::dieDebug( __METHOD__, "Unknown generator=$generatorName" );
-               }
-               $generator = new $className ( $this, $generatorName );
-               if ( !$generator instanceof ApiQueryGeneratorBase ) {
-                       $this->dieUsage( "Module $generatorName cannot be used as a generator", 'badgenerator' );
-               }
-               $generator->setGeneratorMode();
-               return $generator;
-       }
-
-       /**
-        * For generator mode, execute generator, and use its output as new
-        * ApiPageSet
-        * @param $generator ApiQueryGeneratorBase Generator Module
-        * @param $modules array of module objects
-        */
-       protected function executeGeneratorModule( $generator, $modules ) {
-               // Generator results
-               $resultPageSet = new ApiPageSet( $this, $this->redirects, $this->convertTitles );
-
-               // Add any additional fields modules may need
-               $generator->requestExtraData( $this->mPageSet );
-               $this->addCustomFldsToPageSet( $modules, $resultPageSet );
-
-               // Populate page information with the original user input
-               $this->mPageSet->execute();
-
-               // populate resultPageSet with the generator output
-               $generator->profileIn();
-               $generator->executeGenerator( $resultPageSet );
-               wfRunHooks( 'APIQueryGeneratorAfterExecute', array( &$generator, &$resultPageSet ) );
-               $resultPageSet->finishPageSetGeneration();
-               $generator->profileOut();
-
-               // Swap the resulting pageset back in
-               $this->mPageSet = $resultPageSet;
-       }
-
-       public function getAllowedParams() {
-               return array(
+       public function getAllowedParams( $flags = 0 ) {
+               $result = array(
                        'prop' => array(
                                ApiBase::PARAM_ISMULTI => true,
-                               ApiBase::PARAM_TYPE => $this->mPropModuleNames
+                               ApiBase::PARAM_TYPE => $this->mModuleMgr->getNames( 'prop' )
                        ),
                        'list' => array(
                                ApiBase::PARAM_ISMULTI => true,
-                               ApiBase::PARAM_TYPE => $this->mListModuleNames
+                               ApiBase::PARAM_TYPE => $this->mModuleMgr->getNames( 'list' )
                        ),
                        'meta' => array(
                                ApiBase::PARAM_ISMULTI => true,
-                               ApiBase::PARAM_TYPE => $this->mMetaModuleNames
-                       ),
-                       'generator' => array(
-                               ApiBase::PARAM_TYPE => $this->mAllowedGenerators
+                               ApiBase::PARAM_TYPE => $this->mModuleMgr->getNames( 'meta' )
                        ),
-                       'redirects' => false,
-                       'converttitles' => false,
                        'indexpageids' => false,
                        'export' => false,
                        'exportnowrap' => false,
                        'iwurl' => false,
                );
+               if( $flags ) {
+                       $result += $this->getPageSet()->getFinalParams( $flags );
+               }
+               return $result;
        }
 
        /**
@@ -669,42 +509,40 @@ class ApiQuery extends ApiBase {
         * @return string
         */
        public function makeHelpMsg() {
-               // Make sure the internal object is empty
-               // (just in case a sub-module decides to optimize during instantiation)
-               $this->mPageSet = null;
+
+               // Use parent to make default message for the query module
+               $msg = parent::makeHelpMsg();
 
                $querySeparator = str_repeat( '--- ', 12 );
                $moduleSeparator = str_repeat( '*** ', 14 );
-               $msg = "\n$querySeparator Query: Prop  $querySeparator\n\n";
-               $msg .= $this->makeHelpMsgHelper( $this->mQueryPropModules, 'prop' );
+               $msg .= "\n$querySeparator Query: Prop  $querySeparator\n\n";
+               $msg .= $this->makeHelpMsgHelper( 'prop' );
                $msg .= "\n$querySeparator Query: List  $querySeparator\n\n";
-               $msg .= $this->makeHelpMsgHelper( $this->mQueryListModules, 'list' );
+               $msg .= $this->makeHelpMsgHelper( 'list' );
                $msg .= "\n$querySeparator Query: Meta  $querySeparator\n\n";
-               $msg .= $this->makeHelpMsgHelper( $this->mQueryMetaModules, 'meta' );
+               $msg .= $this->makeHelpMsgHelper( 'meta' );
                $msg .= "\n\n$moduleSeparator Modules: continuation  $moduleSeparator\n\n";
 
-               // Use parent to make default message for the query module
-               $msg = parent::makeHelpMsg() . $msg;
-
                return $msg;
        }
 
        /**
-        * For all modules in $moduleList, generate help messages and join them together
-        * @param $moduleList Array array(modulename => classname)
-        * @param $paramName string Parameter name
+        * For all modules of a given group, generate help messages and join them together
+        * @param $group string Module group
         * @return string
         */
-       private function makeHelpMsgHelper( $moduleList, $paramName ) {
+       private function makeHelpMsgHelper( $group ) {
                $moduleDescriptions = array();
 
-               foreach ( $moduleList as $moduleName => $moduleClass ) {
+               $moduleNames = $this->mModuleMgr->getNames( $group );
+               sort( $moduleNames );
+               foreach ( $moduleNames as $name ) {
                        /**
                         * @var $module ApiQueryBase
                         */
-                       $module = new $moduleClass( $this, $moduleName, null );
+                       $module = $this->mModuleMgr->getModule( $name );
 
-                       $msg = ApiMain::makeHelpMsgHeader( $module, $paramName );
+                       $msg = ApiMain::makeHelpMsgHeader( $module, $group );
                        $msg2 = $module->makeHelpMsg();
                        if ( $msg2 !== false ) {
                                $msg .= $msg2;
@@ -718,29 +556,15 @@ class ApiQuery extends ApiBase {
                return implode( "\n", $moduleDescriptions );
        }
 
-       /**
-        * Override to add extra parameters from PageSet
-        * @return string
-        */
-       public function makeHelpMsgParameters() {
-               $psModule = new ApiPageSet( $this );
-               return $psModule->makeHelpMsgParameters() . parent::makeHelpMsgParameters();
-       }
-
        public function shouldCheckMaxlag() {
                return true;
        }
 
        public function getParamDescription() {
-               return array(
+               return $this->getPageSet()->getParamDescription() + array(
                        'prop' => 'Which properties to get for the titles/revisions/pageids. Module help is available below',
                        'list' => 'Which lists to get. Module help is available below',
                        'meta' => 'Which metadata to get about the site. Module help is available below',
-                       'generator' => array( 'Use the output of a list as the input for other prop/list/meta items',
-                                       'NOTE: generator parameter names must be prefixed with a \'g\', see examples' ),
-                       'redirects' => 'Automatically resolve redirects',
-                       'converttitles' => array( "Convert titles to other variants if necessary. Only works if the wiki's content language supports variant conversion.",
-                                       'Languages that support variant conversion include ' . implode( ', ', LanguageConverter::$languagesWithVariants ) ),
                        'indexpageids' => 'Include an additional pageids section listing all returned page IDs',
                        'export' => 'Export the current revisions of all given or generated pages',
                        'exportnowrap' => 'Return the export XML without wrapping it in an XML result (same format as Special:Export). Can only be used with export',
@@ -757,9 +581,10 @@ class ApiQuery extends ApiBase {
        }
 
        public function getPossibleErrors() {
-               return array_merge( parent::getPossibleErrors(), array(
-                       array( 'code' => 'badgenerator', 'info' => 'Module $generatorName cannot be used as a generator' ),
-               ) );
+               return array_merge(
+                       parent::getPossibleErrors(),
+                       $this->getPageSet()->getPossibleErrors()
+               );
        }
 
        public function getExamples() {
index bbc5272..adf2037 100644 (file)
@@ -41,7 +41,7 @@ class ApiQueryAllImages extends ApiQueryGeneratorBase {
        }
 
        /**
-        * Override parent method to make sure to make sure the repo's DB is used
+        * Override parent method to make sure the repo's DB is used
         * which may not necesarilly be the same as the local DB.
         *
         * TODO: allow querying non-local repos.
@@ -94,7 +94,7 @@ class ApiQueryAllImages extends ApiQueryGeneratorBase {
                $this->addFields( LocalFile::selectFields() );
 
                $ascendingOrder = true;
-               if ( $params['dir'] == 'descending' || $params['dir'] == 'older') {
+               if ( $params['dir'] == 'descending' || $params['dir'] == 'older' ) {
                        $ascendingOrder = false;
                }
 
index fcc3dba..6b6b1a3 100644 (file)
@@ -116,7 +116,7 @@ class ApiQueryAllMessages extends ApiQueryBase {
                        $lang = $langObj->getCode();
 
                        $customisedMessages = AllmessagesTablePager::getCustomisedStatuses(
-                               array_map( array( $langObj, 'ucfirst'), $messages_target ), $lang, $lang != $wgContLang->getCode() );
+                               array_map( array( $langObj, 'ucfirst' ), $messages_target ), $lang, $lang != $wgContLang->getCode() );
 
                        $customised = $params['customised'] === 'modified';
                }
index 2a8645f..59e6652 100644 (file)
@@ -351,7 +351,7 @@ abstract class ApiQueryBase extends ApiBase {
                }
                $result = $this->getResult();
                $fit = $result->addValue( array( 'query', 'pages', $pageId,
-                                        $this->getModuleName() ), null, $item );
+                       $this->getModuleName() ), null, $item );
                if ( !$fit ) {
                        return false;
                }
@@ -393,8 +393,7 @@ abstract class ApiQueryBase extends ApiBase {
         */
        protected function getDB() {
                if ( is_null( $this->mDb ) ) {
-                       $apiQuery = $this->getQuery();
-                       $this->mDb = $apiQuery->getDB();
+                       $this->mDb = $this->getQuery()->getDB();
                }
                return $this->mDb;
        }
@@ -585,24 +584,32 @@ abstract class ApiQueryBase extends ApiBase {
  */
 abstract class ApiQueryGeneratorBase extends ApiQueryBase {
 
-       private $mIsGenerator;
+       private $mGeneratorPageSet = null;
 
        /**
-        * @param $query ApiBase
-        * @param $moduleName string
-        * @param $paramPrefix string
+        * Switch this module to generator mode. By default, generator mode is
+        * switched off and the module acts like a normal query module.
+        * @since 1.21 requires pageset parameter
+        * @param $generatorPageSet ApiPageSet object that the module will get
+        *        by calling getPageSet() when in generator mode.
         */
-       public function __construct( $query, $moduleName, $paramPrefix = '' ) {
-               parent::__construct( $query, $moduleName, $paramPrefix );
-               $this->mIsGenerator = false;
+       public function setGeneratorMode( ApiPageSet $generatorPageSet ) {
+               if ( $generatorPageSet === null ) {
+                       ApiBase::dieDebug( __METHOD__, 'Required parameter missing - $generatorPageSet' );
+               }
+               $this->mGeneratorPageSet = $generatorPageSet;
        }
 
        /**
-        * Switch this module to generator mode. By default, generator mode is
-        * switched off and the module acts like a normal query module.
+        * Get the PageSet object to work on.
+        * If this module is generator, the pageSet object is different from other module's
+        * @return ApiPageSet
         */
-       public function setGeneratorMode() {
-               $this->mIsGenerator = true;
+       protected function getPageSet() {
+               if ( $this->mGeneratorPageSet !== null ) {
+                       return $this->mGeneratorPageSet;
+               }
+               return parent::getPageSet();
        }
 
        /**
@@ -611,7 +618,7 @@ abstract class ApiQueryGeneratorBase extends ApiQueryBase {
         * @return string Prefixed parameter name
         */
        public function encodeParamName( $paramName ) {
-               if ( $this->mIsGenerator ) {
+               if ( $this->mGeneratorPageSet !== null ) {
                        return 'g' . parent::encodeParamName( $paramName );
                } else {
                        return parent::encodeParamName( $paramName );
index 0d2fa0d..d9be9f2 100644 (file)
@@ -132,10 +132,10 @@ class ApiQueryBlocks extends ApiQueryBase {
                        $this->addWhereIf( 'ipb_user != 0', isset( $show['account'] ) );
                        $this->addWhereIf( 'ipb_user != 0 OR ipb_range_end > ipb_range_start', isset( $show['!ip'] ) );
                        $this->addWhereIf( 'ipb_user = 0 AND ipb_range_end = ipb_range_start', isset( $show['ip'] ) );
-                       $this->addWhereIf( 'ipb_expiry =  '.$db->addQuotes($db->getInfinity()), isset( $show['!temp'] ) );
-                       $this->addWhereIf( 'ipb_expiry != '.$db->addQuotes($db->getInfinity()), isset( $show['temp'] ) );
-                       $this->addWhereIf( "ipb_range_end = ipb_range_start", isset( $show['!range'] ) );
-                       $this->addWhereIf( "ipb_range_end > ipb_range_start", isset( $show['range'] ) );
+                       $this->addWhereIf( 'ipb_expiry = ' . $db->addQuotes( $db->getInfinity() ), isset( $show['!temp'] ) );
+                       $this->addWhereIf( 'ipb_expiry != ' . $db->addQuotes( $db->getInfinity() ), isset( $show['temp'] ) );
+                       $this->addWhereIf( 'ipb_range_end = ipb_range_start', isset( $show['!range'] ) );
+                       $this->addWhereIf( 'ipb_range_end > ipb_range_start', isset( $show['range'] ) );
                }
 
                if ( !$this->getUser()->isAllowed( 'hideuser' ) ) {
index 6a392bd..fd9d4c5 100644 (file)
@@ -243,7 +243,7 @@ class ApiQueryCategoryMembers extends ApiQueryGeneratorBase {
 
                if ( is_null( $resultPageSet ) ) {
                        $result->setIndexedTagName_internal(
-                                        array( 'query', $this->getModuleName() ), 'cm' );
+                               array( 'query', $this->getModuleName() ), 'cm' );
                }
        }
 
index 27d95ee..31812cf 100644 (file)
@@ -76,13 +76,13 @@ class ApiQueryDeletedrevs extends ApiQueryBase {
                        // Ignore namespace and unique due to inability to know whether they were purposely set
                        foreach( array( 'from', 'to', 'prefix', /*'namespace',*/ 'continue', /*'unique'*/ ) as $p ) {
                                if ( !is_null( $params[$p] ) ) {
-                                       $this->dieUsage( "The '{$p}' parameter cannot be used in modes 1 or 2", 'badparams');
+                                       $this->dieUsage( "The '{$p}' parameter cannot be used in modes 1 or 2", 'badparams' );
                                }
                        }
                } else {
                        foreach( array( 'start', 'end' ) as $p ) {
                                if ( !is_null( $params[$p] ) ) {
-                                       $this->dieUsage( "The {$p} parameter cannot be used in mode 3", 'badparams');
+                                       $this->dieUsage( "The {$p} parameter cannot be used in mode 3", 'badparams' );
                                }
                        }
                }
index c0929a0..cf0d841 100644 (file)
  */
 class ApiQueryDisabled extends ApiQueryBase {
 
-       public function __construct( $main, $action ) {
-               parent::__construct( $main, $action );
-       }
-
        public function execute() {
                $this->setWarning( "The \"{$this->getModuleName()}\" module has been disabled." );
        }
index b368af8..351753c 100644 (file)
@@ -52,9 +52,8 @@ class ApiQueryImageInfo extends ApiQueryBase {
                        $titles = array_keys( $pageIds[NS_FILE] );
                        asort( $titles ); // Ensure the order is always the same
 
-                       $skip = false;
+                       $fromTitle = null;
                        if ( !is_null( $params['continue'] ) ) {
-                               $skip = true;
                                $cont = explode( '|', $params['continue'] );
                                $this->dieContinueUsageIf( count( $cont ) != 2 );
                                $fromTitle = strval( $cont[0] );
@@ -77,12 +76,18 @@ class ApiQueryImageInfo extends ApiQueryBase {
                                $images = RepoGroup::singleton()->findFiles( $titles );
                        }
                        foreach ( $titles as $title ) {
+                               $pageId = $pageIds[NS_FILE][$title];
+                               $start = $title === $fromTitle ? $fromTimestamp : $params['start'];
+
                                if ( !isset( $images[$title] ) ) {
+                                       $result->addValue(
+                                               array( 'query', 'pages', intval( $pageId ) ),
+                                               'imagerepository', ''
+                                       );
+                                       // The above can't fail because it doesn't increase the result size
                                        continue;
                                }
 
-                               $start = $skip ? $fromTimestamp : $params['start'];
-                               $pageId = $pageIds[NS_FILE][$title];
                                $img = $images[$title];
 
                                $fit = $result->addValue(
@@ -97,10 +102,11 @@ class ApiQueryImageInfo extends ApiQueryBase {
                                                // thing again. When the violating queries have been
                                                // out-continued, the result will get through
                                                $this->setContinueEnumParameter( 'start',
-                                                       wfTimestamp( TS_ISO_8601, $img->getTimestamp() ) );
+                                                       $start !== null ? $start : wfTimestamp( TS_ISO_8601, $img->getTimestamp() )
+                                               );
                                        } else {
                                                $this->setContinueEnumParameter( 'continue',
-                                                       $this->getContinueStr( $img ) );
+                                                       $this->getContinueStr( $img, $start ) );
                                        }
                                        break;
                                }
@@ -164,18 +170,6 @@ class ApiQueryImageInfo extends ApiQueryBase {
                                if ( !$fit ) {
                                        break;
                                }
-                               $skip = false;
-                       }
-
-                       $data = $this->getResultData();
-                       foreach ( $data['query']['pages'] as $pageid => $arr ) {
-                               if ( is_array( $arr ) && !isset( $arr['imagerepository'] ) ) {
-                                       $result->addValue(
-                                               array( 'query', 'pages', $pageid ),
-                                               'imagerepository', ''
-                                       );
-                               }
-                               // The above can't fail because it doesn't increase the result size
                        }
                }
        }
@@ -433,9 +427,11 @@ class ApiQueryImageInfo extends ApiQueryBase {
         * @param $img File
         * @return string
         */
-       protected function getContinueStr( $img ) {
-               return $img->getOriginalTitle()->getText() .
-                       '|' .  $img->getTimestamp();
+       protected function getContinueStr( $img, $start = null ) {
+               if ( $start === null ) {
+                       $start = $img->getTimestamp();
+               }
+               return $img->getOriginalTitle()->getText() . '|' . $start;
        }
 
        public function getAllowedParams() {
@@ -539,7 +535,7 @@ class ApiQueryImageInfo extends ApiQueryBase {
                return array(
                        'prop' => self::getPropertyDescriptions( array(), $p ),
                        'urlwidth' => array( "If {$p}prop=url is set, a URL to an image scaled to this width will be returned.",
-                                           'Only the current version of the image can be scaled' ),
+                                               'Only the current version of the image can be scaled' ),
                        'urlheight' => "Similar to {$p}urlwidth. Cannot be used without {$p}urlwidth",
                        'urlparam' => array( "A handler specific parameter string. For example, pdf's ",
                                "might use 'page15-100px'. {$p}urlwidth must be used and be consistent with {$p}urlparam" ),
index 94b6ad8..7797205 100644 (file)
@@ -96,7 +96,7 @@ class ApiQueryInfo extends ApiQueryBase {
                        'unblock' => array( 'ApiQueryInfo', 'getUnblockToken' ),
                        'email' => array( 'ApiQueryInfo', 'getEmailToken' ),
                        'import' => array( 'ApiQueryInfo', 'getImportToken' ),
-                       'watch' => array( 'ApiQueryInfo', 'getWatchToken'),
+                       'watch' => array( 'ApiQueryInfo', 'getWatchToken' ),
                );
                wfRunHooks( 'APIQueryInfoTokens', array( &$this->tokenFunctions ) );
                return $this->tokenFunctions;
index 138d79b..69d81ae 100644 (file)
@@ -238,9 +238,9 @@ class ApiQueryLinks extends ApiQueryGeneratorBase {
                $desc = $this->description;
                $name = $this->getModuleName();
                return array(
-                       "api.php?action=query&prop={$name}&titles=Main%20Page" => "Get {$desc}s from the [[Main Page]]:",
-                       "api.php?action=query&generator={$name}&titles=Main%20Page&prop=info" => "Get information about the {$desc} pages in the [[Main Page]]:",
-                       "api.php?action=query&prop={$name}&titles=Main%20Page&{$this->prefix}namespace=2|10" => "Get {$desc}s from the Main Page in the User and Template namespaces:",
+                       "api.php?action=query&prop={$name}&titles=Main%20Page" => "Get {$desc}s from the [[Main Page]]",
+                       "api.php?action=query&generator={$name}&titles=Main%20Page&prop=info" => "Get information about the {$desc} pages in the [[Main Page]]",
+                       "api.php?action=query&prop={$name}&titles=Main%20Page&{$this->prefix}namespace=2|10" => "Get {$desc}s from the Main Page in the User and Template namespaces",
                );
        }
 
index 189e15a..9dd2c6a 100644 (file)
@@ -49,7 +49,7 @@ class ApiQueryPageProps extends ApiQueryBase {
 
                $this->addTables( 'page_props' );
                $this->addFields( array( 'pp_page', 'pp_propname', 'pp_value' ) );
-               $this->addWhereFld( 'pp_page',  array_keys( $pages ) );
+               $this->addWhereFld( 'pp_page', array_keys( $pages ) );
 
                if ( $this->params['continue'] ) {
                        $this->addWhere( 'pp_page >=' . intval( $this->params['continue'] ) );
index 182bc2c..1c9deb7 100644 (file)
@@ -211,7 +211,7 @@ class ApiQueryQueryPage extends ApiQueryGeneratorBase {
 
        public function getPossibleErrors() {
                return array_merge( parent::getPossibleErrors(), array(
-                        array( 'specialpage-cantexecute' )
+                       array( 'specialpage-cantexecute' )
                ) );
        }
 
index f7a22bd..6acca67 100644 (file)
@@ -234,7 +234,7 @@ class ApiQueryRecentChanges extends ApiQueryGeneratorBase {
                        $this->addFieldsIf( 'rc_comment', $this->fld_comment || $this->fld_parsedcomment );
                        $this->addFieldsIf( 'rc_user', $this->fld_user );
                        $this->addFieldsIf( 'rc_user_text', $this->fld_user || $this->fld_userid );
-                       $this->addFieldsIf( array( 'rc_minor', 'rc_type', 'rc_bot' ) , $this->fld_flags );
+                       $this->addFieldsIf( array( 'rc_minor', 'rc_type', 'rc_bot' ), $this->fld_flags );
                        $this->addFieldsIf( array( 'rc_old_len', 'rc_new_len' ), $this->fld_sizes );
                        $this->addFieldsIf( 'rc_patrolled', $this->fld_patrolled );
                        $this->addFieldsIf( array( 'rc_logid', 'rc_log_type', 'rc_log_action', 'rc_params' ), $this->fld_loginfo );
@@ -260,7 +260,7 @@ class ApiQueryRecentChanges extends ApiQueryGeneratorBase {
                if ( !is_null( $params['tag'] ) ) {
                        $this->addTables( 'change_tag' );
                        $this->addJoinConds( array( 'change_tag' => array( 'INNER JOIN', array( 'rc_id=ct_rc_id' ) ) ) );
-                       $this->addWhereFld( 'ct_tag' , $params['tag'] );
+                       $this->addWhereFld( 'ct_tag', $params['tag'] );
                        global $wgOldChangeTagsIndex;
                        $index['change_tag'] = $wgOldChangeTagsIndex ? 'ct_tag' : 'change_tag_tag_id';
                }
index 27ea6be..9b54ee5 100644 (file)
@@ -189,7 +189,7 @@ class ApiQueryRevisions extends ApiQueryBase {
                if ( !is_null( $params['tag'] ) ) {
                        $this->addTables( 'change_tag' );
                        $this->addJoinConds( array( 'change_tag' => array( 'INNER JOIN', array( 'rev_id=ct_rev_id' ) ) ) );
-                       $this->addWhereFld( 'ct_tag' , $params['tag'] );
+                       $this->addWhereFld( 'ct_tag', $params['tag'] );
                        global $wgOldChangeTagsIndex;
                        $index['change_tag'] = $wgOldChangeTagsIndex ? 'ct_tag' : 'change_tag_tag_id';
                }
index 2fef68a..3ed0113 100644 (file)
@@ -120,7 +120,7 @@ class ApiQuerySiteinfo extends ApiQueryBase {
                $data['sitename'] = $GLOBALS['wgSitename'];
                $data['generator'] = "MediaWiki {$GLOBALS['wgVersion']}";
                $data['phpversion'] = phpversion();
-               $data['phpsapi'] = php_sapi_name();
+               $data['phpsapi'] = PHP_SAPI;
                $data['dbtype'] = $GLOBALS['wgDBtype'];
                $data['dbversion'] = $this->getDB()->getServerVersion();
 
@@ -462,7 +462,7 @@ class ApiQuerySiteinfo extends ApiQueryBase {
                                }
                                if ( isset( $ext['author'] ) ) {
                                        $ret['author'] = is_array( $ext['author'] ) ?
-                                               implode( ', ', $ext['author' ] ) : $ext['author'];
+                                               implode( ', ', $ext['author'] ) : $ext['author'];
                                }
                                if ( isset( $ext['url'] ) ) {
                                        $ret['url'] = $ext['url'];
@@ -530,7 +530,7 @@ class ApiQuerySiteinfo extends ApiQueryBase {
        public function appendExtensionTags( $property ) {
                global $wgParser;
                $wgParser->firstCallInit();
-               $tags = array_map( array( $this, 'formatParserTags'), $wgParser->getTags() );
+               $tags = array_map( array( $this, 'formatParserTags' ), $wgParser->getTags() );
                $this->getResult()->setIndexedTagName( $tags, 't' );
                return $this->getResult()->addValue( 'query', $property, $tags );
        }
index 1b97317..6899375 100644 (file)
@@ -42,7 +42,7 @@ class ApiQueryStashImageInfo extends ApiQueryImageInfo {
                $result = $this->getResult();
 
                if ( !$params['filekey'] && !$params['sessionkey'] ) {
-                       $this->dieUsage( "One of filekey or sessionkey must be supplied", 'nofilekey');
+                       $this->dieUsage( "One of filekey or sessionkey must be supplied", 'nofilekey' );
                }
 
                // Alias sessionkey to filekey, but give an existing filekey precedence.
@@ -139,4 +139,3 @@ class ApiQueryStashImageInfo extends ApiQueryImageInfo {
        }
 
 }
-
index 4d1edf1..2410f05 100644 (file)
@@ -220,7 +220,7 @@ class ApiQueryContributions extends ApiQueryBase {
                ) );
 
                if ( isset( $show['patrolled'] ) || isset( $show['!patrolled'] ) ||
-                                $this->fld_patrolled ) {
+                               $this->fld_patrolled ) {
                        if ( !$user->useRCPatrol() && !$user->useNPPatrol() ) {
                                $this->dieUsage( 'You need the patrol right to request the patrolled flag', 'permissiondenied' );
                        }
index 03a0b79..50ea587 100644 (file)
@@ -161,7 +161,7 @@ class ApiQueryUsers extends ApiQueryBase {
                                }
 
                                if ( isset( $this->prop['implicitgroups'] ) ) {
-                                       $data[$name]['implicitgroups'] =  $user->getAutomaticGroups();
+                                       $data[$name]['implicitgroups'] = $user->getAutomaticGroups();
                                }
 
                                if ( isset( $this->prop['rights'] ) ) {
index 402bab1..6e55a5e 100644 (file)
  */
 class ApiRollback extends ApiBase {
 
-       public function __construct( $main, $action ) {
-               parent::__construct( $main, $action );
-       }
-
        /**
         * @var Title
         */
index 752a6be..c4a1328 100644 (file)
  */
 class ApiRsd extends ApiBase {
 
-       public function __construct( $main, $action ) {
-               parent::__construct( $main, $action );
-       }
-
        public function execute() {
                $result = $this->getResult();
 
index 68160fa..3f5ebfe 100644 (file)
@@ -31,9 +31,7 @@
  */
 class ApiSetNotificationTimestamp extends ApiBase {
 
-       public function __construct( $main, $action ) {
-               parent::__construct( $main, $action );
-       }
+       private $mPageSet;
 
        public function execute() {
                $user = $this->getUser();
@@ -45,7 +43,7 @@ class ApiSetNotificationTimestamp extends ApiBase {
                $params = $this->extractRequestParams();
                $this->requireMaxOneParameter( $params, 'timestamp', 'torevid', 'newerthanrevid' );
 
-               $pageSet = new ApiPageSet( $this );
+               $pageSet = $this->getPageSet();
                $args = array_merge( array( $params, 'entirewatchlist' ), array_keys( $pageSet->getAllowedParams() ) );
                call_user_func_array( array( $this, 'requireOnlyOneParameter' ), $args );
 
@@ -96,20 +94,20 @@ class ApiSetNotificationTimestamp extends ApiBase {
                        $result['notificationtimestamp'] = ( is_null( $timestamp ) ? '' : wfTimestamp( TS_ISO_8601, $timestamp ) );
                } else {
                        // First, log the invalid titles
-                       foreach( $pageSet->getInvalidTitles() as $title ) {
+                       foreach ( $pageSet->getInvalidTitles() as $title ) {
                                $r = array();
                                $r['title'] = $title;
                                $r['invalid'] = '';
                                $result[] = $r;
                        }
-                       foreach( $pageSet->getMissingPageIDs() as $p ) {
+                       foreach ( $pageSet->getMissingPageIDs() as $p ) {
                                $page = array();
                                $page['pageid'] = $p;
                                $page['missing'] = '';
                                $page['notwatched'] = '';
                                $result[] = $page;
                        }
-                       foreach( $pageSet->getMissingRevisionIDs() as $r ) {
+                       foreach ( $pageSet->getMissingRevisionIDs() as $r ) {
                                $rev = array();
                                $rev['revid'] = $r;
                                $rev['missing'] = '';
@@ -161,6 +159,17 @@ class ApiSetNotificationTimestamp extends ApiBase {
                $apiResult->addValue( null, $this->getModuleName(), $result );
        }
 
+       /**
+        * Get a cached instance of an ApiPageSet object
+        * @return ApiPageSet
+        */
+       private function getPageSet() {
+               if ( !isset( $this->mPageSet ) ) {
+                       $this->mPageSet = new ApiPageSet( $this );
+               }
+               return $this->mPageSet;
+       }
+
        public function mustBePosted() {
                return true;
        }
@@ -177,9 +186,8 @@ class ApiSetNotificationTimestamp extends ApiBase {
                return '';
        }
 
-       public function getAllowedParams() {
-               $psModule = new ApiPageSet( $this );
-               return $psModule->getAllowedParams() + array(
+       public function getAllowedParams( $flags = 0 ) {
+               $result = array(
                        'entirewatchlist' => array(
                                ApiBase::PARAM_TYPE => 'boolean'
                        ),
@@ -194,11 +202,15 @@ class ApiSetNotificationTimestamp extends ApiBase {
                                ApiBase::PARAM_TYPE => 'integer'
                        ),
                );
+               if ( $flags ) {
+                       $result += $this->getPageSet()->getFinalParams( $flags );
+               }
+               return $result;
+
        }
 
        public function getParamDescription() {
-               $psModule = new ApiPageSet( $this );
-               return $psModule->getParamDescription() + array(
+               return $this->getPageSet()->getParamDescription() + array(
                        'entirewatchlist' => 'Work on all watched pages',
                        'timestamp' => 'Timestamp to which to set the notification timestamp',
                        'torevid' => 'Revision to set the notification timestamp to (one page only)',
@@ -253,12 +265,14 @@ class ApiSetNotificationTimestamp extends ApiBase {
        }
 
        public function getPossibleErrors() {
-               $psModule = new ApiPageSet( $this );
+               $ps = $this->getPageSet();
                return array_merge(
                        parent::getPossibleErrors(),
-                       $psModule->getPossibleErrors(),
-                       $this->getRequireMaxOneParameterErrorMessages( array( 'timestamp', 'torevid', 'newerthanrevid' ) ),
-                       $this->getRequireOnlyOneParameterErrorMessages( array_merge( array( 'entirewatchlist' ), array_keys( $psModule->getAllowedParams() ) ) ),
+                       $ps->getPossibleErrors(),
+                       $this->getRequireMaxOneParameterErrorMessages(
+                               array( 'timestamp', 'torevid', 'newerthanrevid' ) ),
+                       $this->getRequireOnlyOneParameterErrorMessages(
+                               array_merge( array( 'entirewatchlist' ), array_keys( $ps->getFinalParams() ) ) ),
                        array(
                                array( 'code' => 'notloggedin', 'info' => 'Anonymous users cannot use watchlist change notifications' ),
                                array( 'code' => 'multpages', 'info' => 'torevid may only be used with a single page' ),
index 2be2b24..518bfce 100644 (file)
  */
 class ApiTokens extends ApiBase {
 
-       public function __construct( $main, $action ) {
-               parent::__construct( $main, $action );
-       }
-
        public function execute() {
                wfProfileIn( __METHOD__ );
                $params = $this->extractRequestParams();
index 5802a98..bc7f6e7 100644 (file)
  */
 class ApiUnblock extends ApiBase {
 
-       public function __construct( $main, $action ) {
-               parent::__construct( $main, $action );
-       }
-
        /**
         * Unblocks the specified user or provides the reason the unblock failed.
         */
index b1eeff3..f53f065 100644 (file)
  */
 class ApiUndelete extends ApiBase {
 
-       public function __construct( $main, $action ) {
-               parent::__construct( $main, $action );
-       }
-
        public function execute() {
                $params = $this->extractRequestParams();
 
index 2d45b29..a0da765 100644 (file)
@@ -36,10 +36,6 @@ class ApiUpload extends ApiBase {
 
        protected $mParams;
 
-       public function __construct( $main, $action ) {
-               parent::__construct( $main, $action );
-       }
-
        public function execute() {
                // Check whether upload is enabled
                if ( !UploadBase::isEnabled() ) {
@@ -198,7 +194,7 @@ class ApiUpload extends ApiBase {
                $request = $this->getMain()->getRequest();
                $chunkPath = $request->getFileTempname( 'chunk' );
                $chunkSize = $request->getUpload( 'chunk' )->getSize();
-               if ($this->mParams['offset'] == 0) {
+               if ( $this->mParams['offset'] == 0 ) {
                        $result['filekey'] = $this->performStash();
                } else {
                        $status = $this->mUpload->addChunk(
@@ -250,7 +246,7 @@ class ApiUpload extends ApiBase {
                                        }
 
                                        // We have a new filekey for the fully concatenated file.
-                                       $result['filekey'] =  $this->mUpload->getLocalFile()->getFileKey();
+                                       $result['filekey'] = $this->mUpload->getLocalFile()->getFileKey();
 
                                        // Remove chunk from stash. (Checks against user ownership of chunks.)
                                        $this->mUpload->stash->removeFile( $this->mParams['filekey'] );
@@ -282,7 +278,7 @@ class ApiUpload extends ApiBase {
                        $fileKey = $stashFile->getFileKey();
                } catch ( MWException $e ) {
                        $message = 'Stashing temporary file failed: ' . get_class( $e ) . ' ' . $e->getMessage();
-                       wfDebug( __METHOD__ . ' ' . $message . "\n");
+                       wfDebug( __METHOD__ . ' ' . $message . "\n" );
                        throw new MWException( $message );
                }
                return $fileKey;
@@ -523,7 +519,7 @@ class ApiUpload extends ApiBase {
                                break;
                        default:
                                $this->dieUsage( 'An unknown error occurred', 'unknown-error',
-                                               0, array( 'code' =>  $verification['status'] ) );
+                                               0, array( 'code' => $verification['status'] ) );
                                break;
                }
        }
@@ -662,7 +658,7 @@ class ApiUpload extends ApiBase {
        protected function checkAsyncDownloadEnabled() {
                global $wgAllowAsyncCopyUploads;
                if ( !$wgAllowAsyncCopyUploads ) {
-                       $this->dieUsage( 'Asynchronous copy uploads disabled', 'asynccopyuploaddisabled');
+                       $this->dieUsage( 'Asynchronous copy uploads disabled', 'asynccopyuploaddisabled' );
                }
        }
 
@@ -795,7 +791,7 @@ class ApiUpload extends ApiBase {
                        ' * Have the MediaWiki server fetch a file from a URL, using the "url" parameter',
                        ' * Complete an earlier upload that failed due to warnings, using the "filekey" parameter',
                        'Note that the HTTP POST must be done as a file upload (i.e. using multipart/form-data) when',
-                       'sending the "file".  Also you must get and send an edit token before doing any upload stuff'
+                       'sending the "file". Also you must get and send an edit token before doing any upload stuff'
                );
        }
 
index 0c6ebb1..b9b1eed 100644 (file)
  */
 class ApiUserrights extends ApiBase {
 
-       public function __construct( $main, $action ) {
-               parent::__construct( $main, $action );
-       }
-
        private $mUser = null;
 
        public function execute() {
index 16da176..2454e33 100644 (file)
  */
 class ApiWatch extends ApiBase {
 
-       public function __construct( $main, $action ) {
-               parent::__construct( $main, $action );
-       }
-
        public function execute() {
                $user = $this->getUser();
                if ( !$user->isLoggedIn() ) {
index 5cdc867..c67b655 100644 (file)
@@ -404,7 +404,7 @@ class GlobalDependency extends CacheDependency {
         * @return bool
         */
        function isExpired() {
-               if( !isset($GLOBALS[$this->name]) ) {
+               if( !isset( $GLOBALS[$this->name] ) ) {
                        return true;
                }
                return $GLOBALS[$this->name] != $this->value;
index 1a08d9f..ccdd98a 100644 (file)
@@ -163,7 +163,7 @@ abstract class FileCacheBase {
 
                $this->checkCacheDirs(); // build parent dir
                if ( !file_put_contents( $this->cachePath(), $text, LOCK_EX ) ) {
-                       wfDebug( __METHOD__ . "() failed saving ". $this->cachePath() . "\n");
+                       wfDebug( __METHOD__ . "() failed saving ". $this->cachePath() . "\n" );
                        $this->mCached = null;
                        return false;
                }
index fca071a..055fd68 100644 (file)
@@ -128,7 +128,7 @@ class HTMLFileCache extends FileCacheBase {
        public function loadFromFileCache( IContextSource $context ) {
                global $wgMimeType, $wgLanguageCode;
 
-               wfDebug( __METHOD__ . "()\n");
+               wfDebug( __METHOD__ . "()\n" );
                $filename = $this->cachePath();
 
                $context->getOutput()->sendCacheControl();
@@ -168,10 +168,10 @@ class HTMLFileCache extends FileCacheBase {
                $now = wfTimestampNow();
                if ( $this->useGzip() ) {
                        $text = str_replace(
-                               '</html>', '<!-- Cached/compressed '.$now." -->\n</html>", $text );
+                               '</html>', '<!-- Cached/compressed ' . $now . " -->\n</html>", $text );
                } else {
                        $text = str_replace(
-                               '</html>', '<!-- Cached '.$now." -->\n</html>", $text );
+                               '</html>', '<!-- Cached ' . $now . " -->\n</html>", $text );
                }
 
                // Store text to FS...
index e2cf1b4..89e5325 100644 (file)
@@ -499,7 +499,7 @@ class MessageCache {
 
                // Also delete cached sidebar... just in case it is affected
                $codes = array( $code );
-               if ( $code === 'en'  ) {
+               if ( $code === 'en' ) {
                        // Delete all sidebars, like for example on action=purge on the
                        // sidebar messages
                        $codes = array_keys( Language::fetchLanguageNames() );
@@ -545,7 +545,7 @@ class MessageCache {
                        $serialized = serialize( $cache );
                        $hash = md5( $serialized );
                        $this->mMemc->set( wfMemcKey( 'messages', $code, 'hash' ), $hash, $this->mExpiry );
-                       if ($wgLocalMessageCacheSerialized) {
+                       if ( $wgLocalMessageCacheSerialized ) {
                                $this->saveToLocal( $serialized, $hash, $code );
                        } else {
                                $this->saveToScript( $cache, $hash, $code );
index bcc8446..784e30e 100644 (file)
@@ -67,7 +67,7 @@ class SquidUpdate {
                $blurlArr = $title->getSquidURLs();
                if ( $res->numRows() <= $wgMaxSquidPurgeTitles ) {
                        foreach ( $res as $BL ) {
-                               $tobj = Title::makeTitle( $BL->page_namespace, $BL->page_title ) ;
+                               $tobj = Title::makeTitle( $BL->page_namespace, $BL->page_title );
                                $blurlArr[] = $tobj->getInternalURL();
                        }
                }
diff --git a/includes/clientpool/RedisConnectionPool.php b/includes/clientpool/RedisConnectionPool.php
new file mode 100644 (file)
index 0000000..eace85a
--- /dev/null
@@ -0,0 +1,299 @@
+<?php
+/**
+ * PhpRedis client connection pooling manager.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ * @file
+ * @defgroup Redis Redis
+ * @author Aaron Schulz
+ */
+
+/**
+ * Helper class to manage redis connections using PhpRedis.
+ *
+ * This can be used to get handle wrappers that free the handle when the wrapper
+ * leaves scope. The maximum number of free handles (connections) is configurable.
+ * This provides an easy way to cache connection handles that may also have state,
+ * such as a handle does between multi() and exec(), and without hoarding connections.
+ * The wrappers use PHP magic methods so that calling functions on them calls the
+ * function of the actual Redis object handle.
+ *
+ * @ingroup Redis
+ * @since 1.21
+ */
+class RedisConnectionPool {
+       // Settings for all connections in this pool
+       protected $connectTimeout; // string; connection timeout
+       protected $persistent; // bool; whether connections persist
+       protected $password; // string; plaintext auth password
+       protected $poolSize; // integer; maximum number of idle connections
+       protected $serializer; // integer; the serializer to use (Redis::SERIALIZER_*)
+
+       protected $idlePoolSize = 0; // integer; current idle pool size
+
+       /** @var Array (server name => ((connection info array),...) */
+       protected $connections = array();
+       /** @var Array (server name => UNIX timestamp) */
+       protected $downServers = array();
+
+       /** @var Array */
+       protected static $instances = array(); // (pool ID => RedisConnectionPool)
+
+       const SERVER_DOWN_TTL = 30; // integer; seconds to cache servers as "down"
+
+       /**
+        * $options include:
+        *   - connectTimeout : The timeout for new connections, in seconds.
+        *                      Optional, default is 1 second.
+        *   - persistent     : Set this to true to allow connections to persist across
+        *                      multiple web requests. False by default.
+        *   - poolSize       : Maximim number of idle connections. Default is 5.
+        *   - password       : The authentication password, will be sent to Redis in clear text.
+        *                      Optional, if it is unspecified, no AUTH command will be sent.
+        *   - serializer     : Set to "php" or "igbinary". Default is "php".
+        * @param array $options
+        */
+       protected function __construct( array $options ) {
+               if ( !extension_loaded( 'redis' ) ) {
+                       throw new MWException( __CLASS__. ' requires the phpredis extension: ' .
+                               'https://github.com/nicolasff/phpredis' );
+               }
+               $this->connectTimeout = isset( $options['connectTimeout'] )
+                       ? $options['connectTimeout']
+                       : 1;
+               $this->persistent = isset( $options['persistent'] )
+                       ? $options['persistent']
+                       : false;
+               $this->password = isset( $options['password'] )
+                       ? $options['password']
+                       : '';
+               $this->poolSize = isset( $options['poolSize'] )
+                       ? $options['poolSize']
+                       : 5;
+               if ( !isset( $options['serializer'] ) || $options['serializer'] === 'php' ) {
+                       $this->serializer = Redis::SERIALIZER_PHP;
+               } elseif ( $options['serializer'] === 'igbinary' ) {
+                       $this->serializer = Redis::SERIALIZER_IGBINARY;
+               } else {
+                       throw new MWException( "Invalid serializer specified." );
+               }
+       }
+
+       /**
+        * @param $options Array
+        * @return RedisConnectionPool
+        */
+       public static function singleton( array $options ) {
+               ksort( $options ); // normalize
+               $id = sha1( serialize( $options ) );
+               if ( !isset( self::$instances[$id] ) ) {
+                       self::$instances[$id] = new self( $options );
+                       wfDebug( "Creating a new " . __CLASS__ . " instance with id $id." );
+               }
+               return self::$instances[$id];
+       }
+
+       /**
+        * Get a connection to a redis server. Based on code in RedisBagOStuff.php.
+        *
+        * @param $server string A hostname/port combination or the absolute path of a UNIX socket.
+        *                       If a hostname is specified but no port, port 6379 will be used.
+        * @return RedisConnRef|bool Returns false on failure
+        * @throws MWException
+        */
+       public function getConnection( $server ) {
+               // Check the listing "dead" servers which have had a connection errors.
+               // Servers are marked dead for a limited period of time, to
+               // avoid excessive overhead from repeated connection timeouts.
+               if ( isset( $this->downServers[$server] ) ) {
+                       $now = time();
+                       if ( $now > $this->downServers[$server] ) {
+                               // Dead time expired
+                               unset( $this->downServers[$server] );
+                       } else {
+                               // Server is dead
+                               wfDebug( "server $server is marked down for another " .
+                                       ( $this->downServers[$server] - $now ) . " seconds, can't get connection" );
+                               return false;
+                       }
+               }
+
+               // Check if a connection is already free for use
+               if ( isset( $this->connections[$server] ) ) {
+                       foreach ( $this->connections[$server] as &$connection ) {
+                               if ( $connection['free'] ) {
+                                       $connection['free'] = false;
+                                       --$this->idlePoolSize;
+                                       return new RedisConnRef( $this, $server, $connection['conn'] );
+                               }
+                       }
+               }
+
+               if ( substr( $server, 0, 1 ) === '/' ) {
+                       // UNIX domain socket
+                       // These are required by the redis extension to start with a slash, but
+                       // we still need to set the port to a special value to make it work.
+                       $host = $server;
+                       $port = 0;
+               } else {
+                       // TCP connection
+                       $hostPort = IP::splitHostAndPort( $server );
+                       if ( !$hostPort ) {
+                               throw new MWException( __CLASS__.": invalid configured server \"$server\"" );
+                       }
+                       list( $host, $port ) = $hostPort;
+                       if ( $port === false ) {
+                               $port = 6379;
+                       }
+               }
+
+               $conn = new Redis();
+               try {
+                       if ( $this->persistent ) {
+                               $result = $conn->pconnect( $host, $port, $this->connectTimeout );
+                       } else {
+                               $result = $conn->connect( $host, $port, $this->connectTimeout );
+                       }
+                       if ( !$result ) {
+                               wfDebugLog( 'redis', "Could not connect to server $server" );
+                               // Mark server down for some time to avoid further timeouts
+                               $this->downServers[$server] = time() + self::SERVER_DOWN_TTL;
+                               return false;
+                       }
+                       if ( $this->password !== null ) {
+                               if ( !$conn->auth( $this->password ) ) {
+                                       wfDebugLog( 'redis', "Authentication error connecting to $server" );
+                               }
+                       }
+               } catch ( RedisException $e ) {
+                       $this->downServers[$server] = time() + self::SERVER_DOWN_TTL;
+                       wfDebugLog( 'redis', "Redis exception: " . $e->getMessage() . "\n" );
+                       return false;
+               }
+
+               if ( $conn ) {
+                       $conn->setOption( Redis::OPT_SERIALIZER, $this->serializer );
+                       $this->connections[$server][] = array( 'conn' => $conn, 'free' => false );
+                       return new RedisConnRef( $this, $server, $conn );
+               } else {
+                       return false;
+               }
+       }
+
+       /**
+        * Mark a connection to a server as free to return to the pool
+        *
+        * @param $server string
+        * @param $conn Redis
+        * @return boolean
+        */
+       public function freeConnection( $server, Redis $conn ) {
+               $found = false;
+
+               foreach ( $this->connections[$server] as &$connection ) {
+                       if ( $connection['conn'] === $conn && !$connection['free'] ) {
+                               $connection['free'] = true;
+                               ++$this->idlePoolSize;
+                               break;
+                       }
+               }
+
+               $this->closeExcessIdleConections();
+
+               return $found;
+       }
+
+       /**
+        * Close any extra idle connections if there are more than the limit
+        *
+        * @return void
+        */
+       protected function closeExcessIdleConections() {
+               if ( $this->idlePoolSize <= $this->poolSize ) {
+                       return; // nothing to do
+               }
+
+               foreach ( $this->connections as $server => &$serverConnections ) {
+                       foreach ( $serverConnections as $key => &$connection ) {
+                               if ( $connection['free'] ) {
+                                       unset( $serverConnections[$key] );
+                                       if ( --$this->idlePoolSize <= $this->poolSize ) {
+                                               return; // done
+                                       }
+                               }
+                       }
+               }
+       }
+
+       /**
+        * The redis extension throws an exception in response to various read, write
+        * and protocol errors. Sometimes it also closes the connection, sometimes
+        * not. The safest response for us is to explicitly destroy the connection
+        * object and let it be reopened during the next request.
+        *
+        * @param $server string
+        * @param $conn RedisConnRef
+        * @param $e RedisException
+        * @return void
+        */
+       public function handleException( $server, RedisConnRef $conn, RedisException $e ) {
+               wfDebugLog( 'redis',
+                       "Redis exception on server $server: " . $e->getMessage() . "\n" );
+               foreach ( $this->connections[$server] as $key => $connection ) {
+                       if ( $connection['conn'] === $conn ) {
+                               $this->idlePoolSize -= $connection['free'] ? 1 : 0;
+                               unset( $this->connections[$server][$key] );
+                               break;
+                       }
+               }
+       }
+}
+
+/**
+ * Helper class to handle automatically marking connectons as reusable (via RAII pattern)
+ *
+ * @ingroup Redis
+ * @since 1.21
+ */
+class RedisConnRef {
+       /** @var RedisConnectionPool */
+       protected $pool;
+
+       protected $server; // string
+
+       /** @var Redis */
+       protected $conn;
+
+       /**
+        * @param $pool RedisConnectionPool
+        * @param $server string
+        * @param $conn Redis
+        */
+       public function __construct( RedisConnectionPool $pool, $server, Redis $conn ) {
+               $this->pool = $pool;
+               $this->server = $server;
+               $this->conn = $conn;
+       }
+
+       public function __call( $name, $arguments ) {
+               return call_user_func_array( array( $this->conn, $name ), $arguments );
+       }
+
+       function __destruct() {
+               $this->pool->freeConnection( $this->server, $this->conn );
+       }
+}
index 926dea7..e14fb56 100644 (file)
@@ -75,7 +75,7 @@ abstract class AbstractContent implements Content {
                if ( $modelId !== $this->model_id ) {
                        throw new MWException(
                                "Bad content model: " .
-                               "expected {$this->model_id}  " .
+                               "expected {$this->model_id} " .
                                "but got $modelId."
                        );
                }
@@ -338,7 +338,7 @@ abstract class AbstractContent implements Content {
         *
         * @since 1.21
         */
-       public function replaceSection( $section, Content $with, $sectionTitle = ''  ) {
+       public function replaceSection( $section, Content $with, $sectionTitle = '' ) {
                return null;
        }
 
index 75ac5f2..31345af 100644 (file)
@@ -391,7 +391,7 @@ interface Content {
         * @param $sectionTitle String: new section's subject, only if $section is 'new'
         * @return string Complete article text, or null if error
         */
-       public function replaceSection( $section, Content $with, $sectionTitle = ''  );
+       public function replaceSection( $section, Content $with, $sectionTitle = '' );
 
        /**
         * Returns a Content object with pre-save transformations applied (or this
index 0dc7455..5e0447f 100644 (file)
@@ -1074,7 +1074,7 @@ abstract class ContentHandler {
 
                        wfRestoreWarnings();
 
-                       wfWarn( "Using obsolete hook $event via ContentHandler::runLegacyHooks()! Handlers: " . implode(', ', $handlerInfo), 2 );
+                       wfWarn( "Using obsolete hook $event via ContentHandler::runLegacyHooks()! Handlers: " . implode( ', ', $handlerInfo ), 2 );
                }
 
                // convert Content objects to text
@@ -1114,4 +1114,3 @@ abstract class ContentHandler {
                return $ok;
        }
 }
-
index 8d778f5..89aac20 100644 (file)
@@ -241,7 +241,7 @@ class WikitextContent extends TextContent {
                        case 'any':
                                return true;
                        case 'comma':
-                               return strpos( $text,  ',' ) !== false;
+                               return strpos( $text, ',' ) !== false;
                        case 'link':
                                if ( $hasLinks === null ) { # not known, find out
                                        if ( !$title ) {
index 96d27b0..09cb409 100644 (file)
@@ -278,10 +278,14 @@ class RequestContext implements IContextSource {
         */
        public function getLanguage() {
                if ( isset( $this->recursion ) ) {
-                       throw new MWException( 'Recursion detected' );
-               }
-
-               if ( $this->lang === null ) {
+                       trigger_error( "Recursion detected in " . __METHOD__, E_USER_WARNING );
+                       $e = new Exception;
+                       wfDebugLog( 'recursion-guard', "Recursion detected:\n" . $e->getTraceAsString() );
+
+                       global $wgLanguageCode;
+                       $code = ( $wgLanguageCode ) ? $wgLanguageCode : 'en';
+                       $this->lang = Language::factory( $code );
+               } elseif ( $this->lang === null ) {
                        $this->recursion = true;
 
                        global $wgLanguageCode, $wgContLang;
index 4ff7913..56717b6 100644 (file)
@@ -100,12 +100,12 @@ class CloneDatabase {
 
                        if( $this->dropCurrentTables && !in_array( $this->db->getType(), array( 'postgres', 'oracle' ) ) ) {
                                $this->db->dropTable( $tbl, __METHOD__ );
-                               wfDebug( __METHOD__." dropping {$newTableName}\n", true);
+                               wfDebug( __METHOD__ . " dropping {$newTableName}\n", true );
                                //Dropping the oldTable because the prefix was changed
                        }
 
                        # Create new table
-                       wfDebug( __METHOD__." duplicating $oldTableName to $newTableName\n", true );
+                       wfDebug( __METHOD__ . " duplicating $oldTableName to $newTableName\n", true );
                        $this->db->duplicateTableStructure( $oldTableName, $newTableName, $this->useTemporaryTables );
                }
        }
index fff1837..7e865c1 100644 (file)
@@ -112,8 +112,8 @@ interface DatabaseType {
         * The value inserted should be fetched from nextSequenceValue()
         *
         * Example:
-        * $id = $dbw->nextSequenceValue('page_page_id_seq');
-        * $dbw->insert('page',array('page_id' => $id));
+        * $id = $dbw->nextSequenceValue( 'page_page_id_seq' );
+        * $dbw->insert( 'page', array( 'page_id' => $id ) );
         * $id = $dbw->insertId();
         *
         * @return int
@@ -393,7 +393,7 @@ abstract class DatabaseBase implements DatabaseType {
                return wfSetVar( $this->mTablePrefix, $prefix );
        }
 
-       /**
+       /**
         * Set the filehandle to copy write statements to.
         *
         * @param $fh filehandle
@@ -584,7 +584,7 @@ abstract class DatabaseBase implements DatabaseType {
                global $wgDebugDBTransactions;
                $this->mFlags |= $flag;
                if ( ( $flag & DBO_TRX) & $wgDebugDBTransactions ) {
-                       wfDebug("Implicit transactions are now  disabled.\n");
+                       wfDebug( "Implicit transactions are now  disabled.\n" );
                }
        }
 
@@ -597,7 +597,7 @@ abstract class DatabaseBase implements DatabaseType {
                global $wgDebugDBTransactions;
                $this->mFlags &= ~$flag;
                if ( ( $flag & DBO_TRX ) && $wgDebugDBTransactions ) {
-                       wfDebug("Implicit transactions are now disabled.\n");
+                       wfDebug( "Implicit transactions are now disabled.\n" );
                }
        }
 
@@ -671,12 +671,12 @@ abstract class DatabaseBase implements DatabaseType {
                        if ( $wgCommandLineMode ) {
                                $this->mFlags &= ~DBO_TRX;
                                if ( $wgDebugDBTransactions ) {
-                                       wfDebug("Implicit transaction open disabled.\n");
+                                       wfDebug( "Implicit transaction open disabled.\n" );
                                }
                        } else {
                                $this->mFlags |= DBO_TRX;
                                if ( $wgDebugDBTransactions ) {
-                                       wfDebug("Implicit transaction open enabled.\n");
+                                       wfDebug( "Implicit transaction open enabled.\n" );
                                }
                        }
                }
@@ -772,7 +772,7 @@ abstract class DatabaseBase implements DatabaseType {
         * @param $errno
         * @param $errstr
         */
-       protected function connectionErrorHandler( $errno,  $errstr ) {
+       protected function connectionErrorHandler( $errno, $errstr ) {
                $this->mPHPError = $errstr;
        }
 
@@ -921,7 +921,7 @@ abstract class DatabaseBase implements DatabaseType {
                        if ( strpos( $sqlstart, "SHOW " ) !== 0 && strpos( $sqlstart, "SET " ) !== 0 ) {
                                global $wgDebugDBTransactions;
                                if ( $wgDebugDBTransactions ) {
-                                       wfDebug("Implicit transaction start.\n");
+                                       wfDebug( "Implicit transaction start.\n" );
                                }
                                $this->begin( __METHOD__ . " ($fname)" );
                                $this->mTrxAutomatic = true;
@@ -1096,7 +1096,7 @@ abstract class DatabaseBase implements DatabaseType {
                        case '\\&': return '&';
                }
 
-               list( /* $n */ , $arg ) = each( $this->preparedArgs );
+               list( /* $n */, $arg ) = each( $this->preparedArgs );
 
                switch( $matches[1] ) {
                        case '?': return $this->addQuotes( $arg );
@@ -1180,26 +1180,9 @@ abstract class DatabaseBase implements DatabaseType {
                        }
                }
 
-               if ( isset( $options['GROUP BY'] ) ) {
-                       $gb = is_array( $options['GROUP BY'] )
-                               ? implode( ',', $options['GROUP BY'] )
-                               : $options['GROUP BY'];
-                       $preLimitTail .= " GROUP BY {$gb}";
-               }
+               $preLimitTail .= $this->makeGroupByWithHaving( $options );
 
-               if ( isset( $options['HAVING'] ) ) {
-                       $having = is_array( $options['HAVING'] )
-                               ? $this->makeList( $options['HAVING'], LIST_AND )
-                               : $options['HAVING'];
-                       $preLimitTail .= " HAVING {$having}";
-               }
-
-               if ( isset( $options['ORDER BY'] ) ) {
-                       $ob = is_array( $options['ORDER BY'] )
-                               ? implode( ',', $options['ORDER BY'] )
-                               : $options['ORDER BY'];
-                       $preLimitTail .= " ORDER BY {$ob}";
-               }
+               $preLimitTail .= $this->makeOrderBy( $options );
 
                // if (isset($options['LIMIT'])) {
                //      $tailOpts .= $this->limitResult('', $options['LIMIT'],
@@ -1261,6 +1244,49 @@ abstract class DatabaseBase implements DatabaseType {
                return array( $startOpts, $useIndex, $preLimitTail, $postLimitTail );
        }
 
+       /**
+        * Returns an optional GROUP BY with an optional HAVING
+        *
+        * @param $options Array: associative array of options
+        * @return string
+        * @see DatabaseBase::select()
+        * @since 1.21
+        */
+       public function makeGroupByWithHaving( $options ) {
+               $sql = '';
+               if ( isset( $options['GROUP BY'] ) ) {
+                       $gb = is_array( $options['GROUP BY'] )
+                               ? implode( ',', $options['GROUP BY'] )
+                               : $options['GROUP BY'];
+                       $sql .= ' GROUP BY ' . $gb;
+               }
+               if ( isset( $options['HAVING'] ) ) {
+                       $having = is_array( $options['HAVING'] )
+                               ? $this->makeList( $options['HAVING'], LIST_AND )
+                               : $options['HAVING'];
+                       $sql .= ' HAVING ' . $having;
+               }
+               return $sql;
+       }
+
+       /**
+        * Returns an optional ORDER BY
+        *
+        * @param $options Array: associative array of options
+        * @return string
+        * @see DatabaseBase::select()
+        * @since 1.21
+        */
+       public function makeOrderBy( $options ) {
+               if ( isset( $options['ORDER BY'] ) ) {
+                       $ob = is_array( $options['ORDER BY'] )
+                               ? implode( ',', $options['ORDER BY'] )
+                               : $options['ORDER BY'];
+                       return ' ORDER BY ' . $ob;
+               }
+               return '';
+       }
+
        /**
         * Execute a SELECT query constructed using the various parameters provided.
         * See below for full details of the parameters.
@@ -1393,7 +1419,7 @@ abstract class DatabaseBase implements DatabaseType {
         * join, the second is an SQL fragment giving the join condition for that
         * table. For example:
         *
-        *    array( 'page' => array('LEFT JOIN','page_latest=rev_id') )
+        *    array( 'page' => array( 'LEFT JOIN', 'page_latest=rev_id' ) )
         *
         * @return ResultWrapper. If the query returned no rows, a ResultWrapper
         *   with no rows in it will be returned. If there was a query error, a
@@ -2071,7 +2097,7 @@ abstract class DatabaseBase implements DatabaseType {
         * This is handy when you need to construct SQL for joins
         *
         * Example:
-        * extract($dbr->tableNames('user','watchlist'));
+        * extract( $dbr->tableNames( 'user', 'watchlist' ) );
         * $sql = "SELECT wl_namespace,wl_title FROM $watchlist,$user
         *         WHERE wl_user=user_id AND wl_user=$nameWithQuotes";
         *
@@ -2093,7 +2119,7 @@ abstract class DatabaseBase implements DatabaseType {
         * This is handy when you need to construct SQL for joins
         *
         * Example:
-        * list( $user, $watchlist ) = $dbr->tableNamesN('user','watchlist');
+        * list( $user, $watchlist ) = $dbr->tableNamesN( 'user', 'watchlist' );
         * $sql = "SELECT wl_namespace,wl_title FROM $watchlist,$user
         *         WHERE wl_user=user_id AND wl_user=$nameWithQuotes";
         *
@@ -2645,7 +2671,7 @@ abstract class DatabaseBase implements DatabaseType {
                list( $startOpts, $useIndex, $tailOpts ) = $this->makeSelectOptions( $selectOptions );
 
                if ( is_array( $srcTable ) ) {
-                       $srcTable =  implode( ',', array_map( array( &$this, 'tableName' ), $srcTable ) );
+                       $srcTable = implode( ',', array_map( array( &$this, 'tableName' ), $srcTable ) );
                } else {
                        $srcTable = $this->tableName( $srcTable );
                }
@@ -3440,7 +3466,7 @@ abstract class DatabaseBase implements DatabaseType {
                        // replace `{$var}`
                        $ins = str_replace( '`{$' . $var . '}`', $this->addIdentifierQuotes( $value ), $ins );
                        // replace /*$var*/
-                       $ins = str_replace( '/*$' . $var . '*/', $this->strencode( $value ) , $ins );
+                       $ins = str_replace( '/*$' . $var . '*/', $this->strencode( $value ), $ins );
                }
                return $ins;
        }
index b6d0d00..18b2733 100644 (file)
@@ -289,10 +289,10 @@ class DBQueryError extends DBError {
         * @param $fname string
         */
        function __construct( DatabaseBase &$db, $error, $errno, $sql, $fname ) {
-               $message = "A database error has occurred.  Did you forget to run maintenance/update.php after upgrading?  See: https://www.mediawiki.org/wiki/Manual:Upgrading#Run_the_update_script\n" .
-                 "Query: $sql\n" .
-                 "Function: $fname\n" .
-                 "Error: $errno $error\n";
+               $message = "A database error has occurred. Did you forget to run maintenance/update.php after upgrading?  See: https://www.mediawiki.org/wiki/Manual:Upgrading#Run_the_update_script\n" .
+                       "Query: $sql\n" .
+                       "Function: $fname\n" .
+                       "Error: $errno $error\n";
                parent::__construct( $db, $message );
 
                $this->error = $error;
index f2b4b09..57fc7b9 100644 (file)
@@ -787,8 +787,8 @@ class DatabaseIbm_db2 extends DatabaseBase {
                // Wide characters are evil -- some of them look like '
                $s = utf8_encode( $s );
                // Fix its stupidity
-               $from = array(  "\\\\", "\\'",  '\\n',  '\\t',  '\\"',  '\\r' );
-               $to = array(            "\\",           "''",           "\n",           "\t",           '"',            "\r" );
+               $from = array( "\\\\", "\\'", '\\n', '\\t', '\\"', '\\r' );
+               $to = array( "\\", "''", "\n", "\t", '"', "\r" );
                $s = str_replace( $from, $to, $s ); // DB2 expects '', not \' escaping
                return $s;
        }
@@ -1115,10 +1115,10 @@ class DatabaseIbm_db2 extends DatabaseBase {
 
                // find out the primary keys
                $keyres = $this->doQuery( "SELECT NAME FROM SYSIBM.SYSCOLUMNS WHERE TBNAME = '"
-                 . strtoupper( $table )
-                 . "' AND TBCREATOR = '"
-                 . strtoupper( $schema )
-                 . "' AND KEYSEQ > 0" );
+                       . strtoupper( $table )
+                       . "' AND TBCREATOR = '"
+                       . strtoupper( $schema )
+                       . "' AND KEYSEQ > 0" );
 
                $keys = array();
                for (
@@ -1379,15 +1379,9 @@ class DatabaseIbm_db2 extends DatabaseBase {
                        }
                }
 
-               if ( isset( $options['GROUP BY'] ) ) {
-                       $preLimitTail .= " GROUP BY {$options['GROUP BY']}";
-               }
-               if ( isset( $options['HAVING'] ) ) {
-                       $preLimitTail .= " HAVING {$options['HAVING']}";
-               }
-               if ( isset( $options['ORDER BY'] ) ) {
-                       $preLimitTail .= " ORDER BY {$options['ORDER BY']}";
-               }
+               $preLimitTail .= $this->makeGroupByWithHaving( $options );
+
+               $preLimitTail .= $this->makeOrderBy( $options );
 
                if ( isset( $noKeyOptions['DISTINCT'] )
                        || isset( $noKeyOptions['DISTINCTROW'] ) )
index 7def1b2..1c920cb 100644 (file)
@@ -28,9 +28,9 @@
  * @ingroup Database
  */
 class DatabaseMssql extends DatabaseBase {
-       var $mInsertId = NULL;
-       var $mLastResult = NULL;
-       var $mAffectedRows = NULL;
+       var $mInsertId = null;
+       var $mLastResult = null;
+       var $mAffectedRows = null;
 
        var $mPort;
 
@@ -144,7 +144,7 @@ class DatabaseMssql extends DatabaseBase {
                // $this->limitResult();
                if ( preg_match( '/\bLIMIT\s*/i', $sql ) ) {
                        // massage LIMIT -> TopN
-                       $sql = $this->LimitToTopN( $sql ) ;
+                       $sql = $this->LimitToTopN( $sql );
                }
 
                // MSSQL doesn't have EXTRACT(epoch FROM XXX)
@@ -156,7 +156,7 @@ class DatabaseMssql extends DatabaseBase {
                // perform query
                $stmt = sqlsrv_query( $this->mConn, $sql );
                if ( $stmt == false ) {
-                       $message = "A database error has occurred.  Did you forget to run maintenance/update.php after upgrading?  See: http://www.mediawiki.org/wiki/Manual:Upgrading#Run_the_update_script\n" .
+                       $message = "A database error has occurred. Did you forget to run maintenance/update.php after upgrading?  See: http://www.mediawiki.org/wiki/Manual:Upgrading#Run_the_update_script\n" .
                                "Query: " . htmlentities( $sql ) . "\n" .
                                "Function: " . __METHOD__ . "\n";
                        // process each error (our driver will give us an array of errors unlike other providers)
@@ -319,7 +319,7 @@ class DatabaseMssql extends DatabaseBase {
                if ( isset( $options['EXPLAIN'] ) ) {
                        unset( $options['EXPLAIN'] );
                }
-               return parent::selectSQLText(  $table, $vars, $conds, $fname, $options, $join_conds );
+               return parent::selectSQLText( $table, $vars, $conds, $fname, $options, $join_conds );
        }
 
        /**
@@ -353,7 +353,7 @@ class DatabaseMssql extends DatabaseBase {
                $sql = "sp_helpindex '" . $table . "'";
                $res = $this->query( $sql, $fname );
                if ( !$res ) {
-                       return NULL;
+                       return null;
                }
 
                $result = array();
@@ -433,7 +433,7 @@ class DatabaseMssql extends DatabaseBase {
                                        if ( $k == $identity ) {
                                                if( !is_null($v) ) {
                                                        // there is a value being passed to us, we need to turn on and off inserted identity
-                                                       $sqlPre = "SET IDENTITY_INSERT $table ON;" ;
+                                                       $sqlPre = "SET IDENTITY_INSERT $table ON;";
                                                        $sqlPost = ";SET IDENTITY_INSERT $table OFF;";
 
                                                } else {
@@ -484,7 +484,7 @@ class DatabaseMssql extends DatabaseBase {
                                } elseif ( is_array( $value ) || is_object( $value ) ) {
                                        if ( is_object( $value ) && strtolower( get_class( $value ) ) == 'blob' ) {
                                                $sql .= $this->addQuotes( $value );
-                                       }  else {
+                                       } else {
                                                $sql .= $this->addQuotes( serialize( $value ) );
                                        }
                                } else {
@@ -498,7 +498,7 @@ class DatabaseMssql extends DatabaseBase {
 
                        if ( $ret === false ) {
                                throw new DBQueryError( $this, $this->getErrors(), $this->lastErrno(), $sql, $fname );
-                       } elseif ( $ret != NULL ) {
+                       } elseif ( $ret != null ) {
                                // remember number of rows affected
                                $this->mAffectedRows = sqlsrv_rows_affected( $ret );
                                if ( !is_null($identity) ) {
@@ -536,12 +536,12 @@ class DatabaseMssql extends DatabaseBase {
 
                if ( $ret === false ) {
                        throw new DBQueryError( $this, $this->getErrors(), $this->lastErrno(), /*$sql*/ '', $fname );
-               } elseif ( $ret != NULL ) {
+               } elseif ( $ret != null ) {
                        // remember number of rows affected
                        $this->mAffectedRows = sqlsrv_rows_affected( $ret );
                        return $ret;
                }
-               return NULL;
+               return null;
        }
 
        /**
@@ -608,9 +608,9 @@ class DatabaseMssql extends DatabaseBase {
                } else {
                        $sql = '
                                SELECT * FROM (
-                                 SELECT sub2.*, ROW_NUMBER() OVER(ORDER BY sub2.line2) AS line3 FROM (
-                                       SELECT 1 AS line2, sub1.* FROM (' . $sql . ') AS sub1
-                                 ) as sub2
+                                       SELECT sub2.*, ROW_NUMBER() OVER(ORDER BY sub2.line2) AS line3 FROM (
+                                               SELECT 1 AS line2, sub1.* FROM (' . $sql . ') AS sub1
+                                       ) as sub2
                                ) AS sub3
                                WHERE line3 BETWEEN ' . ( $offset + 1 ) . ' AND ' . ( $offset + $limit );
                        return $sql;
@@ -770,17 +770,17 @@ class DatabaseMssql extends DatabaseBase {
                $newUser = $this->escapeIdentifier( $newUser );
                $loginPassword = $this->addQuotes( $loginPassword );
 
-               $this->doQuery("CREATE DATABASE $dbName;");
-               $this->doQuery("USE $dbName;");
-               $this->doQuery("CREATE SCHEMA $dbName;");
-               $this->doQuery("
+               $this->doQuery( "CREATE DATABASE $dbName;" );
+               $this->doQuery( "USE $dbName;" );
+               $this->doQuery( "CREATE SCHEMA $dbName;" );
+               $this->doQuery( "
                                                CREATE
                                                        LOGIN $newUser
                                                WITH
                                                        PASSWORD=$loginPassword
                                                ;
-                                       ");
-               $this->doQuery("
+                                       " );
+               $this->doQuery( "
                                                CREATE
                                                        USER $newUser
                                                FOR
@@ -788,8 +788,8 @@ class DatabaseMssql extends DatabaseBase {
                                                WITH
                                                        DEFAULT_SCHEMA=$dbName
                                                ;
-                                       ");
-               $this->doQuery("
+                                       " );
+               $this->doQuery( "
                                                GRANT
                                                        BACKUP DATABASE,
                                                        BACKUP LOG,
@@ -804,15 +804,15 @@ class DatabaseMssql extends DatabaseBase {
                                                        DATABASE::$dbName
                                                TO $newUser
                                                ;
-                                       ");
-               $this->doQuery("
+                                       " );
+               $this->doQuery( "
                                                GRANT
                                                        CONTROL
                                                ON
                                                        SCHEMA::$dbName
                                                TO $newUser
                                                ;
-                                       ");
+                                       " );
 
 
        }
@@ -908,22 +908,16 @@ class DatabaseMssql extends DatabaseBase {
                        }
                }
 
-               if ( isset( $options['GROUP BY'] ) ) {
-                       $tailOpts .= " GROUP BY {$options['GROUP BY']}";
-               }
-               if ( isset( $options['HAVING'] ) ) {
-                       $tailOpts .= " HAVING {$options['GROUP BY']}";
-               }
-               if ( isset( $options['ORDER BY'] ) ) {
-                       $tailOpts .= " ORDER BY {$options['ORDER BY']}";
-               }
+               $tailOpts .= $this->makeGroupByWithHaving( $options );
+
+               $tailOpts .= $this->makeOrderBy( $options );
 
                if ( isset( $noKeyOptions['DISTINCT'] ) && isset( $noKeyOptions['DISTINCTROW'] ) ) {
                        $startOpts .= 'DISTINCT';
                }
 
                // we want this to be compatible with the output of parent::makeSelectOptions()
-               return array( $startOpts, '' , $tailOpts, '' );
+               return array( $startOpts, '', $tailOpts, '' );
        }
 
        /**
@@ -1138,6 +1132,5 @@ class MssqlResult {
 
        public function free() {
                unset( $this->mRows );
-               return;
        }
 }
index 04c22f1..c5100b5 100644 (file)
@@ -361,7 +361,7 @@ class DatabaseMysql extends DatabaseBase {
         * @param $options string|array
         * @return int
         */
-       public function estimateRowCount( $table, $vars='*', $conds='', $fname = 'DatabaseMysql::estimateRowCount', $options = array() ) {
+       public function estimateRowCount( $table, $vars = '*', $conds = '', $fname = 'DatabaseMysql::estimateRowCount', $options = array() ) {
                $options['EXPLAIN'] = true;
                $res = $this->select( $table, $vars, $conds, $fname, $options );
                if ( $res === false ) {
@@ -393,7 +393,7 @@ class DatabaseMysql extends DatabaseBase {
                for( $i = 0; $i < $n; $i++ ) {
                        $meta = mysql_fetch_field( $res->result, $i );
                        if( $field == $meta->name ) {
-                               return new MySQLField($meta);
+                               return new MySQLField( $meta );
                        }
                }
                return false;
@@ -449,7 +449,7 @@ class DatabaseMysql extends DatabaseBase {
        function strencode( $s ) {
                $sQuoted = mysql_real_escape_string( $s, $this->mConn );
 
-               if($sQuoted === false) {
+               if( $sQuoted === false ) {
                        $this->ping();
                        $sQuoted = mysql_real_escape_string( $s, $this->mConn );
                }
@@ -685,7 +685,7 @@ class DatabaseMysql extends DatabaseBase {
 
        public function streamStatementEnd( &$sql, &$newLine ) {
                if ( strtoupper( substr( $newLine, 0, 9 ) ) == 'DELIMITER' ) {
-                       preg_match( '/^DELIMITER\s+(\S+)/' , $newLine, $m );
+                       preg_match( '/^DELIMITER\s+(\S+)/', $newLine, $m );
                        $this->delimiter = $m[1];
                        $newLine = '';
                }
@@ -721,7 +721,7 @@ class DatabaseMysql extends DatabaseBase {
                if( $row->lockstatus == 1 ) {
                        return true;
                } else {
-                       wfDebug( __METHOD__." failed to acquire lock\n" );
+                       wfDebug( __METHOD__ . " failed to acquire lock\n" );
                        return false;
                }
        }
@@ -899,7 +899,7 @@ class DatabaseMysql extends DatabaseBase {
                $endArray = array();
 
                foreach( $result as $table ) {
-                       $vars = get_object_vars($table);
+                       $vars = get_object_vars( $table );
                        $table = array_pop( $vars );
 
                        if( !$prefix || strpos( $table, $prefix ) === 0 ) {
index 7e3c0ca..626d841 100644 (file)
@@ -23,7 +23,7 @@
 
 /**
  * The oci8 extension is fairly weak and doesn't support oci_num_rows, among
- * other things.  We use a wrapper class to handle that and other
+ * other things. We use a wrapper class to handle that and other
  * Oracle-specific bits, like converting column names back to lowercase.
  * @ingroup Database
  */
@@ -69,7 +69,7 @@ class ORAResult {
                        $this->nrows = count( $this->rows );
                }
 
-               if ($this->nrows > 0) {
+               if ( $this->nrows > 0 ) {
                        foreach ( $this->rows[0] as $k => $v ) {
                                $this->columns[$k] = strtolower( oci_field_name( $stmt, $k + 1 ) );
                        }
@@ -80,7 +80,7 @@ class ORAResult {
        }
 
        public function free() {
-               unset($this->db);
+               unset( $this->db );
        }
 
        public function seek( $row ) {
@@ -92,7 +92,7 @@ class ORAResult {
        }
 
        public function numFields() {
-               return count($this->columns);
+               return count( $this->columns );
        }
 
        public function fetchObject() {
@@ -633,7 +633,7 @@ class DatabaseOracle extends DatabaseBase {
                }
                list( $startOpts, $useIndex, $tailOpts ) = $this->makeSelectOptions( $selectOptions );
                if ( is_array( $srcTable ) ) {
-                       $srcTable =  implode( ',', array_map( array( &$this, 'tableName' ), $srcTable ) );
+                       $srcTable = implode( ',', array_map( array( &$this, 'tableName' ), $srcTable ) );
                } else {
                        $srcTable = $this->tableName( $srcTable );
                }
@@ -756,7 +756,7 @@ class DatabaseOracle extends DatabaseBase {
 
        function unionQueries( $sqls, $all ) {
                $glue = ' UNION ALL ';
-               return 'SELECT * ' . ( $all ? '':'/* UNION_UNIQUE */ ' ) . 'FROM (' . implode( $glue, $sqls ) . ')' ;
+               return 'SELECT * ' . ( $all ? '':'/* UNION_UNIQUE */ ' ) . 'FROM (' . implode( $glue, $sqls ) . ')';
        }
 
        function wasDeadlock() {
@@ -778,8 +778,8 @@ class DatabaseOracle extends DatabaseBase {
 
        function listTables( $prefix = null, $fname = 'DatabaseOracle::listTables' ) {
                $listWhere = '';
-               if (!empty($prefix)) {
-                       $listWhere = ' AND table_name LIKE \''.strtoupper($prefix).'%\'';
+               if ( !empty( $prefix ) ) {
+                       $listWhere = ' AND table_name LIKE \'' . strtoupper( $prefix ) . '%\'';
                }
 
                $owner = strtoupper( $this->mDBname );
@@ -787,12 +787,12 @@ class DatabaseOracle extends DatabaseBase {
 
                // dirty code ... i know
                $endArray = array();
-               $endArray[] = strtoupper($prefix.'MWUSER');
-               $endArray[] = strtoupper($prefix.'PAGE');
-               $endArray[] = strtoupper($prefix.'IMAGE');
+               $endArray[] = strtoupper( $prefix . 'MWUSER' );
+               $endArray[] = strtoupper( $prefix . 'PAGE' );
+               $endArray[] = strtoupper( $prefix . 'IMAGE' );
                $fixedOrderTabs = $endArray;
-               while (($row = $result->fetchRow()) !== false) {
-                       if (!in_array($row['table_name'], $fixedOrderTabs))
+               while ( ($row = $result->fetchRow()) !== false ) {
+                       if ( !in_array( $row['table_name'], $fixedOrderTabs ) )
                                $endArray[] = $row['table_name'];
                }
 
@@ -800,7 +800,7 @@ class DatabaseOracle extends DatabaseBase {
        }
 
        public function dropTable( $tableName, $fName = 'DatabaseOracle::dropTable' ) {
-               $tableName = $this->tableName($tableName);
+               $tableName = $this->tableName( $tableName );
                if( !$this->tableExists( $tableName ) ) {
                        return false;
                }
@@ -846,7 +846,7 @@ class DatabaseOracle extends DatabaseBase {
        function getServerVersion() {
                //better version number, fallback on driver
                $rset = $this->doQuery( 'SELECT version FROM product_component_version WHERE UPPER(product) LIKE \'ORACLE DATABASE%\'' );
-               if ( !( $row =  $rset->fetchRow() ) ) {
+               if ( !( $row = $rset->fetchRow() ) ) {
                        return oci_server_version( $this->mConn );
                }
                return $row['version'];
@@ -907,7 +907,7 @@ class DatabaseOracle extends DatabaseBase {
                        $table = array_map( array( &$this, 'tableNameInternal' ), $table );
                        $tableWhere = 'IN (';
                        foreach( $table as &$singleTable ) {
-                               $singleTable = $this->removeIdentifierQuotes($singleTable);
+                               $singleTable = $this->removeIdentifierQuotes( $singleTable );
                                if ( isset( $this->mFieldInfoCache["$singleTable.$field"] ) ) {
                                        return $this->mFieldInfoCache["$singleTable.$field"];
                                }
@@ -915,14 +915,14 @@ class DatabaseOracle extends DatabaseBase {
                        }
                        $tableWhere = rtrim( $tableWhere, ',' ) . ')';
                } else {
-                       $table = $this->removeIdentifierQuotes(  $this->tableNameInternal( $table ) );
+                       $table = $this->removeIdentifierQuotes( $this->tableNameInternal( $table ) );
                        if ( isset( $this->mFieldInfoCache["$table.$field"] ) ) {
                                return $this->mFieldInfoCache["$table.$field"];
                        }
                        $tableWhere = '= \''.$table.'\'';
                }
 
-               $fieldInfoStmt = oci_parse( $this->mConn, 'SELECT * FROM wiki_field_info_full WHERE table_name '.$tableWhere.' and column_name = \''.$field.'\'' );
+               $fieldInfoStmt = oci_parse( $this->mConn, 'SELECT * FROM wiki_field_info_full WHERE table_name ' . $tableWhere . ' and column_name = \'' . $field . '\'' );
                if ( oci_execute( $fieldInfoStmt, $this->execFlags() ) === false ) {
                        $e = oci_error( $fieldInfoStmt );
                        $this->reportQueryError( $e['message'], $e['code'], 'fieldInfo QUERY', __METHOD__ );
@@ -957,7 +957,7 @@ class DatabaseOracle extends DatabaseBase {
                if ( is_array( $table ) ) {
                        throw new DBUnexpectedError( $this, 'DatabaseOracle::fieldInfo called with table array!' );
                }
-               return $this->fieldInfoMulti ($table, $field);
+               return $this->fieldInfoMulti( $table, $field );
        }
 
        protected function doBegin( $fname = 'DatabaseOracle::begin' ) {
@@ -1066,7 +1066,7 @@ class DatabaseOracle extends DatabaseBase {
                if ( $db == null || $db == $this->mUser ) {
                        return true;
                }
-               $sql = 'ALTER SESSION SET CURRENT_SCHEMA=' . strtoupper($db);
+               $sql = 'ALTER SESSION SET CURRENT_SCHEMA=' . strtoupper( $db );
                $stmt = oci_parse( $this->mConn, $sql );
                wfSuppressWarnings();
                $success = oci_execute( $stmt );
@@ -1101,11 +1101,11 @@ class DatabaseOracle extends DatabaseBase {
        }
 
        public function removeIdentifierQuotes( $s ) {
-               return strpos($s, '/*Q*/') === FALSE ? $s : substr($s, 5);
+               return strpos( $s, '/*Q*/' ) === false ? $s : substr( $s, 5 );
        }
 
        public function isQuotedIdentifier( $s ) {
-               return strpos($s, '/*Q*/') !== FALSE;
+               return strpos( $s, '/*Q*/' ) !== false;
        }
 
        private function wrapFieldForWhere( $table, &$col, &$val ) {
@@ -1139,7 +1139,7 @@ class DatabaseOracle extends DatabaseBase {
        }
 
        function selectRow( $table, $vars, $conds, $fname = 'DatabaseOracle::selectRow', $options = array(), $join_conds = array() ) {
-               if ( is_array($conds) ) {
+               if ( is_array( $conds ) ) {
                        $conds = $this->wrapConditionsForWhere( $table, $conds );
                }
                return parent::selectRow( $table, $vars, $conds, $fname, $options, $join_conds );
@@ -1166,26 +1166,9 @@ class DatabaseOracle extends DatabaseBase {
                        }
                }
 
-               if ( isset( $options['GROUP BY'] ) ) {
-                       $gb = is_array( $options['GROUP BY'] )
-                               ? implode( ',', $options['GROUP BY'] )
-                               : $options['GROUP BY'];
-                       $preLimitTail .= " GROUP BY {$gb}";
-               }
+               $preLimitTail .= $this->makeGroupByWithHaving( $options );
 
-               if ( isset( $options['HAVING'] ) ) {
-                       $having = is_array( $options['HAVING'] )
-                               ? $this->makeList( $options['HAVING'], LIST_AND )
-                               : $options['HAVING'];
-                       $preLimitTail .= " HAVING {$having}";
-               }
-
-               if ( isset( $options['ORDER BY'] ) ) {
-                       $ob = is_array( $options['ORDER BY'] )
-                               ? implode( ',', $options['ORDER BY'] )
-                               : $options['ORDER BY'];
-                       $preLimitTail .= " ORDER BY {$ob}";
-               }
+               $preLimitTail .= $this->makeOrderBy( $options );
 
                if ( isset( $noKeyOptions['FOR UPDATE'] ) ) {
                        $postLimitTail .= ' FOR UPDATE';
@@ -1203,15 +1186,15 @@ class DatabaseOracle extends DatabaseBase {
 
                return array( $startOpts, $useIndex, $preLimitTail, $postLimitTail );
        }
-       
+
        public function delete( $table, $conds, $fname = 'DatabaseOracle::delete' ) {
-               if ( is_array($conds) ) {
+               if ( is_array( $conds ) ) {
                        $conds = $this->wrapConditionsForWhere( $table, $conds );
                }
                // a hack for deleting pages, users and images (which have non-nullable FKs)
                // all deletions on these tables have transactions so final failure rollbacks these updates
                $table = $this->tableName( $table );
-               if ( $table == $this->tableName( 'user' )  ) {
+               if ( $table == $this->tableName( 'user' ) ) {
                                $this->update( 'archive', array( 'ar_user' => 0 ), array( 'ar_user' => $conds['user_id'] ), $fname );
                                $this->update( 'ipblocks', array( 'ipb_user' => 0 ), array( 'ipb_user' => $conds['user_id'] ), $fname );
                                $this->update( 'image', array( 'img_user' => 0 ), array( 'img_user' => $conds['user_id'] ), $fname );
@@ -1221,7 +1204,7 @@ class DatabaseOracle extends DatabaseBase {
                                $this->update( 'uploadstash', array( 'us_user' => 0 ), array( 'us_user' => $conds['user_id'] ), $fname );
                                $this->update( 'recentchanges', array( 'rc_user' => 0 ), array( 'rc_user' => $conds['user_id'] ), $fname );
                                $this->update( 'logging', array( 'log_user' => 0 ), array( 'log_user' => $conds['user_id'] ), $fname );
-               } elseif ( $table == $this->tableName( 'image' )  ) {
+               } elseif ( $table == $this->tableName( 'image' ) ) {
                                $this->update( 'oldimage', array( 'oi_name' => 0 ), array( 'oi_name' => $conds['img_name'] ), $fname );
                }
                return parent::delete( $table, $conds, $fname );
index 419488e..86b8e8a 100644 (file)
@@ -176,8 +176,8 @@ class PostgresTransactionState {
                                $old = reset( $this->mCurrentState );
                                $new = reset( $this->mNewState );
                                foreach ( self::$WATCHED as $watched ) {
-                                       if ($old !== $new) {
-                                               $this->log_changed($old, $new, $watched);
+                                       if ( $old !== $new ) {
+                                               $this->log_changed( $old, $new, $watched );
                                        }
                                        $old = next( $this->mCurrentState );
                                        $new = next( $this->mNewState );
@@ -197,11 +197,11 @@ class PostgresTransactionState {
        }
 
        protected function log_changed( $old, $new, $watched ) {
-               wfDebug(sprintf($watched["desc"],
+               wfDebug( sprintf( $watched["desc"],
                        $this->mConn,
                        $this->describe_changed( $old, $watched["states"] ),
-                       $this->describe_changed( $new, $watched["states"] ))
-               );
+                       $this->describe_changed( $new, $watched["states"] )
+               ) );
        }
 }
 
@@ -218,7 +218,7 @@ class SavepointPostgres {
        protected $id;
        protected $didbegin;
 
-       public function __construct ($dbw, $id) {
+       public function __construct ( $dbw, $id ) {
                $this->dbw = $dbw;
                $this->id = $id;
                $this->didbegin = false;
@@ -232,12 +232,14 @@ class SavepointPostgres {
        public function __destruct() {
                if ( $this->didbegin ) {
                        $this->dbw->rollback();
+                       $this->didbegin = false;
                }
        }
 
        public function commit() {
                if ( $this->didbegin ) {
                        $this->dbw->commit();
+                       $this->didbegin = false;
                }
        }
 
@@ -245,29 +247,29 @@ class SavepointPostgres {
                global $wgDebugDBTransactions;
                if ( $this->dbw->doQuery( $keyword . " " . $this->id ) !== false ) {
                        if ( $wgDebugDBTransactions ) {
-                               wfDebug( sprintf ($msg_ok, $this->id ) );
+                               wfDebug( sprintf ( $msg_ok, $this->id ) );
                        }
                } else {
-                       wfDebug( sprintf ($msg_failed, $this->id ) );
+                       wfDebug( sprintf ( $msg_failed, $this->id ) );
                }
        }
 
        public function savepoint() {
-               $this->query("SAVEPOINT",
+               $this->query( "SAVEPOINT",
                        "Transaction state: savepoint \"%s\" established.\n",
                        "Transaction state: establishment of savepoint \"%s\" FAILED.\n"
                );
        }
 
        public function release() {
-               $this->query("RELEASE",
+               $this->query( "RELEASE",
                        "Transaction state: savepoint \"%s\" released.\n",
                        "Transaction state: release of savepoint \"%s\" FAILED.\n"
                );
        }
 
        public function rollback() {
-               $this->query("ROLLBACK TO",
+               $this->query( "ROLLBACK TO",
                        "Transaction state: savepoint \"%s\" rolled back.\n",
                        "Transaction state: rollback of savepoint \"%s\" FAILED.\n"
                );
@@ -604,7 +606,7 @@ class DatabasePostgres extends DatabaseBase {
         * Takes same arguments as Database::select()
         * @return int
         */
-       function estimateRowCount( $table, $vars = '*', $conds='', $fname = 'DatabasePostgres::estimateRowCount', $options = array() ) {
+       function estimateRowCount( $table, $vars = '*', $conds = '', $fname = 'DatabasePostgres::estimateRowCount', $options = array() ) {
                $options['EXPLAIN'] = true;
                $res = $this->select( $table, $vars, $conds, $fname, $options );
                $rows = -1;
@@ -682,7 +684,7 @@ class DatabasePostgres extends DatabaseBase {
                                        AND     i.indclass[s.g] = opcls.oid
                                        AND     pg_am.oid = opcls.opcmethod
 __INDEXATTR__;
-               $res = $this->query($sql, __METHOD__);
+               $res = $this->query( $sql, __METHOD__ );
                $a = array();
                if ( $res ) {
                        foreach ( $res as $row ) {
@@ -690,7 +692,7 @@ __INDEXATTR__;
                                        $row->attname,
                                        $row->opcname,
                                        $row->amname,
-                                       $row->option);
+                                       $row->option );
                        }
                } else {
                        return null;
@@ -733,7 +735,7 @@ __INDEXATTR__;
                }
 
                $table = $this->tableName( $table );
-               if (isset( $this->numeric_version ) ) {
+               if ( !isset( $this->numeric_version ) ) {
                        $this->getServerVersion();
                }
 
@@ -985,7 +987,7 @@ __INDEXATTR__;
                $endArray = array();
 
                foreach( $result as $table ) {
-                       $vars = get_object_vars($table);
+                       $vars = get_object_vars( $table );
                        $table = array_pop( $vars );
                        if( !$prefix || strpos( $table, $prefix ) === 0 ) {
                                $endArray[] = $table;
@@ -1066,7 +1068,7 @@ __INDEXATTR__;
         * @return string return default schema for the current session
         */
        function getCurrentSchema() {
-               $res = $this->query( "SELECT current_schema()", __METHOD__);
+               $res = $this->query( "SELECT current_schema()", __METHOD__ );
                $row = $this->fetchRow( $res );
                return $row[0];
        }
@@ -1082,11 +1084,11 @@ __INDEXATTR__;
         * @return array list of actual schemas for the current sesson
         */
        function getSchemas() {
-               $res = $this->query( "SELECT current_schemas(false)", __METHOD__);
+               $res = $this->query( "SELECT current_schemas(false)", __METHOD__ );
                $row = $this->fetchRow( $res );
                $schemas = array();
                /* PHP pgsql support does not support array type, "{a,b}" string is returned */
-               return $this->pg_array_parse($row[0], $schemas);
+               return $this->pg_array_parse( $row[0], $schemas );
        }
 
        /**
@@ -1099,10 +1101,10 @@ __INDEXATTR__;
         * @return array how to search for table names schemas for the current user
         */
        function getSearchPath() {
-               $res = $this->query( "SHOW search_path", __METHOD__);
+               $res = $this->query( "SHOW search_path", __METHOD__ );
                $row = $this->fetchRow( $res );
                /* PostgreSQL returns SHOW values as strings */
-               return explode(",", $row[0]);
+               return explode( ",", $row[0] );
        }
 
        /**
@@ -1113,7 +1115,7 @@ __INDEXATTR__;
         * @param $search_path array list of schemas to be searched by default
         */
        function setSearchPath( $search_path ) {
-               $this->query( "SET search_path = " . implode(", ", $search_path) );
+               $this->query( "SET search_path = " . implode( ", ", $search_path ) );
        }
 
        /**
@@ -1134,7 +1136,7 @@ __INDEXATTR__;
                if ( $this->schemaExists( $desired_schema ) ) {
                        if ( in_array( $desired_schema, $this->getSchemas() ) ) {
                                $this->mCoreSchema = $desired_schema;
-                               wfDebug("Schema \"" . $desired_schema . "\" already in the search path\n");
+                               wfDebug( "Schema \"" . $desired_schema . "\" already in the search path\n" );
                        } else {
                                /**
                                 * Prepend our schema (e.g. 'mediawiki') in front
@@ -1146,11 +1148,11 @@ __INDEXATTR__;
                                        $this->addIdentifierQuotes( $desired_schema ));
                                $this->setSearchPath( $search_path );
                                $this->mCoreSchema = $desired_schema;
-                               wfDebug("Schema \"" . $desired_schema . "\" added to the search path\n");
+                               wfDebug( "Schema \"" . $desired_schema . "\" added to the search path\n" );
                        }
                } else {
                        $this->mCoreSchema = $this->getCurrentSchema();
-                       wfDebug("Schema \"" . $desired_schema . "\" not found, using current \"". $this->mCoreSchema ."\"\n");
+                       wfDebug( "Schema \"" . $desired_schema . "\" not found, using current \"" . $this->mCoreSchema . "\"\n" );
                }
                /* Commit SET otherwise it will be rollbacked on error or IGNORE SELECT */
                $this->commit( __METHOD__ );
@@ -1256,8 +1258,8 @@ SQL;
        }
 
        function constraintExists( $table, $constraint ) {
-               $SQL = sprintf( "SELECT 1 FROM information_schema.table_constraints ".
-                          "WHERE constraint_schema = %s AND table_name = %s AND constraint_name = %s",
+               $SQL = sprintf( "SELECT 1 FROM information_schema.table_constraints " .
+                               "WHERE constraint_schema = %s AND table_name = %s AND constraint_name = %s",
                        $this->addQuotes( $this->getCoreSchema() ),
                        $this->addQuotes( $table ),
                        $this->addQuotes( $constraint )
@@ -1384,23 +1386,9 @@ SQL;
                        }
                }
 
-               if ( isset( $options['GROUP BY'] ) ) {
-                       $gb = is_array( $options['GROUP BY'] )
-                               ? implode( ',', $options['GROUP BY'] )
-                               : $options['GROUP BY'];
-                       $preLimitTail .= " GROUP BY {$gb}";
-               }
-
-               if ( isset( $options['HAVING'] ) ) {
-                       $preLimitTail .= " HAVING {$options['HAVING']}";
-               }
+               $preLimitTail .= $this->makeGroupByWithHaving( $options );
 
-               if ( isset( $options['ORDER BY'] ) ) {
-                       $ob = is_array( $options['ORDER BY'] )
-                               ? implode( ',', $options['ORDER BY'] )
-                               : $options['ORDER BY'];
-                       $preLimitTail .= " ORDER BY {$ob}";
-               }
+               $preLimitTail .= $this->makeOrderBy( $options );
 
                //if ( isset( $options['LIMIT'] ) ) {
                //      $tailOpts .= $this->limitResult( '', $options['LIMIT'],
index d30d984..9120c28 100644 (file)
@@ -127,6 +127,8 @@ class DatabaseSqlite extends DatabaseBase {
                # set error codes only, don't raise exceptions
                if ( $this->mOpened ) {
                        $this->mConn->setAttribute( PDO::ATTR_ERRMODE, PDO::ERRMODE_SILENT );
+                       # Enforce LIKE to be case sensitive, just like MySQL\r
+                       $this->query( 'PRAGMA case_sensitive_like = 1' );
                        return true;
                }
        }
@@ -161,7 +163,7 @@ class DatabaseSqlite extends DatabaseBase {
                        $res = $this->query( "SELECT sql FROM sqlite_master WHERE tbl_name = '$table'", __METHOD__ );
                        if ( $res ) {
                                $row = $res->fetchRow();
-                               self::$fulltextEnabled = stristr($row['sql'], 'fts' ) !== false;
+                               self::$fulltextEnabled = stristr( $row['sql'], 'fts' ) !== false;
                        }
                }
                return self::$fulltextEnabled;
@@ -848,7 +850,7 @@ class DatabaseSqlite extends DatabaseBase {
                $endArray = array();
 
                foreach( $result as $table ) {
-                       $vars = get_object_vars($table);
+                       $vars = get_object_vars( $table );
                        $table = array_pop( $vars );
 
                        if( !$prefix || strpos( $table, $prefix ) === 0 ) {
index c846788..5e11076 100644 (file)
@@ -138,7 +138,7 @@ class ResultWrapper implements Iterator {
 
        /**
         * Fetch the next row from the given result object, in associative array
-        * form.  Fields are retrieved with $row['fieldname'].
+        * form. Fields are retrieved with $row['fieldname'].
         *
         * @return Array
         * @throws DBUnexpectedError Thrown if the database returns an error
@@ -306,4 +306,3 @@ class LikeMatch {
  */
 interface DBMasterPos {
 }
-
index 1ea4b12..6a7a5bb 100644 (file)
@@ -272,4 +272,4 @@ interface IORMRow {
         */
        public function getTable();
 
-}
\ No newline at end of file
+}
index e82c54b..cc7f133 100644 (file)
@@ -240,7 +240,7 @@ class LBFactory_Simple extends LBFactory {
        function newExternalLB( $cluster, $wiki = false ) {
                global $wgExternalServers;
                if ( !isset( $wgExternalServers[$cluster] ) ) {
-                       throw new MWException( __METHOD__.": Unknown cluster \"$cluster\"" );
+                       throw new MWException( __METHOD__ . ": Unknown cluster \"$cluster\"" );
                }
                return new LoadBalancer( array(
                        'servers' => $wgExternalServers[$cluster]
@@ -345,7 +345,7 @@ class ChronologyProtector {
                if ( $lb->getServerCount() > 1 && !empty( $this->startupPos[$masterName] ) ) {
                        $info = $lb->parentInfo();
                        $pos = $this->startupPos[$masterName];
-                       wfDebug( __METHOD__.": LB " . $info['id'] . " waiting for master pos $pos\n" );
+                       wfDebug( __METHOD__ . ": LB " . $info['id'] . " waiting for master pos $pos\n" );
                        $lb->waitFor( $this->startupPos[$masterName] );
                }
        }
@@ -370,11 +370,11 @@ class ChronologyProtector {
                $db = $lb->getAnyOpenConnection( 0 );
                $info = $lb->parentInfo();
                if ( !$db || !$db->doneWrites() ) {
-                       wfDebug( __METHOD__.": LB {$info['id']}, no writes done\n" );
+                       wfDebug( __METHOD__ . ": LB {$info['id']}, no writes done\n" );
                        return;
                }
                $pos = $db->getMasterPos();
-               wfDebug( __METHOD__.": LB {$info['id']} has master pos $pos\n" );
+               wfDebug( __METHOD__ . ": LB {$info['id']} has master pos $pos\n" );
                $this->shutdownPos[$masterName] = $pos;
        }
 
@@ -384,7 +384,7 @@ class ChronologyProtector {
         */
        function shutdown() {
                if ( session_id() != '' && count( $this->shutdownPos ) ) {
-                       wfDebug( __METHOD__.": saving master pos for " .
+                       wfDebug( __METHOD__ . ": saving master pos for " .
                                count( $this->shutdownPos ) . " master(s)\n" );
                        $_SESSION[__CLASS__] = $this->shutdownPos;
                }
index 9b468a7..88b7500 100644 (file)
@@ -83,7 +83,7 @@ class LBFactory_Multi extends LBFactory {
 
                foreach ( $required as $key ) {
                        if ( !isset( $conf[$key] ) ) {
-                               throw new MWException( __CLASS__.": $key is required in configuration" );
+                               throw new MWException( __CLASS__ . ": $key is required in configuration" );
                        }
                        $this->$key = $conf[$key];
                }
@@ -161,7 +161,7 @@ class LBFactory_Multi extends LBFactory {
         */
        function newExternalLB( $cluster, $wiki = false ) {
                if ( !isset( $this->externalLoads[$cluster] ) ) {
-                       throw new MWException( __METHOD__.": Unknown cluster \"$cluster\"" );
+                       throw new MWException( __METHOD__ . ": Unknown cluster \"$cluster\"" );
                }
                $template = $this->serverTemplate;
                if ( isset( $this->externalTemplateOverrides ) ) {
index 2a0c50f..d42a152 100644 (file)
@@ -45,7 +45,7 @@ class LoadBalancer {
         */
        function __construct( $params ) {
                if ( !isset( $params['servers'] ) ) {
-                       throw new MWException( __CLASS__.': missing servers parameter' );
+                       throw new MWException( __CLASS__ . ': missing servers parameter' );
                }
                $this->mServers = $params['servers'];
 
@@ -205,7 +205,7 @@ class LoadBalancer {
                global $wgReadOnly, $wgDBClusterTimeout, $wgDBAvgStatusPoll, $wgDBtype;
 
                # @todo FIXME: For now, only go through all this for mysql databases
-               if ($wgDBtype != 'mysql') {
+               if ( $wgDBtype != 'mysql' ) {
                        return $this->getWriterIndex();
                }
 
@@ -230,7 +230,7 @@ class LoadBalancer {
                                $nonErrorLoads = $this->mGroupLoads[$group];
                        } else {
                                # No loads for this group, return false and the caller can use some other group
-                               wfDebug( __METHOD__.": no loads for group $group\n" );
+                               wfDebug( __METHOD__ . ": no loads for group $group\n" );
                                wfProfileOut( __METHOD__ );
                                return false;
                        }
@@ -272,16 +272,16 @@ class LoadBalancer {
                                        # pickRandom() returned false
                                        # This is permanent and means the configuration or the load monitor
                                        # wants us to return false.
-                                       wfDebugLog( 'connect', __METHOD__.": pickRandom() returned false\n" );
+                                       wfDebugLog( 'connect', __METHOD__ . ": pickRandom() returned false\n" );
                                        wfProfileOut( __METHOD__ );
                                        return false;
                                }
 
-                               wfDebugLog( 'connect', __METHOD__.": Using reader #$i: {$this->mServers[$i]['host']}...\n" );
+                               wfDebugLog( 'connect', __METHOD__ . ": Using reader #$i: {$this->mServers[$i]['host']}...\n" );
                                $conn = $this->openConnection( $i, $wiki );
 
                                if ( !$conn ) {
-                                       wfDebugLog( 'connect', __METHOD__.": Failed connecting to $i/$wiki\n" );
+                                       wfDebugLog( 'connect', __METHOD__ . ": Failed connecting to $i/$wiki\n" );
                                        unset( $nonErrorLoads[$i] );
                                        unset( $currentLoads[$i] );
                                        continue;
@@ -320,7 +320,7 @@ class LoadBalancer {
 
                        # Some servers must have been overloaded
                        if ( $overloadedServers == 0 ) {
-                               throw new MWException( __METHOD__.": unexpectedly found no overloaded servers" );
+                               throw new MWException( __METHOD__ . ": unexpectedly found no overloaded servers" );
                        }
                        # Back off for a while
                        # Scale the sleep time by the number of connected threads, to produce a
@@ -358,7 +358,7 @@ class LoadBalancer {
         */
        function sleep( $t ) {
                wfProfileIn( __METHOD__ );
-               wfDebug( __METHOD__.": waiting $t us\n" );
+               wfDebug( __METHOD__ . ": waiting $t us\n" );
                usleep( $t );
                wfProfileOut( __METHOD__ );
                return $t;
@@ -435,15 +435,15 @@ class LoadBalancer {
                        }
                }
 
-               wfDebug( __METHOD__.": Waiting for slave #$index to catch up...\n" );
+               wfDebug( __METHOD__ . ": Waiting for slave #$index to catch up...\n" );
                $result = $conn->masterPosWait( $this->mWaitForPos, $this->mWaitTimeout );
 
                if ( $result == -1 || is_null( $result ) ) {
                        # Timed out waiting for slave, use master instead
-                       wfDebug( __METHOD__.": Timed out waiting for slave #$index pos {$this->mWaitForPos}\n" );
+                       wfDebug( __METHOD__ . ": Timed out waiting for slave #$index pos {$this->mWaitForPos}\n" );
                        return false;
                } else {
-                       wfDebug( __METHOD__.": Done\n" );
+                       wfDebug( __METHOD__ . ": Done\n" );
                        return true;
                }
        }
@@ -479,7 +479,7 @@ class LoadBalancer {
                        $groupIndex = $this->getReaderIndex( $groups, $wiki );
                        if ( $groupIndex !== false ) {
                                $serverName = $this->getServerName( $groupIndex );
-                               wfDebug( __METHOD__.": using server $serverName for group $groups\n" );
+                               wfDebug( __METHOD__ . ": using server $serverName for group $groups\n" );
                                $i = $groupIndex;
                        }
                } else {
@@ -487,7 +487,7 @@ class LoadBalancer {
                                $groupIndex = $this->getReaderIndex( $group, $wiki );
                                if ( $groupIndex !== false ) {
                                        $serverName = $this->getServerName( $groupIndex );
-                                       wfDebug( __METHOD__.": using server $serverName for group $group\n" );
+                                       wfDebug( __METHOD__ . ": using server $serverName for group $group\n" );
                                        $i = $groupIndex;
                                        break;
                                }
@@ -525,8 +525,8 @@ class LoadBalancer {
         * @throws MWException
         */
        public function reuseConnection( $conn ) {
-               $serverIndex = $conn->getLBInfo('serverIndex');
-               $refCount = $conn->getLBInfo('foreignPoolRefCount');
+               $serverIndex = $conn->getLBInfo( 'serverIndex' );
+               $refCount = $conn->getLBInfo( 'foreignPoolRefCount' );
                $dbName = $conn->getDBname();
                $prefix = $conn->tablePrefix();
                if ( strval( $prefix ) !== '' ) {
@@ -535,7 +535,7 @@ class LoadBalancer {
                        $wiki = $dbName;
                }
                if ( $serverIndex === null || $refCount === null ) {
-                       wfDebug( __METHOD__.": this connection was not opened as a foreign connection\n" );
+                       wfDebug( __METHOD__ . ": this connection was not opened as a foreign connection\n" );
                        /**
                         * This can happen in code like:
                         *   foreach ( $dbs as $db ) {
@@ -549,15 +549,15 @@ class LoadBalancer {
                        return;
                }
                if ( $this->mConns['foreignUsed'][$serverIndex][$wiki] !== $conn ) {
-                       throw new MWException( __METHOD__.": connection not found, has the connection been freed already?" );
+                       throw new MWException( __METHOD__ . ": connection not found, has the connection been freed already?" );
                }
                $conn->setLBInfo( 'foreignPoolRefCount', --$refCount );
                if ( $refCount <= 0 ) {
                        $this->mConns['foreignFree'][$serverIndex][$wiki] = $conn;
                        unset( $this->mConns['foreignUsed'][$serverIndex][$wiki] );
-                       wfDebug( __METHOD__.": freed connection $serverIndex/$wiki\n" );
+                       wfDebug( __METHOD__ . ": freed connection $serverIndex/$wiki\n" );
                } else {
-                       wfDebug( __METHOD__.": reference count for $serverIndex/$wiki reduced to $refCount\n" );
+                       wfDebug( __METHOD__ . ": reference count for $serverIndex/$wiki reduced to $refCount\n" );
                }
        }
 
@@ -620,18 +620,18 @@ class LoadBalancer {
         * @return DatabaseBase
         */
        function openForeignConnection( $i, $wiki ) {
-               wfProfileIn(__METHOD__);
+               wfProfileIn( __METHOD__ );
                list( $dbName, $prefix ) = wfSplitWikiID( $wiki );
                if ( isset( $this->mConns['foreignUsed'][$i][$wiki] ) ) {
                        // Reuse an already-used connection
                        $conn = $this->mConns['foreignUsed'][$i][$wiki];
-                       wfDebug( __METHOD__.": reusing connection $i/$wiki\n" );
+                       wfDebug( __METHOD__ . ": reusing connection $i/$wiki\n" );
                } elseif ( isset( $this->mConns['foreignFree'][$i][$wiki] ) ) {
                        // Reuse a free connection for the same wiki
                        $conn = $this->mConns['foreignFree'][$i][$wiki];
                        unset( $this->mConns['foreignFree'][$i][$wiki] );
                        $this->mConns['foreignUsed'][$i][$wiki] = $conn;
-                       wfDebug( __METHOD__.": reusing free connection $i/$wiki\n" );
+                       wfDebug( __METHOD__ . ": reusing free connection $i/$wiki\n" );
                } elseif ( !empty( $this->mConns['foreignFree'][$i] ) ) {
                        // Reuse a connection from another wiki
                        $conn = reset( $this->mConns['foreignFree'][$i] );
@@ -646,7 +646,7 @@ class LoadBalancer {
                                $conn->tablePrefix( $prefix );
                                unset( $this->mConns['foreignFree'][$i][$oldWiki] );
                                $this->mConns['foreignUsed'][$i][$wiki] = $conn;
-                               wfDebug( __METHOD__.": reusing free connection from $oldWiki for $wiki\n" );
+                               wfDebug( __METHOD__ . ": reusing free connection from $oldWiki for $wiki\n" );
                        }
                } else {
                        // Open a new connection
@@ -655,13 +655,13 @@ class LoadBalancer {
                        $server['foreignPoolRefCount'] = 0;
                        $conn = $this->reallyOpenConnection( $server, $dbName );
                        if ( !$conn->isOpen() ) {
-                               wfDebug( __METHOD__.": error opening connection for $i/$wiki\n" );
+                               wfDebug( __METHOD__ . ": error opening connection for $i/$wiki\n" );
                                $this->mErrorConnection = $conn;
                                $conn = false;
                        } else {
                                $conn->tablePrefix( $prefix );
                                $this->mConns['foreignUsed'][$i][$wiki] = $conn;
-                               wfDebug( __METHOD__.": opened new connection for $i/$wiki\n" );
+                               wfDebug( __METHOD__ . ": opened new connection for $i/$wiki\n" );
                        }
                }
 
@@ -670,7 +670,7 @@ class LoadBalancer {
                        $refCount = $conn->getLBInfo( 'foreignPoolRefCount' );
                        $conn->setLBInfo( 'foreignPoolRefCount', $refCount + 1 );
                }
-               wfProfileOut(__METHOD__);
+               wfProfileOut( __METHOD__ );
                return $conn;
        }
 
index 146ac61..cb3376f 100644 (file)
@@ -159,7 +159,7 @@ class LoadMonitor_MySQL implements LoadMonitor {
 
                $times = array();
                foreach ( $serverIndexes as $i ) {
-                       if ($i == 0) { # Master
+                       if ( $i == 0 ) { # Master
                                $times[$i] = 0;
                        } elseif ( false !== ( $conn = $this->parent->getAnyOpenConnection( $i ) ) ) {
                                $times[$i] = $conn->getLag();
@@ -173,7 +173,7 @@ class LoadMonitor_MySQL implements LoadMonitor {
                $wgMemc->set( $memcKey, $times, $expiry );
 
                # But don't give the timestamp to the caller
-               unset($times['timestamp']);
+               unset( $times['timestamp'] );
                $lagTimes = $times;
 
                wfProfileOut( __METHOD__ );
@@ -189,7 +189,7 @@ class LoadMonitor_MySQL implements LoadMonitor {
                if ( !$threshold ) {
                        return 0;
                }
-               $status = $conn->getMysqlStatus("Thread%");
+               $status = $conn->getMysqlStatus( "Thread%" );
                if ( $status['Threads_running'] > $threshold ) {
                        $server = $conn->getProperty( 'mServer' );
                        wfLogDBError( "LB backoff from $server - Threads_running = {$status['Threads_running']}\n" );
@@ -199,4 +199,3 @@ class LoadMonitor_MySQL implements LoadMonitor {
                }
        }
 }
-
index 7542797..077eab0 100644 (file)
@@ -28,4 +28,4 @@
  */
 interface ORMIterator extends Iterator {
 
-}
\ No newline at end of file
+}
index 8abfdb6..06f88c1 100644 (file)
@@ -901,4 +901,4 @@ class ORMTable extends DBAccessBase implements IORMTable {
                return array_key_exists( $name, $this->getFields() );
        }
 
-}
\ No newline at end of file
+}
index 46a3398..6ef5fcb 100644 (file)
@@ -167,7 +167,7 @@ class _DiffOp_Change extends _DiffOp {
  */
 class _DiffEngine {
 
-       const MAX_XREF_LENGTH =  10000;
+       const MAX_XREF_LENGTH = 10000;
 
        protected $xchanged, $ychanged;
 
@@ -491,8 +491,7 @@ class _DiffEngine {
                        // $nchunks = sqrt(min($xlim - $xoff, $ylim - $yoff) / 2.5);
                        // $nchunks = max(2,min(8,(int)$nchunks));
                        $nchunks = min( 7, $xlim - $xoff, $ylim - $yoff ) + 1;
-                       list ( $lcs, $seps )
-                       = $this->_diag( $xoff, $xlim, $yoff, $ylim, $nchunks );
+                       list ( $lcs, $seps ) = $this->_diag( $xoff, $xlim, $yoff, $ylim, $nchunks );
                }
 
                if ( $lcs == 0 ) {
@@ -1365,7 +1364,7 @@ class TableDiffFormatter extends DiffFormatter {
         */
        function _block_header( $xbeg, $xlen, $ybeg, $ylen ) {
                $r = '<tr><td colspan="2" class="diff-lineno"><!--LINE ' . $xbeg . "--></td>\n" .
-                 '<td colspan="2" class="diff-lineno"><!--LINE ' . $ybeg . "--></td></tr>\n";
+                       '<td colspan="2" class="diff-lineno"><!--LINE ' . $ybeg . "--></td></tr>\n";
                return $r;
        }
 
index 97553e6..a3239a3 100644 (file)
@@ -152,7 +152,7 @@ class DifferenceEngine extends ContextSource {
        function deletedLink( $id ) {
                if ( $this->getUser()->isAllowed( 'deletedhistory' ) ) {
                        $dbr = wfGetDB( DB_SLAVE );
-                       $row = $dbr->selectRow('archive', '*',
+                       $row = $dbr->selectRow( 'archive', '*',
                                array( 'ar_rev_id' => $id ),
                                __METHOD__ );
                        if ( $row ) {
index 8bf1ca9..5dd49d7 100644 (file)
@@ -138,7 +138,7 @@ class ExternalStore {
                while ( count( $tryStores ) > 0 ) {
                        $index = mt_rand( 0, count( $tryStores ) - 1 );
                        $storeUrl = $tryStores[$index];
-                       wfDebug( __METHOD__.": trying $storeUrl\n" );
+                       wfDebug( __METHOD__ . ": trying $storeUrl\n" );
                        list( $proto, $path ) = explode( '://', $storeUrl, 2 );
                        $store = self::getStoreObject( $proto, $params );
                        if ( $store === false ) {
index 8e05cfe..3857771 100644 (file)
@@ -79,7 +79,7 @@ class ExternalStoreDB extends ExternalStoreMedium {
         * @return LoadBalancer object
         */
        function &getLoadBalancer( $cluster ) {
-               $wiki = isset($this->params['wiki']) ? $this->params['wiki'] : false;
+               $wiki = isset( $this->params['wiki'] ) ? $this->params['wiki'] : false;
 
                return wfGetLBFactory()->getExternalLB( $cluster, $wiki );
        }
@@ -93,12 +93,12 @@ class ExternalStoreDB extends ExternalStoreMedium {
        function &getSlave( $cluster ) {
                global $wgDefaultExternalStore;
 
-               $wiki = isset($this->params['wiki']) ? $this->params['wiki'] : false;
+               $wiki = isset( $this->params['wiki'] ) ? $this->params['wiki'] : false;
                $lb =& $this->getLoadBalancer( $cluster );
 
                if ( !in_array( "DB://" . $cluster, (array)$wgDefaultExternalStore ) ) {
                        wfDebug( "read only external store" );
-                       $lb->allowLagged(true);
+                       $lb->allowLagged( true );
                } else {
                        wfDebug( "writable external store" );
                }
@@ -113,7 +113,7 @@ class ExternalStoreDB extends ExternalStoreMedium {
         * @return DatabaseBase object
         */
        function &getMaster( $cluster ) {
-               $wiki = isset($this->params['wiki']) ? $this->params['wiki'] : false;
+               $wiki = isset( $this->params['wiki'] ) ? $this->params['wiki'] : false;
                $lb =& $this->getLoadBalancer( $cluster );
                return $lb->getConnection( DB_MASTER, array(), $wiki );
        }
index 6794dd5..99d5fc3 100644 (file)
  */
 
 /**
- * Accessable external objects
+ * Accessable external objects in a particular storage medium
+ *
  * @ingroup ExternalStorage
+ * @since 1.21
  */
 abstract class ExternalStoreMedium {
        /** @var Array */
diff --git a/includes/externalstore/ExternalStoreMwstore.php b/includes/externalstore/ExternalStoreMwstore.php
new file mode 100644 (file)
index 0000000..0911cca
--- /dev/null
@@ -0,0 +1,72 @@
+<?php
+/**
+ * External storage in a file backend.
+ *
+ * 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
+ */
+
+/**
+ * File backend accessable external objects.
+ *
+ * In this system, each store "location" maps to the name of a file backend.
+ * The file backends must be defined in $wgFileBackends and must be global
+ * and fully qualified with a global "wikiId" prefix in the configuration.
+ *
+ * @ingroup ExternalStorage
+ * @since 1.21
+ */
+class ExternalStoreMwstore extends ExternalStoreMedium {
+       /**
+        * The URL returned is of the form of the form mwstore://backend/container/wiki/id
+        *
+        * @see ExternalStoreMedium::fetchFromURL()
+        */
+       public function fetchFromURL( $url ) {
+               $be = FileBackendGroup::singleton()->backendFromPath( $url );
+               if ( $be instanceof FileBackend ) {
+                       // We don't need "latest" since objects are immutable and
+                       // backends should at least have "read-after-create" consistency.
+                       return $be->getFileContents( array( 'src' => $url ) );
+               }
+               return false;
+       }
+
+       /**
+        * @see ExternalStoreMedium::store()
+        */
+       public function store( $backend, $data ) {
+               $be = FileBackendGroup::singleton()->get( $backend );
+               if ( $be instanceof FileBackend ) {
+                       // Get three random base 36 characters to act as shard directories
+                       $rand = wfBaseConvert( mt_rand( 0, 46655 ), 10, 36, 3 );
+                       // Make sure ID is roughly lexicographically increasing for performance
+                       $id = str_pad( UIDGenerator::newTimestampedUID128( 32 ), 26, '0', STR_PAD_LEFT );
+                       // Segregate items by wiki ID for the sake of bookkeeping
+                       $wiki = isset( $this->params['wiki'] ) ? $this->params['wiki'] : wfWikiID();
+
+                       $url = $be->getContainerStoragePath( 'data' ) . '/' .
+                               rawurlencode( $wiki ) . "/{$rand[0]}/{$rand[1]}/{$rand[2]}/{$id}";
+
+                       $be->prepare( array( 'dir' => dirname( $url ), 'noAccess' => 1, 'noListing' => 1 ) );
+                       if ( $be->create( array( 'dst' => $url, 'content' => $data ) )->isOK() ) {
+                               return $url;
+                       }
+               }
+               return false;
+       }
+}
index 5141ec5..acbc4a9 100644 (file)
@@ -104,7 +104,7 @@ class FSFile {
         */
        public function getProps( $ext = true ) {
                wfProfileIn( __METHOD__ );
-               wfDebug( __METHOD__.": Getting file info for $this->path\n" );
+               wfDebug( __METHOD__ . ": Getting file info for $this->path\n" );
 
                $info = self::placeholderProps();
                $info['fileExists'] = $this->exists();
@@ -140,9 +140,9 @@ class FSFile {
                        }
                        $info['sha1'] = $this->getSha1Base36();
 
-                       wfDebug(__METHOD__.": $this->path loaded, {$info['size']} bytes, {$info['mime']}.\n");
+                       wfDebug( __METHOD__ . ": $this->path loaded, {$info['size']} bytes, {$info['mime']}.\n" );
                } else {
-                       wfDebug(__METHOD__.": $this->path NOT FOUND!\n");
+                       wfDebug( __METHOD__ . ": $this->path NOT FOUND!\n" );
                }
 
                wfProfileOut( __METHOD__ );
index a4e6ef6..a1d46c1 100644 (file)
@@ -861,12 +861,15 @@ abstract class FSFileBackendList implements Iterator {
         * @param $params array
         */
        public function __construct( $dir, array $params ) {
-               $dir = realpath( $dir ); // normalize
-               $this->suffixStart = strlen( $dir ) + 1; // size of "path/to/dir/"
+               $path = realpath( $dir ); // normalize
+               if( $path === false ) {
+                       $path = $dir;
+               }
+               $this->suffixStart = strlen( $path ) + 1; // size of "path/to/dir/"
                $this->params = $params;
 
                try {
-                       $this->iter = $this->initIterator( $dir );
+                       $this->iter = $this->initIterator( $path );
                } catch ( UnexpectedValueException $e ) {
                        $this->iter = null; // bad permissions? deleted?
                }
@@ -958,8 +961,12 @@ abstract class FSFileBackendList implements Iterator {
         * @param $path string
         * @return string
         */
-       protected function getRelPath( $path ) {
-               return strtr( substr( realpath( $path ), $this->suffixStart ), '\\', '/' );
+       protected function getRelPath( $dir ) {
+               $path = realpath( $dir );
+               if( $path === false ) {
+                       $path = $dir;
+               }
+               return strtr( substr( $path, $this->suffixStart ), '\\', '/' );
        }
 }
 
index 65caf10..c282a07 100644 (file)
  * Outside callers can assume that all backends will have these functions.
  *
  * All "storage paths" are of the format "mwstore://<backend>/<container>/<path>".
- * The "<path>" portion is a relative path that uses UNIX file system (FS)
- * notation, though any particular backend may not actually be using a local
- * filesystem. Therefore, the relative paths are only virtual.
+ * The "backend" portion is unique name for MediaWiki to refer to a backend, while
+ * the "container" portion is a top-level directory of the backend. The "path" portion
+ * is a relative path that uses UNIX file system (FS) notation, though any particular
+ * backend may not actually be using a local filesystem. Therefore, the relative paths
+ * are only virtual.
  *
  * Backend contents are stored under wiki-specific container names by default.
- * For legacy reasons, this has no effect for the FS backend class, and per-wiki
- * segregation must be done by setting the container paths appropriately.
+ * Global (qualified) backends are achieved by configuring the "wiki ID" to a constant.
+ * For legacy reasons, the FSFileBackend class allows manually setting the paths of
+ * containers to ones that do not respect the "wiki ID".
  *
+ * In key/value stores, the container is the only hierarchy (the rest is emulated).
  * FS-based backends are somewhat more restrictive due to the existence of real
  * directory files; a regular file cannot have the same name as a directory. Other
  * backends with virtual directories may not have this limitation. Callers should
@@ -75,9 +79,13 @@ abstract class FileBackend {
         * $config includes:
         *   - name        : The unique name of this backend.
         *                   This should consist of alphanumberic, '-', and '_' characters.
-        *                   This name should not be changed after use.
-        *   - wikiId      : Prefix to container names that is unique to this wiki.
+        *                   This name should not be changed after use (e.g. with journaling).
+        *                   Note that the name is *not* used in actual container names.
+        *   - wikiId      : Prefix to container names that is unique to this backend.
+        *                   If not provided, this defaults to the current wiki ID.
         *                   It should only consist of alphanumberic, '-', and '_' characters.
+        *                   This ID is what avoids collisions if multiple logical backends
+        *                   use the same storage system, so this should be set carefully.
         *   - lockManager : Registered name of a file lock manager to use.
         *   - fileJournal : File journal configuration; see FileJournal::factory().
         *                   Journals simply log changes to files stored in the backend.
@@ -100,7 +108,7 @@ abstract class FileBackend {
                        : wfWikiID(); // e.g. "my_wiki-en_"
                $this->lockManager = ( $config['lockManager'] instanceof LockManager )
                        ? $config['lockManager']
-                       : LockManagerGroup::singleton()->get( $config['lockManager'] );
+                       : LockManagerGroup::singleton( $this->wikiId )->get( $config['lockManager'] );
                $this->fileJournal = isset( $config['fileJournal'] )
                        ? ( ( $config['fileJournal'] instanceof FileJournal )
                                ? $config['fileJournal']
@@ -313,6 +321,7 @@ abstract class FileBackend {
                if ( empty( $opts['force'] ) ) { // sanity
                        unset( $opts['nonLocking'] );
                }
+               $scope = $this->getScopedPHPBehaviorForOps(); // try to ignore client aborts
                return $this->doOperationsInternal( $ops, $opts );
        }
 
@@ -543,6 +552,7 @@ abstract class FileBackend {
                foreach ( $ops as &$op ) {
                        $op['overwrite'] = true; // avoids RTTs in key/value stores
                }
+               $scope = $this->getScopedPHPBehaviorForOps(); // try to ignore client aborts
                return $this->doQuickOperationsInternal( $ops );
        }
 
@@ -686,6 +696,7 @@ abstract class FileBackend {
                if ( empty( $params['bypassReadOnly'] ) && $this->isReadOnly() ) {
                        return Status::newFatal( 'backend-fail-readonly', $this->name, $this->readOnly );
                }
+               $scope = $this->getScopedPHPBehaviorForOps(); // try to ignore client aborts
                return $this->doPrepare( $params );
        }
 
@@ -713,6 +724,7 @@ abstract class FileBackend {
                if ( empty( $params['bypassReadOnly'] ) && $this->isReadOnly() ) {
                        return Status::newFatal( 'backend-fail-readonly', $this->name, $this->readOnly );
                }
+               $scope = $this->getScopedPHPBehaviorForOps(); // try to ignore client aborts
                return $this->doSecure( $params );
        }
 
@@ -741,6 +753,7 @@ abstract class FileBackend {
                if ( empty( $params['bypassReadOnly'] ) && $this->isReadOnly() ) {
                        return Status::newFatal( 'backend-fail-readonly', $this->name, $this->readOnly );
                }
+               $scope = $this->getScopedPHPBehaviorForOps(); // try to ignore client aborts
                return $this->doPublish( $params );
        }
 
@@ -765,6 +778,7 @@ abstract class FileBackend {
                if ( empty( $params['bypassReadOnly'] ) && $this->isReadOnly() ) {
                        return Status::newFatal( 'backend-fail-readonly', $this->name, $this->readOnly );
                }
+               $scope = $this->getScopedPHPBehaviorForOps(); // try to ignore client aborts
                return $this->doClean( $params );
        }
 
@@ -773,6 +787,21 @@ abstract class FileBackend {
         */
        abstract protected function doClean( array $params );
 
+       /**
+        * Enter file operation scope.
+        * This just makes PHP ignore user aborts/disconnects until the return
+        * value leaves scope. This returns null and does nothing in CLI mode.
+        *
+        * @return ScopedCallback|null
+        */
+       final protected function getScopedPHPBehaviorForOps() {
+               if ( php_sapi_name() != 'cli' ) { // http://bugs.php.net/bug.php?id=47540
+                       $old = ignore_user_abort( true ); // avoid half-finished operations
+                       return new ScopedCallback( function() use ( $old ) { ignore_user_abort( $old ); } );
+               }
+               return null;
+       }
+
        /**
         * Check if a file exists at a storage path in the backend.
         * This returns false if only a directory exists at the path.
index 5327204..0bf5279 100644 (file)
@@ -87,6 +87,9 @@ class FileBackendGroup {
                        $thumbDir = isset( $info['thumbDir'] )
                                ? $info['thumbDir']
                                : "{$directory}/thumb";
+                       $transcodedDir = isset( $info['transcodedDir'] )
+                               ? $info['transcodedDir']
+                               : "{$directory}/transcoded";
                        $fileMode = isset( $info['fileMode'] )
                                ? $info['fileMode']
                                : 0644;
@@ -98,6 +101,7 @@ class FileBackendGroup {
                                'containerPaths' => array(
                                        "{$repoName}-public"  => "{$directory}",
                                        "{$repoName}-thumb"   => $thumbDir,
+                                       "{$repoName}-transcoded"   => $transcodedDir,
                                        "{$repoName}-deleted" => $deletedDir,
                                        "{$repoName}-temp"    => "{$directory}/temp"
                                ),
index a443a3a..a5f5073 100644 (file)
@@ -62,7 +62,7 @@ class FileBackendMultiWrite extends FileBackend {
         * Additional $config params include:
         *   - backends       : Array of backend config and multi-backend settings.
         *                      Each value is the config used in the constructor of a
-        *                          FileBackendStore class, but with these additional settings:
+        *                      FileBackendStore class, but with these additional settings:
         *                        - class         : The name of the backend class
         *                        - isMultiMaster : This must be set for one backend.
         *                        - template:     : If given a backend name, this will use
index 7952bcb..28f5b73 100644 (file)
@@ -167,7 +167,7 @@ abstract class FileOp {
         * @return Array
         */
        final public function applyDependencies( array $deps ) {
-               $deps['read']  += array_fill_keys( $this->storagePathsRead(), 1 );
+               $deps['read'] += array_fill_keys( $this->storagePathsRead(), 1 );
                $deps['write'] += array_fill_keys( $this->storagePathsChanged(), 1 );
                return $deps;
        }
index 3c097a1..d825d04 100644 (file)
@@ -148,7 +148,7 @@ class SwiftFileBackend extends FileBackendStore {
                $this->connContainerCache = new ProcessCacheLRU( 300 );
                // Cache auth token information to avoid RTTs
                if ( !empty( $config['cacheAuthInfo'] ) ) {
-                       if ( php_sapi_name() === 'cli' ) {
+                       if ( PHP_SAPI === 'cli' ) {
                                $this->srvCache = wfGetMainCache(); // preferrably memcached
                        } else {
                                try { // look for APC, XCache, WinCache, ect...
index a8fe258..7b365c1 100644 (file)
@@ -22,7 +22,8 @@
  */
 
 /**
- * Version of LockManager based on using DB table locks.
+ * Version of LockManager based on using DB table row locks.
+ *
  * This is meant for multi-wiki systems that may share files.
  * All locks are blocking, so it might be useful to set a small
  * lock-wait timeout via server config to curtail deadlocks.
@@ -67,6 +68,7 @@ class DBLockManager extends QuorumLockManager {
         *                   each having an odd-numbered list of DB names (peers) as values.
         *                   Any DB named 'localDBMaster' will automatically use the DB master
         *                   settings for this wiki (without the need for a dbServers entry).
+        *                   Only use 'localDBMaster' if the domain is a valid wiki ID.
         *   - lockExpiry  : Lock timeout (seconds) for dropped connections. [optional]
         *                   This tells the DB server how long to wait before assuming
         *                   connection failure and releasing all the locks for a session.
@@ -122,7 +124,7 @@ class DBLockManager extends QuorumLockManager {
 
                if ( $type == self::LOCK_EX ) { // writer locks
                        try {
-                               $keys = array_unique( array_map( 'LockManager::sha1Base36', $paths ) );
+                               $keys = array_unique( array_map( array( $this, 'sha1Base36Absolute' ), $paths ) );
                                # Build up values for INSERT clause
                                $data = array();
                                foreach ( $keys as $key ) {
@@ -197,8 +199,8 @@ class DBLockManager extends QuorumLockManager {
                if ( !isset( $this->conns[$lockDb] ) ) {
                        $db = null;
                        if ( $lockDb === 'localDBMaster' ) {
-                               $lb = wfGetLBFactory()->newMainLB();
-                               $db = $lb->getConnection( DB_MASTER );
+                               $lb = wfGetLBFactory()->getMainLB( $this->domain );
+                               $db = $lb->getConnection( DB_MASTER, array(), $this->domain );
                        } elseif ( isset( $this->dbServers[$lockDb] ) ) {
                                $config = $this->dbServers[$lockDb];
                                $db = DatabaseBase::factory( $config['type'], $config );
@@ -321,7 +323,7 @@ class MySqlLockManager extends DBLockManager {
                $status = Status::newGood();
 
                $db = $this->getConnection( $lockSrv ); // checked in isServerUp()
-               $keys = array_unique( array_map( 'LockManager::sha1Base36', $paths ) );
+               $keys = array_unique( array_map( array( $this, 'sha1Base36Absolute' ), $paths ) );
                # Build up values for INSERT clause
                $data = array();
                foreach ( $keys as $key ) {
index 9a6206f..f374fdd 100644 (file)
@@ -237,8 +237,7 @@ class FSLockManager extends LockManager {
         * @return string
         */
        protected function getLockPath( $path ) {
-               $hash = self::sha1Base36( $path );
-               return "{$this->lockDir}/{$hash}.lock";
+               return "{$this->lockDir}/{$this->sha1Base36Absolute( $path )}.lock";
        }
 
        /**
index 3de6183..96d37ab 100644 (file)
@@ -94,7 +94,7 @@ class LSLockManager extends QuorumLockManager {
 
                // Send out the command and get the response...
                $type = ( $type == self::LOCK_SH ) ? 'SH' : 'EX';
-               $keys = array_unique( array_map( 'LockManager::sha1Base36', $paths ) );
+               $keys = array_unique( array_map( array( $this, 'sha1Base36Absolute' ), $paths ) );
                $response = $this->sendCommand( $lockSrv, 'ACQUIRE', $type, $keys );
 
                if ( $response !== 'ACQUIRED' ) {
@@ -115,7 +115,7 @@ class LSLockManager extends QuorumLockManager {
 
                // Send out the command and get the response...
                $type = ( $type == self::LOCK_SH ) ? 'SH' : 'EX';
-               $keys = array_unique( array_map( 'LockManager::sha1Base36', $paths ) );
+               $keys = array_unique( array_map( array( $this, 'sha1Base36Absolute' ), $paths ) );
                $response = $this->sendCommand( $lockSrv, 'RELEASE', $type, $keys );
 
                if ( $response !== 'RELEASED' ) {
index 51454a4..f988ff4 100644 (file)
@@ -53,6 +53,8 @@ abstract class LockManager {
        /** @var Array Map of (resource path => lock type => count) */
        protected $locksHeld = array();
 
+       protected $domain; // string; domain (usually wiki ID)
+
        /* Lock types; stronger locks have higher values */
        const LOCK_SH = 1; // shared lock (for reads)
        const LOCK_UW = 2; // shared lock (for reads used to write elsewhere)
@@ -61,9 +63,14 @@ abstract class LockManager {
        /**
         * Construct a new instance from configuration
         *
+        * $config paramaters include:
+        *   - domain : Domain (usually wiki ID) that all resources are relative to [optional]
+        *
         * @param $config Array
         */
-       public function __construct( array $config ) {}
+       public function __construct( array $config ) {
+               $this->domain = isset( $config['domain'] ) ? $config['domain'] : wfWikiID();
+       }
 
        /**
         * Lock the resources at the given abstract paths
@@ -94,13 +101,15 @@ abstract class LockManager {
        }
 
        /**
-        * Get the base 36 SHA-1 of a string, padded to 31 digits
+        * Get the base 36 SHA-1 of a string, padded to 31 digits.
+        * Before hashing, the path will be prefixed with the domain ID.
+        * This should be used interally for lock key or file names.
         *
         * @param $path string
         * @return string
         */
-       final protected static function sha1Base36( $path ) {
-               return wfBaseConvert( sha1( $path ), 16, 36, 31 );
+       final protected function sha1Base36Absolute( $path ) {
+               return wfBaseConvert( sha1( "{$this->domain}:{$path}" ), 16, 36, 31 );
        }
 
        /**
@@ -122,216 +131,6 @@ abstract class LockManager {
        abstract protected function doUnlock( array $paths, $type );
 }
 
-/**
- * Version of LockManager that uses a quorum from peer servers for locks.
- * The resource space can also be sharded into separate peer groups.
- *
- * @ingroup LockManager
- * @since 1.20
- */
-abstract class QuorumLockManager extends LockManager {
-       /** @var Array Map of bucket indexes to peer server lists */
-       protected $srvsByBucket = array(); // (bucket index => (lsrv1, lsrv2, ...))
-
-       /**
-        * @see LockManager::doLock()
-        * @param $paths array
-        * @param $type int
-        * @return Status
-        */
-       final protected function doLock( array $paths, $type ) {
-               $status = Status::newGood();
-
-               $pathsToLock = array(); // (bucket => paths)
-               // Get locks that need to be acquired (buckets => locks)...
-               foreach ( $paths as $path ) {
-                       if ( isset( $this->locksHeld[$path][$type] ) ) {
-                               ++$this->locksHeld[$path][$type];
-                       } elseif ( isset( $this->locksHeld[$path][self::LOCK_EX] ) ) {
-                               $this->locksHeld[$path][$type] = 1;
-                       } else {
-                               $bucket = $this->getBucketFromKey( $path );
-                               $pathsToLock[$bucket][] = $path;
-                       }
-               }
-
-               $lockedPaths = array(); // files locked in this attempt
-               // Attempt to acquire these locks...
-               foreach ( $pathsToLock as $bucket => $paths ) {
-                       // Try to acquire the locks for this bucket
-                       $status->merge( $this->doLockingRequestBucket( $bucket, $paths, $type ) );
-                       if ( !$status->isOK() ) {
-                               $status->merge( $this->doUnlock( $lockedPaths, $type ) );
-                               return $status;
-                       }
-                       // Record these locks as active
-                       foreach ( $paths as $path ) {
-                               $this->locksHeld[$path][$type] = 1; // locked
-                       }
-                       // Keep track of what locks were made in this attempt
-                       $lockedPaths = array_merge( $lockedPaths, $paths );
-               }
-
-               return $status;
-       }
-
-       /**
-        * @see LockManager::doUnlock()
-        * @param $paths array
-        * @param $type int
-        * @return Status
-        */
-       final protected function doUnlock( array $paths, $type ) {
-               $status = Status::newGood();
-
-               $pathsToUnlock = array();
-               foreach ( $paths as $path ) {
-                       if ( !isset( $this->locksHeld[$path][$type] ) ) {
-                               $status->warning( 'lockmanager-notlocked', $path );
-                       } else {
-                               --$this->locksHeld[$path][$type];
-                               // Reference count the locks held and release locks when zero
-                               if ( $this->locksHeld[$path][$type] <= 0 ) {
-                                       unset( $this->locksHeld[$path][$type] );
-                                       $bucket = $this->getBucketFromKey( $path );
-                                       $pathsToUnlock[$bucket][] = $path;
-                               }
-                               if ( !count( $this->locksHeld[$path] ) ) {
-                                       unset( $this->locksHeld[$path] ); // no SH or EX locks left for key
-                               }
-                       }
-               }
-
-               // Remove these specific locks if possible, or at least release
-               // all locks once this process is currently not holding any locks.
-               foreach ( $pathsToUnlock as $bucket => $paths ) {
-                       $status->merge( $this->doUnlockingRequestBucket( $bucket, $paths, $type ) );
-               }
-               if ( !count( $this->locksHeld ) ) {
-                       $status->merge( $this->releaseAllLocks() );
-               }
-
-               return $status;
-       }
-
-       /**
-        * Attempt to acquire locks with the peers for a bucket.
-        * This is all or nothing; if any key is locked then this totally fails.
-        *
-        * @param $bucket integer
-        * @param $paths Array List of resource keys to lock
-        * @param $type integer LockManager::LOCK_EX or LockManager::LOCK_SH
-        * @return Status
-        */
-       final protected function doLockingRequestBucket( $bucket, array $paths, $type ) {
-               $status = Status::newGood();
-
-               $yesVotes = 0; // locks made on trustable servers
-               $votesLeft = count( $this->srvsByBucket[$bucket] ); // remaining peers
-               $quorum = floor( $votesLeft/2 + 1 ); // simple majority
-               // Get votes for each peer, in order, until we have enough...
-               foreach ( $this->srvsByBucket[$bucket] as $lockSrv ) {
-                       if ( !$this->isServerUp( $lockSrv ) ) {
-                               --$votesLeft;
-                               $status->warning( 'lockmanager-fail-svr-acquire', $lockSrv );
-                               continue; // server down?
-                       }
-                       // Attempt to acquire the lock on this peer
-                       $status->merge( $this->getLocksOnServer( $lockSrv, $paths, $type ) );
-                       if ( !$status->isOK() ) {
-                               return $status; // vetoed; resource locked
-                       }
-                       ++$yesVotes; // success for this peer
-                       if ( $yesVotes >= $quorum ) {
-                               return $status; // lock obtained
-                       }
-                       --$votesLeft;
-                       $votesNeeded = $quorum - $yesVotes;
-                       if ( $votesNeeded > $votesLeft ) {
-                               break; // short-circuit
-                       }
-               }
-               // At this point, we must not have met the quorum
-               $status->setResult( false );
-
-               return $status;
-       }
-
-       /**
-        * Attempt to release locks with the peers for a bucket
-        *
-        * @param $bucket integer
-        * @param $paths Array List of resource keys to lock
-        * @param $type integer LockManager::LOCK_EX or LockManager::LOCK_SH
-        * @return Status
-        */
-       final protected function doUnlockingRequestBucket( $bucket, array $paths, $type ) {
-               $status = Status::newGood();
-
-               foreach ( $this->srvsByBucket[$bucket] as $lockSrv ) {
-                       if ( !$this->isServerUp( $lockSrv ) ) {
-                               $status->fatal( 'lockmanager-fail-svr-release', $lockSrv );
-                       // Attempt to release the lock on this peer
-                       } else {
-                               $status->merge( $this->freeLocksOnServer( $lockSrv, $paths, $type ) );
-                       }
-               }
-
-               return $status;
-       }
-
-       /**
-        * Get the bucket for resource path.
-        * This should avoid throwing any exceptions.
-        *
-        * @param $path string
-        * @return integer
-        */
-       protected function getBucketFromKey( $path ) {
-               $prefix = substr( sha1( $path ), 0, 2 ); // first 2 hex chars (8 bits)
-               return (int)base_convert( $prefix, 16, 10 ) % count( $this->srvsByBucket );
-       }
-
-       /**
-        * Check if a lock server is up
-        *
-        * @param $lockSrv string
-        * @return bool
-        */
-       abstract protected function isServerUp( $lockSrv );
-
-       /**
-        * Get a connection to a lock server and acquire locks on $paths
-        *
-        * @param $lockSrv string
-        * @param $paths array
-        * @param $type integer
-        * @return Status
-        */
-       abstract protected function getLocksOnServer( $lockSrv, array $paths, $type );
-
-       /**
-        * Get a connection to a lock server and release locks on $paths.
-        *
-        * Subclasses must effectively implement this or releaseAllLocks().
-        *
-        * @param $lockSrv string
-        * @param $paths array
-        * @param $type integer
-        * @return Status
-        */
-       abstract protected function freeLocksOnServer( $lockSrv, array $paths, $type );
-
-       /**
-        * Release all locks that this session is holding.
-        *
-        * Subclasses must effectively implement this or freeLocksOnServer().
-        *
-        * @return Status
-        */
-       abstract protected function releaseAllLocks();
-}
-
 /**
  * Simple version of LockManager that does nothing
  * @since 1.19
index 8c8c940..f0d5818 100644 (file)
  * @since 1.19
  */
 class LockManagerGroup {
-       /**
-        * @var LockManagerGroup
-        */
-       protected static $instance = null;
+       /** @var Array (domain => LockManager) */
+       protected static $instances = array();
+
+       protected $domain; // string; domain (usually wiki ID)
 
-       /** @var Array of (name => ('class' =>, 'config' =>, 'instance' =>)) */
+       /** @var Array of (name => ('class' => ..., 'config' => ..., 'instance' => ...)) */
        protected $managers = array();
 
-       protected function __construct() {}
+       /**
+        * @param $domain string Domain (usually wiki ID)
+        */
+       protected function __construct( $domain ) {
+               $this->domain = $domain;
+       }
 
        /**
+        * @param $domain string Domain (usually wiki ID)
         * @return LockManagerGroup
         */
-       public static function singleton() {
-               if ( self::$instance == null ) {
-                       self::$instance = new self();
-                       self::$instance->initFromGlobals();
+       public static function singleton( $domain = false ) {
+               $domain = ( $domain === false ) ? wfWikiID() : $domain;
+               if ( !isset( self::$instances[$domain] ) ) {
+                       self::$instances[$domain] = new self( $domain );
+                       self::$instances[$domain]->initFromGlobals();
                }
-               return self::$instance;
+               return self::$instances[$domain];
        }
 
        /**
-        * Destroy the singleton instance, so that a new one will be created next
-        * time singleton() is called.
+        * Destroy the singleton instances
+        *
+        * @return void
         */
-       public static function destroySingleton() {
-               self::$instance = null;
+       public static function destroySingletons() {
+               self::$instances = array();
        }
 
        /**
@@ -78,6 +86,7 @@ class LockManagerGroup {
         */
        protected function register( array $configs ) {
                foreach ( $configs as $config ) {
+                       $config['domain'] = $this->domain;
                        if ( !isset( $config['name'] ) ) {
                                throw new MWException( "Cannot register a lock manager with no name." );
                        }
@@ -115,6 +124,21 @@ class LockManagerGroup {
                return $this->managers[$name]['instance'];
        }
 
+       /**
+        * Get the config array for a lock manager object with a given name
+        *
+        * @param $name string
+        * @return Array
+        * @throws MWException
+        */
+       public function config( $name ) {
+               if ( !isset( $this->managers[$name] ) ) {
+                       throw new MWException( "No lock manager defined with the name `$name`." );
+               }
+               $class = $this->managers[$name]['class'];
+               return array( 'class' => $class ) + $this->managers[$name]['config'];
+       }
+
        /**
         * Get the default lock manager configured for the site.
         * Returns NullLockManager if no lock manager could be found.
index 610fc47..099f11d 100644 (file)
@@ -50,7 +50,6 @@ class MemcLockManager extends QuorumLockManager {
 
        protected $lockExpiry; // integer; maximum time locks can be held
        protected $session = ''; // string; random SHA-1 UUID
-       protected $wikiId = ''; // string
 
        /**
         * Construct a new instance from configuration.
@@ -61,7 +60,6 @@ class MemcLockManager extends QuorumLockManager {
         *                    each having an odd-numbered list of server names (peers) as values.
         *   - memcConfig   : Configuration array for ObjectCache::newFromParams. [optional]
         *                    If set, this must use one of the memcached classes.
-        *   - wikiId       : Wiki ID string that all resources are relative to. [optional]
         *
         * @param Array $config
         * @throws MWException
@@ -88,8 +86,6 @@ class MemcLockManager extends QuorumLockManager {
                        }
                }
 
-               $this->wikiId = isset( $config['wikiId'] ) ? $config['wikiId'] : wfWikiID();
-
                $met = ini_get( 'max_execution_time' ); // this is 0 in CLI mode
                $this->lockExpiry = $met ? 2*(int)$met : 2*3600;
 
@@ -252,9 +248,7 @@ class MemcLockManager extends QuorumLockManager {
         * @return string
         */
        protected function recordKeyForPath( $path ) {
-               $hash = LockManager::sha1Base36( $path );
-               list( $db, $prefix ) = wfSplitWikiID( $this->wikiId );
-               return wfForeignMemcKey( $db, $prefix, __CLASS__, 'locks', $hash );
+               return implode( ':', array( __CLASS__, 'locks', $this->sha1Base36Absolute( $path ) ) );
        }
 
        /**
diff --git a/includes/filebackend/lockmanager/QuorumLockManager.php b/includes/filebackend/lockmanager/QuorumLockManager.php
new file mode 100644 (file)
index 0000000..76a3ad6
--- /dev/null
@@ -0,0 +1,232 @@
+<?php
+/**
+ * Version of LockManager that uses a quorum from peer servers for locks.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ * @file
+ * @ingroup LockManager
+ */
+
+/**
+ * Version of LockManager that uses a quorum from peer servers for locks.
+ * The resource space can also be sharded into separate peer groups.
+ *
+ * @ingroup LockManager
+ * @since 1.20
+ */
+abstract class QuorumLockManager extends LockManager {
+       /** @var Array Map of bucket indexes to peer server lists */
+       protected $srvsByBucket = array(); // (bucket index => (lsrv1, lsrv2, ...))
+
+       /**
+        * @see LockManager::doLock()
+        * @param $paths array
+        * @param $type int
+        * @return Status
+        */
+       final protected function doLock( array $paths, $type ) {
+               $status = Status::newGood();
+
+               $pathsToLock = array(); // (bucket => paths)
+               // Get locks that need to be acquired (buckets => locks)...
+               foreach ( $paths as $path ) {
+                       if ( isset( $this->locksHeld[$path][$type] ) ) {
+                               ++$this->locksHeld[$path][$type];
+                       } elseif ( isset( $this->locksHeld[$path][self::LOCK_EX] ) ) {
+                               $this->locksHeld[$path][$type] = 1;
+                       } else {
+                               $bucket = $this->getBucketFromPath( $path );
+                               $pathsToLock[$bucket][] = $path;
+                       }
+               }
+
+               $lockedPaths = array(); // files locked in this attempt
+               // Attempt to acquire these locks...
+               foreach ( $pathsToLock as $bucket => $paths ) {
+                       // Try to acquire the locks for this bucket
+                       $status->merge( $this->doLockingRequestBucket( $bucket, $paths, $type ) );
+                       if ( !$status->isOK() ) {
+                               $status->merge( $this->doUnlock( $lockedPaths, $type ) );
+                               return $status;
+                       }
+                       // Record these locks as active
+                       foreach ( $paths as $path ) {
+                               $this->locksHeld[$path][$type] = 1; // locked
+                       }
+                       // Keep track of what locks were made in this attempt
+                       $lockedPaths = array_merge( $lockedPaths, $paths );
+               }
+
+               return $status;
+       }
+
+       /**
+        * @see LockManager::doUnlock()
+        * @param $paths array
+        * @param $type int
+        * @return Status
+        */
+       final protected function doUnlock( array $paths, $type ) {
+               $status = Status::newGood();
+
+               $pathsToUnlock = array();
+               foreach ( $paths as $path ) {
+                       if ( !isset( $this->locksHeld[$path][$type] ) ) {
+                               $status->warning( 'lockmanager-notlocked', $path );
+                       } else {
+                               --$this->locksHeld[$path][$type];
+                               // Reference count the locks held and release locks when zero
+                               if ( $this->locksHeld[$path][$type] <= 0 ) {
+                                       unset( $this->locksHeld[$path][$type] );
+                                       $bucket = $this->getBucketFromPath( $path );
+                                       $pathsToUnlock[$bucket][] = $path;
+                               }
+                               if ( !count( $this->locksHeld[$path] ) ) {
+                                       unset( $this->locksHeld[$path] ); // no SH or EX locks left for key
+                               }
+                       }
+               }
+
+               // Remove these specific locks if possible, or at least release
+               // all locks once this process is currently not holding any locks.
+               foreach ( $pathsToUnlock as $bucket => $paths ) {
+                       $status->merge( $this->doUnlockingRequestBucket( $bucket, $paths, $type ) );
+               }
+               if ( !count( $this->locksHeld ) ) {
+                       $status->merge( $this->releaseAllLocks() );
+               }
+
+               return $status;
+       }
+
+       /**
+        * Attempt to acquire locks with the peers for a bucket.
+        * This is all or nothing; if any key is locked then this totally fails.
+        *
+        * @param $bucket integer
+        * @param $paths Array List of resource keys to lock
+        * @param $type integer LockManager::LOCK_EX or LockManager::LOCK_SH
+        * @return Status
+        */
+       final protected function doLockingRequestBucket( $bucket, array $paths, $type ) {
+               $status = Status::newGood();
+
+               $yesVotes = 0; // locks made on trustable servers
+               $votesLeft = count( $this->srvsByBucket[$bucket] ); // remaining peers
+               $quorum = floor( $votesLeft/2 + 1 ); // simple majority
+               // Get votes for each peer, in order, until we have enough...
+               foreach ( $this->srvsByBucket[$bucket] as $lockSrv ) {
+                       if ( !$this->isServerUp( $lockSrv ) ) {
+                               --$votesLeft;
+                               $status->warning( 'lockmanager-fail-svr-acquire', $lockSrv );
+                               continue; // server down?
+                       }
+                       // Attempt to acquire the lock on this peer
+                       $status->merge( $this->getLocksOnServer( $lockSrv, $paths, $type ) );
+                       if ( !$status->isOK() ) {
+                               return $status; // vetoed; resource locked
+                       }
+                       ++$yesVotes; // success for this peer
+                       if ( $yesVotes >= $quorum ) {
+                               return $status; // lock obtained
+                       }
+                       --$votesLeft;
+                       $votesNeeded = $quorum - $yesVotes;
+                       if ( $votesNeeded > $votesLeft ) {
+                               break; // short-circuit
+                       }
+               }
+               // At this point, we must not have met the quorum
+               $status->setResult( false );
+
+               return $status;
+       }
+
+       /**
+        * Attempt to release locks with the peers for a bucket
+        *
+        * @param $bucket integer
+        * @param $paths Array List of resource keys to lock
+        * @param $type integer LockManager::LOCK_EX or LockManager::LOCK_SH
+        * @return Status
+        */
+       final protected function doUnlockingRequestBucket( $bucket, array $paths, $type ) {
+               $status = Status::newGood();
+
+               foreach ( $this->srvsByBucket[$bucket] as $lockSrv ) {
+                       if ( !$this->isServerUp( $lockSrv ) ) {
+                               $status->fatal( 'lockmanager-fail-svr-release', $lockSrv );
+                       // Attempt to release the lock on this peer
+                       } else {
+                               $status->merge( $this->freeLocksOnServer( $lockSrv, $paths, $type ) );
+                       }
+               }
+
+               return $status;
+       }
+
+       /**
+        * Get the bucket for resource path.
+        * This should avoid throwing any exceptions.
+        *
+        * @param $path string
+        * @return integer
+        */
+       protected function getBucketFromPath( $path ) {
+               $prefix = substr( sha1( $path ), 0, 2 ); // first 2 hex chars (8 bits)
+               return (int)base_convert( $prefix, 16, 10 ) % count( $this->srvsByBucket );
+       }
+
+       /**
+        * Check if a lock server is up
+        *
+        * @param $lockSrv string
+        * @return bool
+        */
+       abstract protected function isServerUp( $lockSrv );
+
+       /**
+        * Get a connection to a lock server and acquire locks on $paths
+        *
+        * @param $lockSrv string
+        * @param $paths array
+        * @param $type integer
+        * @return Status
+        */
+       abstract protected function getLocksOnServer( $lockSrv, array $paths, $type );
+
+       /**
+        * Get a connection to a lock server and release locks on $paths.
+        *
+        * Subclasses must effectively implement this or releaseAllLocks().
+        *
+        * @param $lockSrv string
+        * @param $paths array
+        * @param $type integer
+        * @return Status
+        */
+       abstract protected function freeLocksOnServer( $lockSrv, array $paths, $type );
+
+       /**
+        * Release all locks that this session is holding.
+        *
+        * Subclasses must effectively implement this or freeLocksOnServer().
+        *
+        * @return Status
+        */
+       abstract protected function releaseAllLocks();
+}
index 635cb95..e49f37d 100644 (file)
@@ -46,6 +46,9 @@ class FSRepo extends FileRepo {
                        $thumbDir = isset( $info['thumbDir'] )
                                ? $info['thumbDir']
                                : "{$directory}/thumb";
+                       $transcodedDir = isset( $info['transcodedDir'] )
+                               ? $info['transcodedDir']
+                               : "{$directory}/transcoded";
                        $fileMode = isset( $info['fileMode'] )
                                ? $info['fileMode']
                                : 0644;
@@ -59,6 +62,7 @@ class FSRepo extends FileRepo {
                                        "{$repoName}-public"  => "{$directory}",
                                        "{$repoName}-temp"    => "{$directory}/temp",
                                        "{$repoName}-thumb"   => $thumbDir,
+                                       "{$repoName}-transcoded"   => $transcodedDir,
                                        "{$repoName}-deleted" => $deletedDir
                                ),
                                'fileMode'       => $fileMode,
index 4cc4fde..05e71d4 100644 (file)
@@ -120,7 +120,7 @@ class FileRepo {
                $this->isPrivate = !empty( $info['isPrivate'] );
                // Give defaults for the basic zones...
                $this->zones = isset( $info['zones'] ) ? $info['zones'] : array();
-               foreach ( array( 'public', 'thumb', 'temp', 'deleted' ) as $zone ) {
+               foreach ( array( 'public', 'thumb', 'transcoded', 'temp', 'deleted' ) as $zone ) {
                        if ( !isset( $this->zones[$zone]['container'] ) ) {
                                $this->zones[$zone]['container'] = "{$this->name}-{$zone}";
                        }
@@ -204,7 +204,7 @@ class FileRepo {
         * @return String or false
         */
        public function getZoneUrl( $zone, $ext = null ) {
-               if ( in_array( $zone, array( 'public', 'temp', 'thumb' ) ) ) { // standard public zones
+               if ( in_array( $zone, array( 'public', 'temp', 'thumb', 'transcoded' ) ) ) { // standard public zones
                        if ( $ext !== null && isset( $this->zones[$zone]['urlsByExt'][$ext] ) ) {
                                return $this->zones[$zone]['urlsByExt'][$ext]; // custom URL for extension/zone
                        } elseif ( isset( $this->zones[$zone]['url'] ) ) {
@@ -220,6 +220,8 @@ class FileRepo {
                                return false; // no public URL
                        case 'thumb':
                                return $this->thumbUrl;
+                       case 'transcoded':
+                               return "{$this->url}/transcoded";
                        default:
                                return false;
                }
@@ -240,7 +242,7 @@ class FileRepo {
         */
        public function getZoneHandlerUrl( $zone ) {
                if ( isset( $this->zones[$zone]['handlerUrl'] )
-                       && in_array( $zone, array( 'public', 'temp', 'thumb' ) ) )
+                       && in_array( $zone, array( 'public', 'temp', 'thumb', 'transcoded' ) ) )
                {
                        return $this->zones[$zone]['handlerUrl'];
                }
@@ -955,7 +957,7 @@ class FileRepo {
                $hashPath   = $this->getHashPath( $originalName );
                $dstRel     = "{$hashPath}{$date}!{$originalName}";
                $dstUrlRel  = $hashPath . $date . '!' . rawurlencode( $originalName );
-               $virtualUrl = $this->getVirtualUrl( 'temp' )  . '/' . $dstUrlRel;
+               $virtualUrl = $this->getVirtualUrl( 'temp' ) . '/' . $dstUrlRel;
 
                $result = $this->quickImport( $srcPath, $virtualUrl );
                $result->value = $virtualUrl;
@@ -1105,7 +1107,7 @@ class FileRepo {
                        if ( !$this->initDirectory( $dstDir )->isOK() ) {
                                return $this->newFatal( 'directorycreateerror', $dstDir );
                        }
-                       if ( !$this->initDirectory($archiveDir )->isOK() ) {
+                       if ( !$this->initDirectory( $archiveDir )->isOK() ) {
                                return $this->newFatal( 'directorycreateerror', $archiveDir );
                        }
 
@@ -1670,10 +1672,17 @@ class FileRepo {
                                        'directory' => ( $this->zones['thumb']['directory'] == '' )
                                                ? 'temp'
                                                : $this->zones['thumb']['directory'] . '/temp'
+                               ),
+                               'transcoded'  => array(
+                                       'container' => $this->zones['transcoded']['container'],
+                                       'directory' => ( $this->zones['transcoded']['directory'] == '' )
+                                               ? 'temp'
+                                               : $this->zones['transcoded']['directory'] . '/temp'
                                )
                        ),
                        'url'        => $this->getZoneUrl( 'temp' ),
                        'thumbUrl'   => $this->getZoneUrl( 'thumb' ) . '/temp',
+                       'transcodedUrl'   => $this->getZoneUrl( 'transcoded' ) . '/temp',
                        'hashLevels' => $this->hashLevels // performance
                ) );
        }
index 7697e4e..98a21f7 100644 (file)
@@ -267,14 +267,14 @@ class ForeignAPIRepo extends FileRepo {
                $sizekey = "$width:$height:$params";
 
                /* Get the array of urls that we already know */
-               $knownThumbUrls = $wgMemc->get($key);
+               $knownThumbUrls = $wgMemc->get( $key );
                if( !$knownThumbUrls ) {
                        /* No knownThumbUrls for this file */
                        $knownThumbUrls = array();
                } else {
                        if( isset( $knownThumbUrls[$sizekey] ) ) {
                                wfDebug( __METHOD__ . ': Got thumburl from local cache: ' .
-                                       "{$knownThumbUrls[$sizekey]} \n");
+                                       "{$knownThumbUrls[$sizekey]} \n" );
                                return $knownThumbUrls[$sizekey];
                        }
                        /* This size is not yet known */
@@ -294,9 +294,9 @@ class ForeignAPIRepo extends FileRepo {
                        wfDebug( __METHOD__ . " The deduced filename $fileName is not safe\n" );
                        return false;
                }
-               $localPath =  $this->getZonePath( 'thumb' ) . "/" . $this->getHashPath( $name ) . $name;
+               $localPath = $this->getZonePath( 'thumb' ) . "/" . $this->getHashPath( $name ) . $name;
                $localFilename = $localPath . "/" . $fileName;
-               $localUrl =  $this->getZoneUrl( 'thumb' ) . "/" . $this->getHashPath( $name ) . rawurlencode( $name ) . "/" . rawurlencode( $fileName );
+               $localUrl = $this->getZoneUrl( 'thumb' ) . "/" . $this->getHashPath( $name ) . rawurlencode( $name ) . "/" . rawurlencode( $fileName );
 
                if( $backend->fileExists( array( 'src' => $localFilename ) )
                        && isset( $metadata['timestamp'] ) )
index 118e981..0fbaeef 100644 (file)
@@ -212,8 +212,8 @@ class LocalRepo extends FileRepo {
                $dbr = $this->getSlaveDB();
                $id = $dbr->selectField(
                        'page', // Table
-                       'page_id',  //Field
-                       array(  //Conditions
+                       'page_id', //Field
+                       array( //Conditions
                                'page_namespace' => $title->getNamespace(),
                                'page_title' => $title->getDBkey(),
                        ),
@@ -323,4 +323,3 @@ class LocalRepo extends FileRepo {
                }
        }
 }
-
index f9e5759..1f5ae91 100644 (file)
@@ -131,7 +131,7 @@ class RepoGroup {
                        $time = isset( $options['time'] ) ? $options['time'] : '';
                        $dbkey = $title->getDBkey();
                        if ( isset( $this->cache[$dbkey][$time] ) ) {
-                               wfDebug( __METHOD__.": got File:$dbkey from process cache\n" );
+                               wfDebug( __METHOD__ . ": got File:$dbkey from process cache\n" );
                                # Move it to the end of the list so that we can delete the LRU entry later
                                $this->pingCache( $dbkey );
                                # Return the entry
@@ -388,12 +388,12 @@ class RepoGroup {
         */
        function splitVirtualUrl( $url ) {
                if ( substr( $url, 0, 9 ) != 'mwrepo://' ) {
-                       throw new MWException( __METHOD__.': unknown protocol' );
+                       throw new MWException( __METHOD__ . ': unknown protocol' );
                }
 
                $bits = explode( '/', substr( $url, 9 ), 3 );
                if ( count( $bits ) != 3 ) {
-                       throw new MWException( __METHOD__.": invalid mwrepo URL: $url" );
+                       throw new MWException( __METHOD__ . ": invalid mwrepo URL: $url" );
                }
                return $bits;
        }
@@ -433,7 +433,7 @@ class RepoGroup {
                while ( count( $this->cache ) >= self::MAX_CACHE_SIZE ) {
                        reset( $this->cache );
                        $key = key( $this->cache );
-                       wfDebug( __METHOD__.": evicting $key\n" );
+                       wfDebug( __METHOD__ . ": evicting $key\n" );
                        unset( $this->cache[$key] );
                }
        }
index e1a8547..3f78619 100644 (file)
@@ -68,7 +68,7 @@ class ArchivedFile {
         * @param int $id
         * @param string $key
         */
-       function __construct( $title, $id=0, $key='' ) {
+       function __construct( $title, $id = 0, $key = '' ) {
                $this->id = -1;
                $this->title = false;
                $this->name = false;
@@ -95,11 +95,11 @@ class ArchivedFile {
                        $this->name = $title->getDBkey();
                }
 
-               if ($id) {
+               if ( $id ) {
                        $this->id = $id;
                }
 
-               if ($key) {
+               if ( $key ) {
                        $this->key = $key;
                }
 
@@ -130,37 +130,19 @@ class ArchivedFile {
                        $conds['fa_name'] = $this->title->getDBkey();
                }
 
-               if( !count($conds)) {
+               if( !count( $conds ) ) {
                        throw new MWException( "No specific information for retrieving archived file" );
                }
 
                if( !$this->title || $this->title->getNamespace() == NS_FILE ) {
                        $this->dataLoaded = true; // set it here, to have also true on miss
                        $dbr = wfGetDB( DB_SLAVE );
-                       $row = $dbr->selectRow( 'filearchive',
-                               array(
-                                       'fa_id',
-                                       'fa_name',
-                                       'fa_archive_name',
-                                       'fa_storage_key',
-                                       'fa_storage_group',
-                                       'fa_size',
-                                       'fa_bits',
-                                       'fa_width',
-                                       'fa_height',
-                                       'fa_metadata',
-                                       'fa_media_type',
-                                       'fa_major_mime',
-                                       'fa_minor_mime',
-                                       'fa_description',
-                                       'fa_user',
-                                       'fa_user_text',
-                                       'fa_timestamp',
-                                       'fa_deleted',
-                                       'fa_sha1' ),
+                       $row = $dbr->selectRow(
+                               'filearchive',
+                               self::selectFields(),
                                $conds,
                                __METHOD__,
-                               array( 'ORDER BY' => 'fa_timestamp DESC')
+                               array( 'ORDER BY' => 'fa_timestamp DESC' )
                        );
                        if ( !$row ) {
                                // this revision does not exist?
@@ -190,6 +172,34 @@ class ArchivedFile {
                return $file;
        }
 
+       /**
+        * Fields in the filearchive table
+        * @return array
+        */
+       static function selectFields() {
+               return array(
+                       'fa_id',
+                       'fa_name',
+                       'fa_archive_name',
+                       'fa_storage_key',
+                       'fa_storage_group',
+                       'fa_size',
+                       'fa_bits',
+                       'fa_width',
+                       'fa_height',
+                       'fa_metadata',
+                       'fa_media_type',
+                       'fa_major_mime',
+                       'fa_minor_mime',
+                       'fa_description',
+                       'fa_user',
+                       'fa_user_text',
+                       'fa_timestamp',
+                       'fa_deleted',
+                       'fa_sha1',
+               );
+       }
+
        /**
         * Load ArchivedFile object fields from a DB row.
         *
@@ -197,7 +207,7 @@ class ArchivedFile {
         * @since 1.21
         */
        public function loadFromRow( $row ) {
-               $this->id = intval($row->fa_id);
+               $this->id = intval( $row->fa_id );
                $this->name = $row->fa_name;
                $this->archive_name = $row->fa_archive_name;
                $this->group = $row->fa_storage_group;
index e4e49f5..f371115 100644 (file)
@@ -40,7 +40,7 @@
  * never name a file class explictly outside of the repo class. Instead use the
  * repo's factory functions to generate file objects, for example:
  *
- * RepoGroup::singleton()->getLocalRepo()->newFile($title);
+ * RepoGroup::singleton()->getLocalRepo()->newFile( $title );
  *
  * The convenience functions wfLocalFile() and wfFindFile() should be sufficient
  * in most cases.
@@ -54,7 +54,7 @@ abstract class File {
        const DELETED_RESTRICTED = 8;
 
        /** Force rendering in the current process */
-       const RENDER_NOW   = 1;
+       const RENDER_NOW = 1;
        /**
         * Force rendering even if thumbnail already exist and using RENDER_NOW
         * I.e. you have to pass both flags: File::RENDER_NOW | File::RENDER_FORCE
@@ -348,7 +348,7 @@ abstract class File {
                        if ( $this->canRender() ) {
                                return $this->createThumb( $this->getWidth() );
                        } else {
-                               wfDebug( __METHOD__.': supposed to render ' . $this->getName() .
+                               wfDebug( __METHOD__ . ': supposed to render ' . $this->getName() .
                                        ' (' . $this->getMimeType() . "), but can't!\n" );
                                return $this->getURL(); #hm... return NULL?
                        }
@@ -663,13 +663,13 @@ abstract class File {
                if ( $this->allowInlineDisplay() ) {
                        return true;
                }
-               if ($this->isTrustedFile()) {
+               if ( $this->isTrustedFile() ) {
                        return true;
                }
 
                $type = $this->getMediaType();
                $mime = $this->getMimeType();
-               #wfDebug("LocalFile::isSafeFile: type= $type, mime= $mime\n");
+               #wfDebug( "LocalFile::isSafeFile: type= $type, mime= $mime\n" );
 
                if ( !$type || $type === MEDIATYPE_UNKNOWN ) {
                        return false; #unknown type, not trusted
@@ -903,7 +903,7 @@ abstract class File {
                                // Clean up broken thumbnails as needed
                                $this->migrateThumbFile( $thumbName );
                                // Check if an up-to-date thumbnail already exists...
-                               wfDebug( __METHOD__.": Doing stat for $thumbPath\n" );
+                               wfDebug( __METHOD__ . ": Doing stat for $thumbPath\n" );
                                if ( !( $flags & self::RENDER_FORCE ) && $this->repo->fileExists( $thumbPath ) ) {
                                        $timestamp = $this->repo->getFileTimestamp( $thumbPath );
                                        if ( $timestamp !== false && $timestamp >= $wgThumbnailEpoch ) {
@@ -1247,6 +1247,18 @@ abstract class File {
                return $this->repo->getZonePath( 'thumb' ) . '/' . $this->getThumbRel( $suffix );
        }
 
+       /**
+        * Get the path of the transcoded directory, or a particular file if $suffix is specified
+        *
+        * @param $suffix bool|string if not false, the name of a media file
+        *
+        * @return string
+        */
+       function getTranscodedPath( $suffix = false ) {
+               $this->assertRepoDefined();
+               return $this->repo->getZonePath( 'transcoded' ) . '/' . $this->getThumbRel( $suffix );
+       }
+
        /**
         * Get the URL of the archive directory, or a particular file if $suffix is specified
         *
@@ -1288,22 +1300,45 @@ abstract class File {
        }
 
        /**
-        * Get the URL of the thumbnail directory, or a particular file if $suffix is specified
+        * Get the URL of the zone directory, or a particular file if $suffix is specified
         *
-        * @param $suffix bool|string if not false, the name of a thumbnail file
+        * @param $zone string name of requested zone
+        * @param $suffix bool|string if not false, the name of a file in zone
         *
         * @return string path
         */
-       function getThumbUrl( $suffix = false ) {
+       function getZoneUrl( $zone, $suffix = false ) {
                $this->assertRepoDefined();
                $ext = $this->getExtension();
-               $path = $this->repo->getZoneUrl( 'thumb', $ext ) . '/' . $this->getUrlRel();
+               $path = $this->repo->getZoneUrl( $zone, $ext ) . '/' . $this->getUrlRel();
                if ( $suffix !== false ) {
                        $path .= '/' . rawurlencode( $suffix );
                }
                return $path;
        }
 
+       /**
+        * Get the URL of the thumbnail directory, or a particular file if $suffix is specified
+        *
+        * @param $suffix bool|string if not false, the name of a thumbnail file
+        *
+        * @return string path
+        */
+       function getThumbUrl( $suffix = false ) {
+               return $this->getZoneUrl( 'thumb', $suffix );
+       }
+
+       /**
+        * Get the URL of the transcoded directory, or a particular file if $suffix is specified
+        *
+        * @param $suffix bool|string if not false, the name of a media file
+        *
+        * @return string path
+        */
+       function getTranscodedUrl( $suffix = false ) {
+               return $this->getZoneUrl( 'transcoded', $suffix );
+       }
+
        /**
         * Get the public zone virtual URL for a current version source file
         *
@@ -1366,7 +1401,7 @@ abstract class File {
         * @throws MWException
         */
        function readOnlyError() {
-               throw new MWException( get_class($this) . ': write operations are not supported' );
+               throw new MWException( get_class( $this ) . ': write operations are not supported' );
        }
 
        /**
@@ -1500,9 +1535,9 @@ abstract class File {
         * @param $target Title New file name
         * @return FileRepoStatus object.
         */
-        function move( $target ) {
+       function move( $target ) {
                $this->readOnlyError();
-        }
+       }
 
        /**
         * Delete all versions of the file.
@@ -1627,15 +1662,15 @@ abstract class File {
                $renderUrl = $this->repo->getDescriptionRenderUrl( $this->getName(), $wgLang->getCode() );
                if ( $renderUrl ) {
                        if ( $this->repo->descriptionCacheExpiry > 0 ) {
-                               wfDebug("Attempting to get the description from cache...");
+                               wfDebug( "Attempting to get the description from cache..." );
                                $key = $this->repo->getLocalCacheKey( 'RemoteFileDescription', 'url', $wgLang->getCode(),
                                                                        $this->getName() );
-                               $obj = $wgMemc->get($key);
-                               if ($obj) {
-                                       wfDebug("success!\n");
+                               $obj = $wgMemc->get( $key );
+                               if ( $obj ) {
+                                       wfDebug( "success!\n" );
                                        return $obj;
                                }
-                               wfDebug("miss\n");
+                               wfDebug( "miss\n" );
                        }
                        wfDebug( "Fetching shared description from $renderUrl\n" );
                        $res = Http::get( $renderUrl );
@@ -1721,7 +1756,7 @@ abstract class File {
         * @return array
         */
        static function getPropsFromPath( $path, $ext = true ) {
-               wfDebug( __METHOD__.": Getting file info for $path\n" );
+               wfDebug( __METHOD__ . ": Getting file info for $path\n" );
                wfDeprecated( __METHOD__, '1.19' );
 
                $fsFile = new FSFile( $path );
index 5648261..84e0df6 100644 (file)
@@ -189,7 +189,7 @@ class ForeignAPIFile extends File {
         * @param string $method
         * @return int|null|string
         */
-       public function getUser( $method='text' ) {
+       public function getUser( $method = 'text' ) {
                return isset( $this->mInfo['user'] ) ? strval( $this->mInfo['user'] ) : null;
        }
 
@@ -256,7 +256,7 @@ class ForeignAPIFile extends File {
         */
        function getThumbPath( $suffix = '' ) {
                if ( $this->repo->canCacheThumbs() ) {
-                       $path = $this->repo->getZonePath('thumb') . '/' . $this->getHashPath( $this->getName() );
+                       $path = $this->repo->getZonePath( 'thumb' ) . '/' . $this->getHashPath( $this->getName() );
                        if ( $suffix ) {
                                $path = $path . $suffix . '/';
                        }
@@ -293,7 +293,7 @@ class ForeignAPIFile extends File {
                global $wgMemc, $wgContLang;
 
                $url = $this->repo->getDescriptionRenderUrl( $this->getName(), $wgContLang->getCode() );
-               $key = $this->repo->getLocalCacheKey( 'RemoteFileDescription', 'url', md5($url) );
+               $key = $this->repo->getLocalCacheKey( 'RemoteFileDescription', 'url', md5( $url ) );
 
                $wgMemc->delete( $key );
        }
index c08d192..5acaf04 100644 (file)
@@ -36,7 +36,7 @@ define( 'MW_FILE_VERSION', 9 );
  * never name a file class explictly outside of the repo class. Instead use the
  * repo's factory functions to generate file objects, for example:
  *
- * RepoGroup::singleton()->getLocalRepo()->newFile($title);
+ * RepoGroup::singleton()->getLocalRepo()->newFile( $title );
  *
  * The convenience functions wfLocalFile() and wfFindFile() should be sufficient
  * in most cases.
@@ -398,7 +398,7 @@ class LocalFile extends File {
 
                // Sanity check prefix once
                if ( substr( key( $array ), 0, $prefixLength ) !== $prefix ) {
-                       throw new MWException( __METHOD__ .  ': incorrect $prefix parameter' );
+                       throw new MWException( __METHOD__ . ': incorrect $prefix parameter' );
                }
 
                $decoded = array();
@@ -737,7 +737,7 @@ class LocalFile extends File {
                        // Directory where file should be
                        // This happened occasionally due to broken migration code in 1.5
                        // Rename to broken-*
-                       for ( $i = 0; $i < 100 ; $i++ ) {
+                       for ( $i = 0; $i < 100; $i++ ) {
                                $broken = $this->repo->getZonePath( 'public' ) . "/broken-$i-$thumbName";
                                if ( !file_exists( $broken ) ) {
                                        rename( $thumbPath, $broken );
@@ -901,7 +901,7 @@ class LocalFile extends File {
        protected function purgeThumbList( $dir, $files ) {
                $fileListDebug = strtr(
                        var_export( $files, true ),
-                       array("\n"=>'')
+                       array( "\n" => '' )
                );
                wfDebug( __METHOD__ . ": $fileListDebug\n" );
 
@@ -1285,7 +1285,7 @@ class LocalFile extends File {
                                $log->getRcComment(),
                                false
                        );
-                       if (!is_null($nullRevision)) {
+                       if ( !is_null( $nullRevision ) ) {
                                $nullRevision->insertOn( $dbw );
 
                                wfRunHooks( 'NewRevisionFromEditComplete', array( $wikiPage, $nullRevision, $latest, $user ) );
@@ -2128,7 +2128,9 @@ class LocalFileRestoreBatch {
                        $conditions[] = 'fa_id IN (' . $dbw->makeList( $this->ids ) . ')';
                }
 
-               $result = $dbw->select( 'filearchive', '*',
+               $result = $dbw->select(
+                       'filearchive',
+                       ArchivedFile::selectFields(),
                        $conditions,
                        __METHOD__,
                        array( 'ORDER BY' => 'fa_timestamp DESC' )
index 3180835..4f27c8d 100644 (file)
@@ -42,7 +42,7 @@ class OldLocalFile extends LocalFile {
        static function newFromTitle( $title, $repo, $time = null ) {
                # The null default value is only here to avoid an E_STRICT
                if ( $time === null ) {
-                       throw new MWException( __METHOD__.' got null for $time parameter' );
+                       throw new MWException( __METHOD__ . ' got null for $time parameter' );
                }
                return new self( $title, $repo, $time, null );
        }
@@ -132,7 +132,7 @@ class OldLocalFile extends LocalFile {
                $this->requestedTime = $time;
                $this->archive_name = $archiveName;
                if ( is_null( $time ) && is_null( $archiveName ) ) {
-                       throw new MWException( __METHOD__.': must specify at least one of $time or $archiveName' );
+                       throw new MWException( __METHOD__ . ': must specify at least one of $time or $archiveName' );
                }
        }
 
@@ -164,7 +164,7 @@ class OldLocalFile extends LocalFile {
         * @return bool
         */
        function isVisible() {
-               return $this->exists() && !$this->isDeleted(File::DELETED_FILE);
+               return $this->exists() && !$this->isDeleted( File::DELETED_FILE );
        }
 
        function loadFromDB() {
@@ -255,7 +255,7 @@ class OldLocalFile extends LocalFile {
 
                # Don't destroy file info of missing files
                if ( !$this->fileExists ) {
-                       wfDebug( __METHOD__.": file does not exist, aborting\n" );
+                       wfDebug( __METHOD__ . ": file does not exist, aborting\n" );
                        wfProfileOut( __METHOD__ );
                        return;
                }
@@ -263,7 +263,7 @@ class OldLocalFile extends LocalFile {
                $dbw = $this->repo->getMasterDB();
                list( $major, $minor ) = self::splitMime( $this->mime );
 
-               wfDebug(__METHOD__.': upgrading '.$this->archive_name." to the current schema\n");
+               wfDebug( __METHOD__ . ': upgrading ' . $this->archive_name . " to the current schema\n" );
                $dbw->update( 'oldimage',
                        array(
                                'oi_size'       => $this->size, // sanity
index 698d1eb..9a7f653 100644 (file)
@@ -71,7 +71,7 @@ class UnregisteredLocalFile extends File {
         */
        function __construct( $title = false, $repo = false, $path = false, $mime = false ) {
                if ( !( $title && $repo ) && !$path ) {
-                       throw new MWException( __METHOD__.': not enough parameters, must specify title and repo, or a full path' );
+                       throw new MWException( __METHOD__ . ': not enough parameters, must specify title and repo, or a full path' );
                }
                if ( $title instanceof Title ) {
                        $this->title = File::normalizeTitle( $title, 'exception' );
index 38b4a82..75e55f1 100644 (file)
@@ -193,7 +193,7 @@ class CliInstaller extends Installer {
 
        public function envCheckPath( ) {
                if ( !$this->specifiedScriptPath ) {
-                       $this->showMessage( 'config-no-cli-uri', $this->getVar("wgScriptPath") );
+                       $this->showMessage( 'config-no-cli-uri', $this->getVar( "wgScriptPath" ) );
                }
                return parent::envCheckPath();
        }
index f27165d..10d23fb 100644 (file)
@@ -240,7 +240,7 @@ abstract class DatabaseInstaller {
                if ( $status->isOK() ) {
                        $status->value->setSchemaVars( $this->getSchemaVars() );
                } else {
-                       throw new MWException( __METHOD__.': unexpected DB connection error' );
+                       throw new MWException( __METHOD__ . ': unexpected DB connection error' );
                }
        }
 
@@ -252,7 +252,7 @@ abstract class DatabaseInstaller {
        public function enableLB() {
                $status = $this->getConnection();
                if ( !$status->isOK() ) {
-                       throw new MWException( __METHOD__.': unexpected DB connection error' );
+                       throw new MWException( __METHOD__ . ': unexpected DB connection error' );
                }
                LBFactory::setInstance( new LBFactory_Single( array(
                        'connection' => $status->value ) ) );
index 9caf168..746cd12 100644 (file)
@@ -451,7 +451,7 @@ abstract class DatabaseUpdater {
                $key = "updatelist-$version-" . time();
                $this->db->insert( 'updatelog',
                        array( 'ul_key' => $key, 'ul_value' => serialize( $updates ) ),
-                        __METHOD__ );
+                       __METHOD__ );
                $this->db->setFlag( DBO_DDLMODE );
        }
 
@@ -633,7 +633,7 @@ abstract class DatabaseUpdater {
                } else {
                        $this->db->sourceFile( $path );
                }
-               $this->output( "done.\n" );
+               $this->output( "done.\n" );
                return true;
        }
 
index 9a389dd..e2fb735 100644 (file)
@@ -44,9 +44,9 @@ class InstallDocFormatter {
                $text = preg_replace( '/^\t\t/m', '::', $text );
                $text = preg_replace( '/^\t/m', ':', $text );
                // turn (bug nnnn) into links
-               $text = preg_replace_callback('/bug (\d+)/', array( $this, 'replaceBugLinks' ), $text );
+               $text = preg_replace_callback( '/bug (\d+)/', array( $this, 'replaceBugLinks' ), $text );
                // add links to manual to every global variable mentioned
-               $text = preg_replace_callback('/(\$wg[a-z0-9_]+)/i', array( $this, 'replaceConfigLinks' ), $text );
+               $text = preg_replace_callback( '/(\$wg[a-z0-9_]+)/i', array( $this, 'replaceConfigLinks' ), $text );
                return $text;
        }
 
index eba8f1b..a0049fe 100644 (file)
@@ -585,7 +585,7 @@ $messages['qqq'] = array(
        'config-title' => 'Parameters:
 * $1 is the version of MediaWiki that is being installed.',
        'config-information' => '{{Identical|Information}}',
-       'config-localsettings-cli-upgrade' => 'Do not translate the <code><code>LocalSettings.php</code></code> and the <code>update.php</code> parts.',
+       'config-localsettings-cli-upgrade' => '{{doc-important|Do not translate the <code>LocalSettings.php</code> and the <code>update.php</code> parts.}}',
        'config-session-error' => 'Parameters:
 * $1 is the error that was encountered with the session.',
        'config-session-expired' => 'Parameters:
@@ -603,10 +603,7 @@ $messages['qqq'] = array(
 * $1 is the version of PHP that has been installed.',
        'config-unicode-pure-php-warning' => 'PECL is the name of a group producing standard pieces of software for PHP, and intl is the name of their library handling some aspects of internationalization.',
        'config-unicode-update-warning' => "ICU is a body producing standard software tools for support of Unicode and other internationalization aspects. This message warns the system administrator installing MediaWiki that the server's software is not up-to-date and MediaWiki will have problems handling some characters.",
-       'config-no-db' => 'Do not translate: <code>./configure --with-mysql</code>.
-<br />
-Do not translate: <code>php5-mysql</code>.
-
+       'config-no-db' => '{{doc-important|Do not translate "<code>./configure --with-mysql</code>" and "<code>php5-mysql</code>".}}
 Parameters:
 * $1 is comma separated list of database types supported by MediaWiki.',
        'config-no-fts3' => 'A "[[:wikipedia:Front and back ends|backend]]" is a system or component that ordinary users don\'t interact with directly and don\'t need to know about, and that is responsible for a distinct task or service - for example, a storage back-end is a generic system for storing data which other applications can use. Possible alternatives for back-end are "system" or "service", or (depending on context and language) even leave it untranslated.',
@@ -632,8 +629,8 @@ Add dir="ltr" to the <nowiki><code></nowiki> for right-to-left languages.',
        'config-no-cli-uri' => 'Parameters:
 * $1 is the default value for scriptpath.',
        'config-no-cli-uploads-check' => 'CLI = [[w:Command-line interface|command-line interface]] (i.e. the installer runs as a command-line script, not using HTML interface via an internet browser)',
-       'config-suhosin-max-value-length' => 'Message shown when PHP parameter <code>suhosin.get.max_value_length</code> is between 0 and 1023 (that max value is hard set in MediaWiki software)
-Do not translate "length" in the first sentence',
+       'config-suhosin-max-value-length' => '{{doc-important|Do not translate "length", "suhosin.get.max_value_length", "php.ini", "$wgResourceLoaderMaxQueryLength" and "LocalSettings.php".}}
+Message shown when PHP parameter <code>suhosin.get.max_value_length</code> is between 0 and 1023 (that max value is hard set in MediaWiki software).',
        'config-db-host-help' => '{{doc-singularthey}}',
        'config-db-host-oracle' => 'TNS = [[:wikipedia:Transparent Network Substrate|Transparent Network Substrate]] (<== wikipedia link)',
        'config-db-wiki-settings' => 'This is more acurate: "Enter identifying or distinguishing data for this wiki" since a MySQL database can host tables of several wikis.',
@@ -678,8 +675,8 @@ If you\'re translating this message to a right-to-left language, consider writin
 * {{msg-mw|config-profile-private}}',
        'config-upload-help' => 'The word "mode" here refers to the access rights given to various user groups when attempting to create and store files and/or subdiretories in the said directory on the server. It also refers to the <code>mode</code> command used to maipulate said right mask under Unix, Linux, and similar operating systems. A less operating-system-centric translation is fine.',
        'config-logo-help' => '',
-       'config-cc-not-chosen' => 'Do not translate the <code>"proceed".</code> part.
-This message refers to a block of HTML being embedded into the installer page. It comes from the Creative Commons Web site. The block is in the English language. It is a scripted license chooser. When an individual license has been selected, it asks you to klick "proceed" so as to return to the MediaWiki installer page.',
+       'config-cc-not-chosen' => '{{doc-important|Do not translate the "<code>proceed</code>" part.}}
+This message refers to a block of HTML being embedded into the installer page. It comes from the Creative Commons Web site. The block is in the English language. It is a scripted license chooser. When an individual license has been selected, it asks you to click "proceed" so as to return to the MediaWiki installer page.',
        'config-memcached-servers' => '{{doc-important|Do not translate "memcached".}}
 {{Identical|Memcached server}}',
        'config-extensions' => '{{Identical|Extension}}',
@@ -1407,7 +1404,9 @@ MediaWiki патрабуе падтрымкі UTF-8 для слушнай пра
        'config-using531' => 'PHP $1 не сумяшчальнае з MediaWiki з-за памылкі ў перадачы парамэтраў па ўказальніку да <code>__call()</code>.
 Абнавіце PHP да вэрсіі 5.3.2 ці болей позьняй, ці адкаціце да вэрсіі 5.3.0 каб гэта выправіць.
 Усталяваньне перарванае.',
-       'config-suhosin-max-value-length' => 'Suhosin усталяваны і абмяжоўвае даўжыню парамэтра GET у $1 {{PLURAL:$1|байт|байты|байтаў}}. ResourceLoader для MediaWiki будзе абходзіць гэтае абмежаваньне, што, аднак, адаб’ецца на хуткадзеяньні. Калі магчыма, варта ўстанавіць <code>suhosin.get.max_value_length</code> роўным 1024 ці больш у <code>php.ini</code>, а таксама ўстанавіць тое ж значэньне для <code>$wgResourceLoaderMaxQueryLength</code> у LocalSettings.php.', # Fuzzy
+       'config-suhosin-max-value-length' => 'Suhosin усталяваны і абмяжоўвае <code>даўжыню</code> парамэтра GET да $1 {{PLURAL:$1|байта|байтаў}}.
+ResourceLoader, складнік MediaWiki, будзе абходзіць гэтае абмежаваньне, што, адаб’ецца на прадукцыйнасьці.
+Калі магчыма, варта ўсталяваць у <code>php.ini</code> <code>suhosin.get.max_value_length</code> роўным 1024 ці больш, а таксама вызначыць тое ж значэньне для <code>$wgResourceLoaderMaxQueryLength</code> у LocalSettings.php.',
        'config-db-type' => 'Тып базы зьвестак:',
        'config-db-host' => 'Хост базы зьвестак:',
        'config-db-host-help' => 'Калі сэрвэр Вашай базы зьвестак знаходзіцца на іншым сэрвэры, увядзіце тут імя хоста ці IP-адрас.
@@ -1491,7 +1490,7 @@ $1
        'config-support-postgres' => '* $1 — вядомая сыстэма базы зьвестак з адкрытым кодам, якая зьяўляецца альтэрнатывай MySQL ([http://www.php.net/manual/en/pgsql.installation.php як кампіляваць PHP з падтрымкай PostgreSQL]). Яна можа ўтрымліваць дробныя памылкі, і не рэкамэндуецца выкарыстоўваць яе для працуючых праектаў.',
        'config-support-sqlite' => '* $1 — невялікая сыстэма базы зьвестак, якая мае вельмі добрую падтрымку. ([http://www.php.net/manual/en/pdo.installation.php як кампіляваць PHP з падтрымкай SQLite], выкарыстоўвае PDO)',
        'config-support-oracle' => '* $1 зьяўляецца камэрцыйнай прафэсійнай базай зьвестак. ([http://www.php.net/manual/en/oci8.installation.php Як скампіляваць PHP з падтрымкай OCI8])',
-       'config-support-ibm_db2' => '* $1 â\80\94 Ð±Ð°Ð·Ð° Ð·Ñ\8cвеÑ\81Ñ\82ак ÐºÐ°Ð¼Ñ\8dÑ\80Ñ\86Ñ\8bйнага Ð¿Ñ\80адпÑ\80Ñ\8bемÑ\81Ñ\82ва.', # Fuzzy
+       'config-support-ibm_db2' => '* $1 â\80\94 Ð±Ð°Ð·Ð° Ð·Ñ\8cвеÑ\81Ñ\82ак Ð¼Ð°Ñ\88Ñ\82абÑ\83 Ð¿Ñ\80адпÑ\80Ñ\8bемÑ\81Ñ\82ва. ([http://www.php.net/manual/en/ibm-db2.installation.php Ð¯Ðº Ñ\81кампÑ\96лÑ\8fваÑ\86Ñ\8c PHP Ð· Ð¿Ð°Ð´Ñ\82Ñ\80Ñ\8bмкай IBM DB2])',
        'config-header-mysql' => 'Налады MySQL',
        'config-header-postgres' => 'Налады PostgreSQL',
        'config-header-sqlite' => 'Налады SQLite',
@@ -1631,7 +1630,7 @@ chmod a+w $3</pre>',
        'config-optional-continue' => 'Задаць болей пытаньняў.',
        'config-optional-skip' => 'Хопіць, проста ўсталяваць вікі.',
        'config-profile' => 'Профіль правоў удзельніка:',
-       'config-profile-wiki' => 'ТÑ\80адÑ\8bÑ\86Ñ\8bйнаÑ\8f Ð²Ñ\96кÑ\96', # Fuzzy
+       'config-profile-wiki' => 'Ð\90дкÑ\80Ñ\8bÑ\82аÑ\8f Ð²Ñ\96кÑ\96',
        'config-profile-no-anon' => 'Патрэбнае стварэньне рахунку',
        'config-profile-fishbowl' => 'Толькі для аўтарызаваных рэдактараў',
        'config-profile-private' => 'Прыватная вікі',
@@ -1821,7 +1820,7 @@ $messages['bg'] = array(
 $1',
        'config-localsettings-incomplete' => 'Съществуващият файл <code>LocalSettings.php</code> изглежда непълен.
 Променливата $1 не е зададена.
-Необходимо е да се редактира файлът <code>LocalSettings.php</code> и да се зададе променливата, след което да се натисне "{{int:Config-continue}}".',
+Необходимо е да се редактира файлът <code>LocalSettings.php</code> и да се зададе променливата, след което да се натисне „{{int:Config-continue}}“.',
        'config-localsettings-connection-error' => 'Възникна грешка при свързване с базата от данни чрез данните, посочени в <code>LocalSettings.php</code> или <code>AdminSettings.php</code>. Необходимо е да се коригират тези настройки преди повторен опит за свързване.
 
 $1',
@@ -2017,7 +2016,7 @@ $1
        'config-support-postgres' => '* $1 е популярна система за бази от данни с отворен изходен код, която е алтернатива на MySQL ([http://www.php.net/manual/en/pgsql.installation.php как се компилира PHP с поддръжка на PostgreSQL]). Възможно е все още да има грешки, затова не се препоръчва да се използва в общодостъпна среда.',
        'config-support-sqlite' => '* $1 е лека система за база от данни, която е много добре поддържана. ([http://www.php.net/manual/en/pdo.installation.php Как се компилира PHP с поддръжка на SQLite], използва PDO)',
        'config-support-oracle' => '* $1 е комерсиална корпоративна база от данни. ([http://www.php.net/manual/en/oci8.installation.php Как се компилира PHP с поддръжка на OCI8])',
-       'config-support-ibm_db2' => '* $1 е комерсиална фирмена база от данни.', # Fuzzy
+       'config-support-ibm_db2' => '* $1 е комерсиална фирмена база от данни. ([http://www.php.net/manual/en/ibm-db2.installation.php Как се компилира PHP с поддръжка на IBM DB2])',
        'config-header-mysql' => 'Настройки за MySQL',
        'config-header-postgres' => 'Настройки за PostgreSQL',
        'config-header-sqlite' => 'Настройки за SQLite',
@@ -2156,7 +2155,7 @@ chmod a+w $3</pre>',
        'config-optional-continue' => 'Задаване на допълнителни въпроси.',
        'config-optional-skip' => 'Достатъчно, инсталиране на уикито.',
        'config-profile' => 'Профил на потребителските права:',
-       'config-profile-wiki' => 'ТÑ\80адиÑ\86ионно Ñ\83ики', # Fuzzy
+       'config-profile-wiki' => 'Ð\9eÑ\82воÑ\80ено Ñ\83ики',
        'config-profile-no-anon' => 'Необходимо е създаване на сметка',
        'config-profile-fishbowl' => 'Само одобрени редактори',
        'config-profile-private' => 'Затворено уики',
@@ -2255,8 +2254,8 @@ chmod a+w $3</pre>',
 Възможно е те да изискват допълнително конфигуриране, но сега могат да бъдат включени.',
        'config-install-alreadydone' => "'''Предупреждение:''' Изглежда вече сте инсталирали МедияУики и се опитвате да го инсталирате отново.
 Продължете към следващата страница.",
-       'config-install-begin' => 'Инсталацията на МедияУики ще започне след натискане на бутона "{{int:config-continue}}".
\90ко Ð¶ÐµÐ»Ð°ÐµÑ\82е Ð´Ð° Ð½Ð°Ð¿Ñ\80авиÑ\82е Ð¿Ñ\80омени, Ð½Ð°Ñ\82иÑ\81неÑ\82е Ð\92Ñ\80Ñ\8aÑ\89ане.', # Fuzzy
+       'config-install-begin' => 'Инсталацията на МедияУики ще започне след натискане на бутона „{{int:config-continue}}“.
\92 Ñ\81лÑ\83Ñ\87ай, Ñ\87е Ðµ Ð½ÐµÐ¾Ð±Ñ\85одимо Ð´Ð° Ñ\81е Ð½Ð°Ð¿Ñ\80авÑ\8fÑ\82 Ð¿Ñ\80омени, Ð¸Ð·Ð¿Ð¾Ð»Ð·Ð²Ð° Ñ\81е Ð±Ñ\83Ñ\82она â\80\9e{{int:config-back}}â\80\9c.',
        'config-install-step-done' => 'готово',
        'config-install-step-failed' => 'неуспешно',
        'config-install-extensions' => 'Добавяне на разширенията',
@@ -2315,12 +2314,13 @@ $3
        'config-help' => 'помощ',
        'config-nofile' => 'Файлът „$1“ не може да бъде открит. Да не е бил изтрит?',
        'mainpagetext' => "'''Уикито беше успешно инсталирано.'''",
-       'mainpagedocfooter' => 'Разгледайте [//meta.wikimedia.org/wiki/Help:Contents ръководството] за подробна информация относно използването на софтуера.
+       'mainpagedocfooter' => 'РазгледайÑ\82е [//meta.wikimedia.org/wiki/Help:Contents Ñ\80Ñ\8aководÑ\81Ñ\82воÑ\82о] Ð·Ð° Ð¿Ð¾Ð´Ñ\80обна Ð¸Ð½Ñ\84оÑ\80маÑ\86иÑ\8f Ð¾Ñ\82ноÑ\81но Ð¸Ð·Ð¿Ð¾Ð»Ð·Ð²Ð°Ð½ÐµÑ\82о Ð½Ð° Ñ\83ики Ñ\81оÑ\84Ñ\82Ñ\83еÑ\80а.
 
 == Първи стъпки ==
-* [//www.mediawiki.org/wiki/Manual:Configuration_settings Ð\9aонÑ\84игÑ\83Ñ\80аÑ\86ионни Ð½Ð°Ñ\81Ñ\82Ñ\80ойки]
+* [//www.mediawiki.org/wiki/Manual:Configuration_settings Ð\9dаÑ\81Ñ\82Ñ\80ойки Ð·Ð° ÐºÐ¾Ð½Ñ\84игÑ\83Ñ\80иÑ\80ане]
 * [//www.mediawiki.org/wiki/Manual:FAQ ЧЗВ за МедияУики]
-* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-announce Пощенски списък относно нови версии на МедияУики]', # Fuzzy
+* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-announce Пощенски списък относно нови версии на МедияУики]
+* [//www.mediawiki.org/wiki/Localisation#Translation_resources Локализиране на МедияУики]',
 );
 
 /** Banjar (Bahasa Banjar)
@@ -2942,11 +2942,24 @@ Ovo '''nije preporučeno''' osim ako nemate problema s vašom wiki.",
 );
 
 /** Catalan (català)
+ * @author Pitort
  * @author පසිඳු කාවින්ද
  */
 $messages['ca'] = array(
        'config-page-language' => 'Llengua',
        'config-page-name' => 'Nom',
+       'config-charset-mysql5' => 'MySQL 4.1/5.0 UTF-8',
+       'config-mysql-innodb' => 'InnoDB',
+       'config-mysql-myisam' => 'MyISAM',
+       'config-mysql-utf8' => 'UTF-8',
+       'config-ns-generic' => 'Projecte',
+       'config-admin-password' => 'Contrasenya:',
+       'config-profile-wiki' => 'Wiki públic',
+       'config-profile-private' => 'Wiki privat',
+       'config-license-pd' => 'Domini públic',
+       'config-upload-deleted' => 'Directori pels arxius suprimits:',
+       'config-advanced-settings' => 'Configuració avançada',
+       'config-extensions' => 'Extensions',
        'mainpagetext' => "'''El programari del MediaWiki s'ha instaŀlat correctament.'''",
        'mainpagedocfooter' => "Consulteu la [//meta.wikimedia.org/wiki/Help:Contents Guia d'Usuari] per a més informació sobre com utilitzar-lo.
 
@@ -2954,7 +2967,7 @@ $messages['ca'] = array(
 
 * [//www.mediawiki.org/wiki/Manual:Configuration_settings Llista de característiques configurables]
 * [//www.mediawiki.org/wiki/Manual:FAQ PMF del MediaWiki]
-* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-announce Llista de correu (''listserv'') per a anuncis del MediaWiki]",
+* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-announce Llista de correu (''listserv'') per a anuncis del MediaWiki]", # Fuzzy
 );
 
 /** Chechen (нохчийн)
@@ -3190,7 +3203,9 @@ Instalace přerušena.',
        'config-using531' => 'MediaWiki nelze používat na PHP $1 kvůli chybě při předávání parametrů odkazem do <code>__call()</code>.
 Pro vyřešení upgradujte na PHP 5.3.2 nebo vyšší nebo downgradujte na PHP 5.3.0.
 Instalace přerušena.',
-       'config-suhosin-max-value-length' => 'Je nainstalován Suhosin, který omezuje délku parametrů GET na $1 bajtů. Komponenta ResourceLoader z MediaWiki dokáže s tímto omezením pracovat, ale sníží to výkon. Pokud to je alespoň trochu možné, měli byste v <code>php.ini</code> nastavit <code>suhosin.get.max_value_length</code> na 1024 nebo vyšší a na stejnou hodnotu nastavit v LocalSettings.php proměnnou <code>$wgResourceLoaderMaxQueryLength</code>.', # Fuzzy
+       'config-suhosin-max-value-length' => 'Je nainstalován Suhosin, který omezuje délku parametrů GET na $1 bajtů.
+Komponenta ResourceLoader z MediaWiki dokáže s tímto omezením pracovat, ale sníží to výkon.
+Pokud to je alespoň trochu možné, měli byste v <code>php.ini</code> nastavit <code>suhosin.get.max_value_length</code> na 1024 nebo vyšší a na stejnou hodnotu nastavit v <code>LocalSettings.php</code> proměnnou <code>$wgResourceLoaderMaxQueryLength</code>.',
        'config-db-type' => 'Typ databáze:',
        'config-db-host' => 'Databázový server:',
        'config-db-host-help' => 'Pokud je váš databázový server na jiném počítači, zadejte zde jméno stroje nebo IP adresu.
@@ -3276,7 +3291,7 @@ Pokud v nabídce níže nevidíte databázový systém, který chcete použít,
        'config-support-postgres' => '* $1 je populární open-source databázový systém používaný jako alternativa k MySQL ([http://www.php.net/manual/en/pgsql.installation.php jak přeložit PHP s podporou PostgreSQL]). Mohou se vyskytnout ještě nějaké menší chyby, použití v produkčním prostředí se nedoporučuje.',
        'config-support-sqlite' => '* $1 je velmi dobře podporovaný lehký databázový systém. ([http://www.php.net/manual/en/pdo.installation.php Jak přeložit PHP s podporou SQLite], používá PDO)',
        'config-support-oracle' => '* $1 je komerční podniková databáze. ([http://www.php.net/manual/en/oci8.installation.php Jak přeložit PHP s podporou OCI8])',
-       'config-support-ibm_db2' => '* $1 je komerční podniková databáze.', # Fuzzy
+       'config-support-ibm_db2' => '* $1 je komerční podniková databáze. ([http://www.php.net/manual/en/ibm-db2.installation.php Jak přeložit PHP s podporou IBM DB2])',
        'config-header-mysql' => 'Nastavení MySQL',
        'config-header-postgres' => 'Nastavení PostgreSQL',
        'config-header-sqlite' => 'Nastavení SQLite',
@@ -3416,7 +3431,7 @@ Zbývající konfiguraci už můžete přeskočit a nainstalovat wiki hned teď.
        'config-optional-continue' => 'Ptejte se mě dál.',
        'config-optional-skip' => 'Už mě to nudí, prostě nainstalujte wiki.',
        'config-profile' => 'Profil uživatelských práv:',
-       'config-profile-wiki' => 'Tradiční wiki', # Fuzzy
+       'config-profile-wiki' => 'Otevřená wiki',
        'config-profile-no-anon' => 'Vyžadována registrace uživatelů',
        'config-profile-fishbowl' => 'Editace jen pro vybrané',
        'config-profile-private' => 'Soukromá wiki',
@@ -3426,13 +3441,13 @@ V MediaWiki můžete snadno kontrolovat poslední změny a vracet zpět libovoln
 Mnoho lidí však zjistilo, že je MediaWiki užitečné v širokém spektru rolí a někdy není snadné všechny přesvědčit o výhodách wikizvyklostí.
 Takže si můžete vybrat.
 
-'''{{int:config-profile-wiki}}''' dovoluje editovat všem, aniž by se museli přihlašovat.
+Model '''{{int:config-profile-wiki}}''' dovoluje editovat všem, aniž by se museli přihlašovat.
 Na wiki, kde je '''{{int:config-profile-no-anon}}''', se lépe řídí zodpovědnost, ale může to odradit náhodné přispěvatele.
 
 Profil '''{{int:config-profile-fishbowl}}''' umožňuje schváleným uživatelům editovat, ale veřejnost si může stránky prohlížet včetně jejich historie.
 '''{{int:config-profile-private}}''' dovoluje stránky prohlížet jen schváleným uživatelům, kteří je i mohou editovat.
 
-Po instalaci je možná komplexní konfigurace uživatelských práv; vizte [//www.mediawiki.org/wiki/Manual:User_rights odpovídající stránku příručky].", # Fuzzy
+Po instalaci je možná komplexní konfigurace uživatelských práv; vizte [//www.mediawiki.org/wiki/Manual:User_rights odpovídající stránku příručky].",
        'config-license' => 'Autorská práva a licence:',
        'config-license-none' => 'Bez patičky s licencí',
        'config-license-cc-by-sa' => 'Creative Commons Uveďte autora-Zachovejte licenci',
@@ -3517,7 +3532,7 @@ Mohou vyžadovat dodatečnou konfiguraci, ale teď je můžete povolit.',
        'config-install-alreadydone' => "'''Upozornění:''' Vypadá to, že jste MediaWiki již nainstalovali a teď se o to pokoušíte znovu.
 Pokračujte na další stránku.",
        'config-install-begin' => 'Stisknutím „{{int:config-continue}}“ spustíte instalaci MediaWiki.
-Pokud ještě chcete udělat nějaké změny, stiskněte tlačítko zpět.', # Fuzzy
+Pokud ještě chcete udělat nějaké změny, stiskněte „{{int:config-back}}“.',
        'config-install-step-done' => 'hotovo',
        'config-install-step-failed' => 'selhaly',
        'config-install-extensions' => 'Vkládají se rozšíření',
@@ -3583,7 +3598,8 @@ Až to dokončíte, můžete '''[$2 vstoupit do své wiki]'''.",
 
 * [//www.mediawiki.org/wiki/Manual:Configuration_settings Nastavení konfigurace]
 * [//www.mediawiki.org/wiki/Manual:FAQ Často kladené otázky o MediaWiki]
-* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-announce E-mailová konference oznámení MediaWiki]', # Fuzzy
+* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-announce E-mailová konference oznámení MediaWiki]
+* [//www.mediawiki.org/wiki/Localisation#Translation_resources Překlad MediaWiki do vašeho jazyka]',
 );
 
 /** Kashubian (kaszëbsczi)
@@ -4333,7 +4349,7 @@ $messages['el'] = array(
        'config-mysql-utf8' => 'UTF-8',
        'config-site-name' => 'Όνομα του βίκι:',
        'config-site-name-blank' => 'Εισαγάγετε όνομα ιστοχώρου.',
-       'config-project-namespace' => 'ΠεÏ\81ιοÏ\87ή Î¿Î½Ï\8cμαÏ\84ος εγχειρήματος:',
+       'config-project-namespace' => 'Î\9fνομαÏ\84οÏ\87Ï\8eÏ\81ος εγχειρήματος:',
        'config-ns-generic' => 'Εγχείρημα',
        'config-ns-site-name' => 'Ίδιο με το όνομα του wiki: $1',
        'config-ns-other' => 'Άλλο (προσδιορίστε)',
@@ -4547,7 +4563,9 @@ Instalación anulada.',
        'config-using531' => 'MediaWiki no puede utilizarse con PHP $1 debido a un error con los parámetros de referencia para <code>__call()</code> .
 Actualice el sistema a PHP 5.3.2 o superior, o vuelva a la versión PHP 5.3.0 para resolver este problema.
 Instalación anulada.',
-       'config-suhosin-max-value-length' => 'Suhosin está instalado y limita la longitud del parámetro GET a $1 bytes. El componente ResourceLoader de MediaWiki trabajará en este límite, pero eso degradará el rendimiento. Si es posible, debe establecer el valor de <code>suhosin.get.max_value_length</code> en 1024 o superior en el archivo <code>php.ini</code> y establecer <code>$wgResourceLoaderMaxQueryLength</code> en el mismo valor en LocalSettings.php.', # Fuzzy
+       'config-suhosin-max-value-length' => 'Suhosin está instalado y limita el parámetro <code>length</code> GET a $1 bytes. 
+El componente ResourceLoader (gestor de recursos) de MediaWiki trabajará en este límite, pero eso perjudicará el rendimiento.
+Si es posible, deberías establecer <code>suhosin.get.max_value_length</code> en el valor 1024 o superior en <code>php.ini</code> y establecer <code>$wgResourceLoaderMaxQueryLength</code> en el mismo valor en <code>php.ini</code>.',
        'config-db-type' => 'Tipo de base de datos',
        'config-db-host' => 'Servidor de la base de datos:',
        'config-db-host-help' => 'Si su servidor de base de datos está en otro servidor, escriba el nombre del host o su dirección IP aquí.
@@ -6389,7 +6407,9 @@ Instalación abortada.',
        'config-using531' => 'O PHP $1 non é compatible con MediaWiki debido a un erro que afecta aos parámetros de referencia de <code>__call()</code>.
 Actualice o sistema á versión 5.3.2 ou posterior do PHP ou volva á versión 5.3.0 do PHP para arranxar o problema.
 Instalación abortada.',
-       'config-suhosin-max-value-length' => 'Suhosin está instalado e limita a lonxitude do parámetro GET a $1 bytes. O compoñente ResourceLoader (xestor de recursos) de MediaWiki traballa neste límite, pero este prexudica o rendemento. Se é posible, debería establecer <code>suhosin.get.max_value_length</code> no valor 1024 ou superior en <code>php.ini</code> e establecer <code>$wgResourceLoaderMaxQueryLength</code> no mesmo valor en LocalSettings.php.', # Fuzzy
+       'config-suhosin-max-value-length' => 'Suhosin está instalado e limita o parámetro GET <code>length</code> a $1 bytes.
+O compoñente ResourceLoader (xestor de recursos) de MediaWiki traballa neste límite, pero este prexudica o rendemento.
+Se é posible, debería establecer <code>suhosin.get.max_value_length</code> no valor 1024 ou superior en <code>php.ini</code> e establecer <code>$wgResourceLoaderMaxQueryLength</code> no mesmo valor en <code>LocalSettings.php</code>.',
        'config-db-type' => 'Tipo de base de datos:',
        'config-db-host' => 'Servidor da base de datos:',
        'config-db-host-help' => 'Se o servidor da súa base de datos está nun servidor diferente, escriba o nome do servidor ou o enderezo IP aquí.
@@ -7110,7 +7130,7 @@ $1
        'config-using531' => 'אי־אפשר להשתמש במדיה־ויקי עם <span dir="ltr">PHP $1</span> בגלל באג בפרמטרים של הפניות (reference parameters) ל־<code dir="ltr">__call()</code>.
 שדרגו ל־PHP 5.3.2 או לגרסה גבוהה יותר כדי לתקן את זה ([//bugs.php.net/bug.php?id=50394 bug filed with PHP]) או שַנמכו ל־PHP 5.3.0 כדי לפתור את הבעיה הזאת.
 ההתקנה בוטלה.',
-       'config-suhosin-max-value-length' => '×\9e×\95תק×\9f ×¤×\94 Suhosin ×\95×\94×\95×\90 ×\9e×\92×\91×\99×\9c ×\90ת ×\90×\95ר×\9a ×¤×¨×\9e×\98ר GET ×\9cÖ¾$1 ×\91ת×\99×\9d. ×¨×\9b×\99×\91 ResourceLoader ×©×\9c ×\9e×\93×\99×\94Ö¾×\95×\99ק×\99 ×\99עק×\95×£ ×\90ת ×\94×\9e×\92×\9c×\91×\94 ×\94×\96×\90ת, ×\90×\91×\9c ×\96×\94 ×\99פ×\92×¢ ×\91×\91×\99צ×\95×¢×\99×\9d. ×\90×\9d ×\96×\94 ×\91×\9b×\9c×\9c ×\90פשר×\99, ×\9b×\93×\99 ×\9cתק×\9f ×\90ת ×\94ער×\9a ×©×\9c <code>suhosin.get.max_value_length</code> ×\9cÖ¾1024 ×\91ק×\95×\91×¥ <code>php.ini</code> ×\95×\9c×\94×\92×\93×\99ר ×\90ת â\80\8e<code>$wgResourceLoaderMaxQueryLength</code> ×\9c×\90×\95ת×\95 ×\94ער×\9a ×\91ק×\95×\91×¥ LocalSettings.php.', # Fuzzy
+       'config-suhosin-max-value-length' => '×\9e×\95תק×\9f ×¤×\94 Suhosin ×\95×\94×\95×\90 ×\9e×\92×\91×\99×\9c ×\90ת ×\90×\95ר×\9a ×¤×¨×\9e×\98ר GET ×\9cÖ¾$1 ×\91ת×\99×\9d. ×¨×\9b×\99×\91 ResourceLoader ×©×\9c ×\9e×\93×\99×\94Ö¾×\95×\99ק×\99 ×\99עק×\95×£ ×\90ת ×\94×\9e×\92×\9c×\91×\94 ×\94×\96×\90ת, ×\90×\91×\9c ×\96×\94 ×\99פ×\92×¢ ×\91×\91×\99צ×\95×¢×\99×\9d. ×\90×\9d ×\96×\94 ×\91×\9b×\9c×\9c ×\90פשר×\99, ×\9b×\93×\90×\99 ×\9cתק×\9f ×\90ת ×\94ער×\9a ×©×\9c <code>suhosin.get.max_value_length</code> ×\9cÖ¾1024 ×\90×\95 ×\99×\95תר ×\91ק×\95×\91×¥ <code>php.ini</code> ×\95×\9c×\94×\92×\93×\99ר ×\90ת â\80\8e<code>$wgResourceLoaderMaxQueryLength</code> ×\9c×\90×\95ת×\95 ×\94ער×\9a ×\91ק×\95×\91×¥ LocalSettings.php.',
        'config-db-type' => 'סוג מסד הנתונים:',
        'config-db-host' => 'שרת מסד הנתונים:',
        'config-db-host-help' => 'אם שרת מסד הנתונים שלכם נמצא על שרת אחר, הקלידו את שם המחשב או את כתובת ה־IP כאן.
@@ -7191,7 +7211,7 @@ $1
        'config-support-postgres' => '$1 הוא מסד נתונים נפוץ בקוד פתוח והוא נפוץ בתור חלופה ל־MySQL (ר׳ [http://www.php.net/manual/en/pgsql.installation.php how to compile PHP with PostgreSQL support]). ייתכן שיש בתצורה הזאת באגים מסוימים והיא לא מומלצת לסביבות מבצעיות.',
        'config-support-sqlite' => '* $1 הוא מסד נתונים קליל עם תמיכה טובה מאוד. (ר׳ [http://www.php.net/manual/en/pdo.installation.php How to compile PHP with SQLite support], משתמש ב־PDO)',
        'config-support-oracle' => '* $1 הוא מסד נתונים עסקי מסחרי. (ר׳ [http://www.php.net/manual/en/oci8.installation.php How to compile PHP with OCI8 support])',
-       'config-support-ibm_db2' => '* $1 הוא מסד נתונים מסחרי ארגוני.', # Fuzzy
+       'config-support-ibm_db2' => '* $1 הוא מסד נתונים מסחרי ארגוני. ([http://www.php.net/manual/en/ibm-db2.installation.php How to compile PHP with IBM DB2 support])',
        'config-header-mysql' => 'הגדרות MySQL',
        'config-header-postgres' => 'הגדרות PostgreSQL',
        'config-header-sqlite' => 'הגדרות SQLite',
@@ -7331,7 +7351,7 @@ chmod a+w $3</pre></div>',
        'config-optional-continue' => 'הצגת שאלות נוספות.',
        'config-optional-skip' => 'משעמם לי, תתקינו לי כבר את הוויקי הזה.',
        'config-profile' => 'תסריט הרשאות משתמשים:',
-       'config-profile-wiki' => '×\95×\99ק×\99 ×\9eס×\95רת×\99', # Fuzzy
+       'config-profile-wiki' => '×\95×\99ק×\99 ×¤×\99ת×\95×\97',
        'config-profile-no-anon' => 'נדרשת יצירת חשבון',
        'config-profile-fishbowl' => 'עורכים מורשים בלבד',
        'config-profile-private' => 'ויקי פרטי',
@@ -7340,13 +7360,13 @@ chmod a+w $3</pre></div>',
 
 עם זאת, אנשים שונים מצאו למדיה־ויקי שימושים מגוּונים ולעתים לא קל לשכנע את כולם ביתרונות של \"דרך הוויקי\" המסורתית. ולכן יש לכם בררה.
 
-באתר '''{{int:config-profile-wiki}}''' – לכולם יש הרשאה לערוך, אפילו בלי להיכנס לחשבון.
+באתר מסוג '''{{int:config-profile-wiki}}''' – לכולם יש הרשאה לערוך, אפילו בלי להיכנס לחשבון.
 באתר וויקי מסוג '''{{int:config-profile-no-anon}}''' יש ביטחון גדול יותר, אבל הגדרה כזאת יכולה להרתיע תורמים מזדמנים.
 
 בתסריט '''{{int:config-profile-fishbowl}}''' רק משתמשים שקיבלו אישור יכולים לערוך, אבל כל הגולשים יכולים לקרוא את הדפים ואת גרסאותיהם הקודמות.
 ב'''{{int:config-profile-private}}''' רק משתמשים שקיבלו אישור יכולים לקרוא ולערוך דפים.
 
-הגדרות מורכבות של הרשאות אפשריות אחרי ההתקנה, ר׳ את [//www.mediawiki.org/wiki/Manual:User_rights הפרק על הנושא הזה בספר ההדרכה].", # Fuzzy
+הגדרות מורכבות של הרשאות אפשריות אחרי ההתקנה, ר׳ את [//www.mediawiki.org/wiki/Manual:User_rights הפרק על הנושא הזה בספר ההדרכה].",
        'config-license' => 'זכויות יוצרים ורישיון:',
        'config-license-none' => 'ללא כותרת תחתית עם רישיון',
        'config-license-cc-by-sa' => 'קריאייטיב קומונז–ייחוס–שיתוף זהה',
@@ -7431,7 +7451,7 @@ chmod a+w $3</pre></div>',
        'config-install-alreadydone' => "'''אזהרה:''' נראה שכבר התקנתם את מדיה־ויקי ואתם מנסים להתקין אותה שוב.
 אנה התקדמו לדף הבא.",
        'config-install-begin' => 'כשתלחצו על "{{int:config-continue}}", תתחילו את ההתקנה של מדיה־ויקי.
-אם אתם עדיין רוצים לשנות משהו, לחצו על "הקודם".', # Fuzzy
+אם אתם עדיין רוצים לשנות משהו, לחצו על "{{int:config-back}}"',
        'config-install-step-done' => 'בוצע',
        'config-install-step-failed' => 'נכשל',
        'config-install-extensions' => 'כולל הרחבות',
@@ -7496,7 +7516,8 @@ $3
 == קישורים שימושיים ==
 * [//www.mediawiki.org/wiki/Manual:Configuration_settings רשימת ההגדרות]
 * [//www.mediawiki.org/wiki/Manual:FAQ שאלות ותשובות על מדיה־ויקי]
-* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-announce רשימת התפוצה על השקת גרסאות]', # Fuzzy
+* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-announce רשימת התפוצה על השקת גרסאות]
+* [//www.mediawiki.org/wiki/Localisation#Translation_resources תרגום מדיה־ויקי לשפה שלך]',
 );
 
 /** Hindi (हिन्दी)
@@ -10042,7 +10063,9 @@ PHPを5.2.9かそれ以降のバージョンに、libxml2を2.7.3かそれ以降
        'config-using531' => 'PHP$1は<code>__call()</code>の引数参照に関するバグのため、MediaWikiと互換性がありません。
 PHP5.3.2以降に更新するか、この([//bugs.php.net/bug.php?id=50394 PHPに提出されたバグ])を修正するためにPHP5.3.0へ戻してください。
 インストールは中止されました。',
-       'config-suhosin-max-value-length' => 'Suhosin がインストールされており、GET パラメーターの長さを $1 バイトに制限しています。MediaWiki の ResourceLoader コンポーネントはこの制限を回避しますが、パフォーマンスは低下します。可能な限り、<code>php.ini</code> で <code>suhosin.get.max_value_length</code> を 1024 以上に設定し、同じ値を <code>LocalSettings.php</code> 中で <code>$wgResourceLoaderMaxQueryLength</code> に設定してください。',
+       'config-suhosin-max-value-length' => 'Suhosin がインストールされており、GET パラメーターの <code>length</code> を $1 バイトに制限しています。
+MediaWiki の ResourceLoader コンポーネントはこの制限を回避しますが、パフォーマンスは低下します。
+可能な限り、<code>php.ini</code> で <code>suhosin.get.max_value_length</code> を 1024 以上に設定し、同じ値を <code>LocalSettings.php</code> 内で <code>$wgResourceLoaderMaxQueryLength</code> に設定してください。',
        'config-db-type' => 'データベースの種類:',
        'config-db-host' => 'データベースのホスト:',
        'config-db-host-help' => '異なるサーバー上にデータベースサーバーがある場合、ホスト名またはIPアドレスをここに入力してください。
@@ -10497,7 +10520,8 @@ $messages['ka'] = array(
        'config-admin-password-confirm' => 'პაროლი ხელმეორედ:',
        'config-admin-name-blank' => 'შეიყვანეთ ადმინისტრატორის მომხმარებლის სახელი.',
        'config-admin-email' => 'ელ. ფოსტის მისამართი:',
-       'config-profile-wiki' => 'ტრადიციული ვიკი', # Fuzzy
+       'config-profile' => 'მომხმარებელთა უფლებების პროფილი:',
+       'config-profile-wiki' => 'ღია ვიკი',
        'config-profile-private' => 'დახურული ვიკი',
        'config-license' => 'საავტორო უფლები და ლიცენზია:',
        'config-license-cc-by-sa' => 'Creative Commons Attribution Share Alike',
@@ -10810,7 +10834,9 @@ PHP 5.2.9 이후와 libxml2 2.7.3 이후로 업그레이드하세요. ([//bugs.p
        'config-using531' => '미디어위키는 <code>__call()</code>을 참고로 매개 변수를 포함하는 버그로 인해 PHP $1(와)과 함께 사용할 수 없습니다.
 문제를 해결하려면 PHP 5.3.2 이상로 업그레이드하거나 PHP 5.3.0으로 다운그레이드를 하세요.
 설치가 중단되었습니다.',
-       'config-suhosin-max-value-length' => 'Suhosin(수호신)이 설치되었고 $1 바이트로 GET 매개 변수 길이를 제한하고 있습니다. 미디어위키의 ResourceLoader 구성 요소는 이 제한을 해결하지만 성능이 저하됩니다. 가능하면 <code>php.ini</code>의 <code>suhosin.get.max_value_length</code>에 1024 이상으로 설정하고 LocalSettings.php의 <code>$wgResourceLoaderMaxQueryLength</code>에 같은 값을 설정해야 합니다.', # Fuzzy
+       'config-suhosin-max-value-length' => 'Suhosin이 설치되었고 $1 바이트로 GET 매개 변수인 <code>length</code>를 제한하고 있습니다.
+미디어위키의 ResourceLoader 구성 요소는 이 제한을 해결하지만 성능이 저하됩니다.
+가능하면 <code>php.ini</code>의 <code>suhosin.get.max_value_length</code>에 1024 이상으로 설정하고 <code>LocalSettings.php</code>의 <code>$wgResourceLoaderMaxQueryLength</code>에 같은 값을 설정해야 합니다.',
        'config-db-type' => '데이터베이스 종류:',
        'config-db-host' => '데이터베이스 호스트:',
        'config-db-host-help' => '데이터베이스 서버가 다른 서버에 있으면 여기에 호스트 이름이나 IP 주소를 입력하세요.
@@ -13932,7 +13958,9 @@ De installatie wordt afgebroken.',
        'config-using531' => 'PHP $1 is niet compatibel met MediaWiki vanwege een fout met betrekking tot referentieparameters met <code>__call()</code>.
 Werk uw PHP bij naar PHP 5.3.2 of hoger of werk bij naar de lagere versie PHP 5.3.0 om dit op te lossen.
 De installatie wordt afgebroken.',
-       'config-suhosin-max-value-length' => 'Suhosin is geïnstalleerd en beperkt de lengte van de GET-parameter tot $1 bytes. De ResourceLoader van MediaWiki omzeilt deze beperking, maar dat is slecht voor de prestaties. Als het mogelijk is, moet u de waarde "<code>suhosin.get.max_value_length</code>" in <code>php.ini</code> instellen op 1024 of hoger en <code>$wgResourceLoaderMaxQueryLength</code> in LocalSettings.php op dezelfde waarde instellen.', # Fuzzy
+       'config-suhosin-max-value-length' => 'Suhosin is geïnstalleerd en beperkt de GET-parameter <code>length</code> tot $1 bytes.
+De ResourceLoader van MediaWiki omzeilt deze beperking, maar dat is slecht voor de prestaties.
+Als het mogelijk is, moet u de waarde "<code>suhosin.get.max_value_length</code>" in <code>php.ini</code> instellen op 1024 of hoger en <code>$wgResourceLoaderMaxQueryLength</code> in LocalSettings.php op dezelfde waarde instellen.',
        'config-db-type' => 'Databasetype:',
        'config-db-host' => 'Databasehost:',
        'config-db-host-help' => 'Als uw databaseserver een andere server is, voer dan de hostnaam of het IP-adres hier in.
@@ -15857,7 +15885,7 @@ $messages['ps'] = array(
        'config-admin-password' => 'پټنوم:',
        'config-admin-password-confirm' => 'پټنوم يو ځل بيا:',
        'config-admin-email' => 'برېښليک پته:',
-       'config-profile-wiki' => 'دوديزه ويکي',
+       'config-profile-wiki' => 'دوديزه ويکي', # Fuzzy
        'config-license-pd' => 'ټولګړی شپول',
        'config-email-settings' => 'د برېښليک امستنې',
        'config-install-step-done' => 'ترسره شو',
@@ -15869,7 +15897,8 @@ $messages['ps'] = array(
 == پيلول ==
 * [//www.mediawiki.org/wiki/Manual:Configuration_settings د امستنو د سازونې لړليک]
 * [//www.mediawiki.org/wiki/Manual:FAQ د ميډياويکي ډېرځليزې پوښتنې]
-* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-announce د مېډياويکي د برېښليکونو لړليک]',
+* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-announce د مېډياويکي د برېښليکونو لړليک]
+* [//www.mediawiki.org/wiki/Localisation#Translation_resources خپلې ژبې لپاره MediaWiki ځايتابول]',
 );
 
 /** Portuguese (português)
@@ -17742,7 +17771,7 @@ Sedaj lahko preskočite preostalo konfiguriranje in zdaj namestite wiki.',
        'config-optional-continue' => 'Zastavi mi več vprašanj.',
        'config-optional-skip' => 'Se že dolgočasim; samo namesti wiki.',
        'config-profile' => 'Profil uporabniških pravic:',
-       'config-profile-wiki' => 'Klasičen wiki', # Fuzzy
+       'config-profile-wiki' => 'Odprti wiki',
        'config-profile-no-anon' => 'Zahtevano je ustvarjanje računa',
        'config-profile-fishbowl' => 'Samo pooblaščeni urejevalci',
        'config-profile-private' => 'Zasebni wiki',
@@ -19807,6 +19836,7 @@ $messages['zea'] = array(
  * @author PhiLiP
  * @author Xiaomingyan
  * @author Yfdyh000
+ * @author 乌拉跨氪
  * @author 阿pp
  * @author 아라
  */
@@ -19992,7 +20022,7 @@ $1
        'config-support-postgres' => '* $1是一种流行的开源数据库系统,可作为MySQL的替代([http://www.php.net/manual/en/pgsql.installation.php 如何将对PostgreSQL的支持编译进PHP中])。本程序中可能依然存在一些小而明显的错误,因此并不建议在生产环境中使用该数据库系统。',
        'config-support-sqlite' => '* $1是一种轻量级的数据库系统,能被良好地支持。([http://www.php.net/manual/en/pdo.installation.php 如何将对SQLite的支持编译进PHP中],须使用PDO)',
        'config-support-oracle' => '* $1是一种商用企业级的数据库。([http://www.php.net/manual/en/oci8.installation.php 如何将对OCI8的支持编译进PHP中])',
-       'config-support-ibm_db2' => '* $1是一种商用企业级数据库。', # Fuzzy
+       'config-support-ibm_db2' => '* $1是一种商用企业级数据库。([http://www.php.net/manual/en/ibm-db2.installation.php 如何编译支持IBM DB2的PHP])',
        'config-header-mysql' => 'MySQL设置',
        'config-header-postgres' => 'PostgreSQL设置',
        'config-header-sqlite' => 'SQLite设置',
index da351ca..325f894 100644 (file)
@@ -488,7 +488,7 @@ abstract class Installer {
                if( !$_lsExists ) {
                        return false;
                }
-               unset($_lsExists);
+               unset( $_lsExists );
 
                require( "$IP/includes/DefaultSettings.php" );
                require( "$IP/LocalSettings.php" );
@@ -1073,18 +1073,18 @@ abstract class Installer {
         * @return string
         */
        protected function unicodeChar( $c ) {
-               $c = hexdec($c);
-               if ($c <= 0x7F) {
-                       return chr($c);
-               } elseif ($c <= 0x7FF) {
-                       return chr(0xC0 | $c >> 6) . chr(0x80 | $c & 0x3F);
-               } elseif ($c <= 0xFFFF) {
-                       return chr(0xE0 | $c >> 12) . chr(0x80 | $c >> 6 & 0x3F)
-                               . chr(0x80 | $c & 0x3F);
-               } elseif ($c <= 0x10FFFF) {
-                       return chr(0xF0 | $c >> 18) . chr(0x80 | $c >> 12 & 0x3F)
-                               . chr(0x80 | $c >> 6 & 0x3F)
-                               . chr(0x80 | $c & 0x3F);
+               $c = hexdec( $c );
+               if ( $c <= 0x7F ) {
+                       return chr( $c );
+               } elseif ( $c <= 0x7FF ) {
+                       return chr( 0xC0 | $c >> 6 ) . chr( 0x80 | $c & 0x3F );
+               } elseif ( $c <= 0xFFFF ) {
+                       return chr( 0xE0 | $c >> 12 ) . chr( 0x80 | $c >> 6 & 0x3F )
+                               . chr( 0x80 | $c & 0x3F );
+               } elseif ( $c <= 0x10FFFF ) {
+                       return chr( 0xF0 | $c >> 18 ) . chr( 0x80 | $c >> 12 & 0x3F )
+                               . chr( 0x80 | $c >> 6 & 0x3F )
+                               . chr( 0x80 | $c & 0x3F );
                } else {
                        return false;
                }
@@ -1105,8 +1105,8 @@ abstract class Installer {
                 * Note that we use the hex representation to create the code
                 * points in order to avoid any Unicode-destroying during transit.
                 */
-               $not_normal_c = $this->unicodeChar("FA6C");
-               $normal_c = $this->unicodeChar("242EE");
+               $not_normal_c = $this->unicodeChar( "FA6C" );
+               $normal_c = $this->unicodeChar( "242EE" );
 
                $useNormalizer = 'php';
                $needsUpdate = false;
index 94c38c4..4eb2d39 100644 (file)
@@ -516,7 +516,8 @@ class MysqlInstaller extends DatabaseInstaller {
                }
 
                if( $tryToCreate ) {
-                       $createHostList = array($server,
+                       $createHostList = array(
+                               $server,
                                'localhost',
                                'localhost.localdomain',
                                '%'
index da638de..a19637e 100644 (file)
@@ -329,7 +329,7 @@ class MysqlUpdater extends DatabaseUpdater {
                }
 
                if( $this->applyPatch( 'patch-fix-il_from.sql', false, "Fixing ancient broken imagelinks table." ) ) {
-                       $this->output("NOTE: you will have to run maintenance/refreshLinks.php after this." );
+                       $this->output( "NOTE: you will have to run maintenance/refreshLinks.php after this." );
                }
        }
 
index 845816e..4c72a8f 100644 (file)
@@ -119,7 +119,7 @@ class OracleInstaller extends DatabaseInstaller {
                                        return $status;
                                }
                                if ( !$this->getVar( '_CreateDBAccount' ) ) {
-                                       $status->fatal('config-db-sys-create-oracle');
+                                       $status->fatal( 'config-db-sys-create-oracle' );
                                }
                        } else {
                                return $status;
@@ -241,7 +241,7 @@ class OracleInstaller extends DatabaseInstaller {
                        $status->fatal( 'config-db-sys-user-exists-oracle', $this->getVar( 'wgDBuser' ) );
                }
 
-               if ($status->isOK()) {
+               if ( $status->isOK() ) {
                        // user created or already existing, switching back to a normal connection
                        // as the new user has all needed privileges to setup the rest of the schema
                        // i will be using that user as _InstallUser from this point on
index 8f43a6d..cafe8cd 100644 (file)
@@ -163,7 +163,7 @@ class OracleUpdater extends DatabaseUpdater {
         * converted to NULL in Oracle
         */
        protected function doRemoveNotNullEmptyDefaults() {
-               $meta = $this->db->fieldInfo( 'categorylinks' , 'cl_sortkey_prefix' );
+               $meta = $this->db->fieldInfo( 'categorylinks', 'cl_sortkey_prefix' );
                if ( $meta->isNullable() ) {
                        return;
                }
@@ -171,7 +171,7 @@ class OracleUpdater extends DatabaseUpdater {
        }
 
        protected function doRemoveNotNullEmptyDefaults2() {
-               $meta = $this->db->fieldInfo( 'ipblocks' , 'ipb_by_text' );
+               $meta = $this->db->fieldInfo( 'ipblocks', 'ipb_by_text' );
                if ( $meta->isNullable() ) {
                        return;
                }
index 5a13d42..ff9e271 100644 (file)
@@ -90,6 +90,7 @@ class PostgresUpdater extends DatabaseUpdater {
                        array( 'addTable', 'uploadstash',       'patch-uploadstash.sql' ),
                        array( 'addTable', 'user_former_groups','patch-user_former_groups.sql' ),
                        array( 'addTable', 'external_user',     'patch-external_user.sql' ),
+                       array( 'addTable', 'sites',             'patch-sites.sql' ),
 
                        # Needed before new field
                        array( 'convertArchive2' ),
@@ -155,6 +156,7 @@ class PostgresUpdater extends DatabaseUpdater {
                        array( 'addPgField', 'uploadstash',   'us_chunk_inx',         "INTEGER NULL" ),
                        array( 'addPgField', 'job',           'job_timestamp',        "TIMESTAMPTZ" ),
                        array( 'addPgField', 'job',           'job_random',           "INTEGER NOT NULL DEFAULT 0" ),
+                       array( 'addPgField', 'job',           'job_attempts',         "INTEGER NOT NULL DEFAULT 0" ),
                        array( 'addPgField', 'job',           'job_token',            "TEXT NOT NULL DEFAULT ''" ),
                        array( 'addPgField', 'job',           'job_token_timestamp',  "TIMESTAMPTZ" ),
                        array( 'addPgField', 'job',           'job_sha1',             "TEXT NOT NULL DEFAULT ''" ),
@@ -233,65 +235,66 @@ class PostgresUpdater extends DatabaseUpdater {
                        array( 'addPgIndex', 'job',           'job_timestamp_idx',      '(job_timestamp)' ),
                        array( 'addPgIndex', 'job',           'job_sha1',               '(job_sha1)' ),
                        array( 'addPgIndex', 'job',           'job_cmd_token',          '(job_cmd, job_token, job_random)' ),
+                       array( 'addPgIndex', 'job',           'job_cmd_token_id',       '(job_cmd, job_token, job_id)' ),
                        array( 'addPgIndex', 'filearchive',   'fa_sha1',                '(fa_sha1)' ),
 
                        array( 'checkIndex', 'pagelink_unique', array(
-                               array('pl_from', 'int4_ops', 'btree', 0),
-                               array('pl_namespace', 'int2_ops', 'btree', 0),
-                               array('pl_title', 'text_ops', 'btree', 0),
+                               array( 'pl_from', 'int4_ops', 'btree', 0 ),
+                               array( 'pl_namespace', 'int2_ops', 'btree', 0 ),
+                               array( 'pl_title', 'text_ops', 'btree', 0 ),
                        ),
                        'CREATE UNIQUE INDEX pagelink_unique ON pagelinks (pl_from,pl_namespace,pl_title)' ),
                        array( 'checkIndex', 'cl_sortkey', array(
-                               array('cl_to', 'text_ops', 'btree', 0),
-                               array('cl_sortkey', 'text_ops', 'btree', 0),
-                               array('cl_from', 'int4_ops', 'btree', 0),
+                               array( 'cl_to', 'text_ops', 'btree', 0 ),
+                               array( 'cl_sortkey', 'text_ops', 'btree', 0 ),
+                               array( 'cl_from', 'int4_ops', 'btree', 0 ),
                        ),
                        'CREATE INDEX cl_sortkey ON "categorylinks" USING "btree" ("cl_to", "cl_sortkey", "cl_from")' ),
                        array( 'checkIndex', 'logging_times', array(
-                               array('log_timestamp', 'timestamptz_ops', 'btree', 0),
+                               array( 'log_timestamp', 'timestamptz_ops', 'btree', 0 ),
                        ),
                        'CREATE INDEX "logging_times" ON "logging" USING "btree" ("log_timestamp")' ),
                        array( 'dropIndex', 'oldimage', 'oi_name' ),
                        array( 'checkIndex', 'oi_name_archive_name', array(
-                               array('oi_name', 'text_ops', 'btree', 0),
-                               array('oi_archive_name', 'text_ops', 'btree', 0),
+                               array( 'oi_name', 'text_ops', 'btree', 0 ),
+                               array( 'oi_archive_name', 'text_ops', 'btree', 0 ),
                        ),
                        'CREATE INDEX "oi_name_archive_name" ON "oldimage" USING "btree" ("oi_name", "oi_archive_name")' ),
                        array( 'checkIndex', 'oi_name_timestamp', array(
-                               array('oi_name', 'text_ops', 'btree', 0),
-                               array('oi_timestamp', 'timestamptz_ops', 'btree', 0),
+                               array( 'oi_name', 'text_ops', 'btree', 0 ),
+                               array( 'oi_timestamp', 'timestamptz_ops', 'btree', 0 ),
                        ),
                        'CREATE INDEX "oi_name_timestamp" ON "oldimage" USING "btree" ("oi_name", "oi_timestamp")' ),
                        array( 'checkIndex', 'page_main_title', array(
-                               array('page_title', 'text_pattern_ops', 'btree', 0),
+                               array( 'page_title', 'text_pattern_ops', 'btree', 0 ),
                        ),
                        'CREATE INDEX "page_main_title" ON "page" USING "btree" ("page_title" "text_pattern_ops") WHERE ("page_namespace" = 0)' ),
                        array( 'checkIndex', 'page_mediawiki_title', array(
-                               array('page_title', 'text_pattern_ops', 'btree', 0),
+                               array( 'page_title', 'text_pattern_ops', 'btree', 0 ),
                        ),
                        'CREATE INDEX "page_mediawiki_title" ON "page" USING "btree" ("page_title" "text_pattern_ops") WHERE ("page_namespace" = 8)' ),
                        array( 'checkIndex', 'page_project_title', array(
-                               array('page_title', 'text_pattern_ops', 'btree', 0),
+                               array( 'page_title', 'text_pattern_ops', 'btree', 0 ),
                        ),
                        'CREATE INDEX "page_project_title" ON "page" USING "btree" ("page_title" "text_pattern_ops") WHERE ("page_namespace" = 4)' ),
                        array( 'checkIndex', 'page_talk_title', array(
-                               array('page_title', 'text_pattern_ops', 'btree', 0),
+                               array( 'page_title', 'text_pattern_ops', 'btree', 0 ),
                        ),
                        'CREATE INDEX "page_talk_title" ON "page" USING "btree" ("page_title" "text_pattern_ops") WHERE ("page_namespace" = 1)' ),
                        array( 'checkIndex', 'page_user_title', array(
-                               array('page_title', 'text_pattern_ops', 'btree', 0),
+                               array( 'page_title', 'text_pattern_ops', 'btree', 0 ),
                        ),
                        'CREATE INDEX "page_user_title" ON "page" USING "btree" ("page_title" "text_pattern_ops") WHERE ("page_namespace" = 2)' ),
                        array( 'checkIndex', 'page_utalk_title', array(
-                               array('page_title', 'text_pattern_ops', 'btree', 0),
+                               array( 'page_title', 'text_pattern_ops', 'btree', 0 ),
                        ),
                        'CREATE INDEX "page_utalk_title" ON "page" USING "btree" ("page_title" "text_pattern_ops") WHERE ("page_namespace" = 3)' ),
                        array( 'checkIndex', 'ts2_page_text', array(
-                               array('textvector', 'tsvector_ops', 'gist', 0),
+                               array( 'textvector', 'tsvector_ops', 'gist', 0 ),
                        ),
                        'CREATE INDEX "ts2_page_text" ON "pagecontent" USING "gist" ("textvector")' ),
                        array( 'checkIndex', 'ts2_page_title', array(
-                               array('titlevector', 'tsvector_ops', 'gist', 0),
+                               array( 'titlevector', 'tsvector_ops', 'gist', 0 ),
                        ),
                        'CREATE INDEX "ts2_page_title" ON "page" USING "gist" ("titlevector")' ),
 
@@ -300,10 +303,10 @@ class PostgresUpdater extends DatabaseUpdater {
                        array( 'checkRevUserFkey' ),
                        array( 'dropIndex', 'ipblocks', 'ipb_address'),
                        array( 'checkIndex', 'ipb_address_unique', array(
-                               array('ipb_address', 'text_ops', 'btree', 0),
-                               array('ipb_user',    'int4_ops', 'btree', 0),
-                               array('ipb_auto',    'int2_ops', 'btree', 0),
-                               array('ipb_anon_only', 'int2_ops', 'btree', 0),
+                               array( 'ipb_address', 'text_ops', 'btree', 0 ),
+                               array( 'ipb_user',    'int4_ops', 'btree', 0 ),
+                               array( 'ipb_auto',    'int2_ops', 'btree', 0 ),
+                               array( 'ipb_anon_only', 'int2_ops', 'btree', 0 ),
                        ),
                        'CREATE UNIQUE INDEX ipb_address_unique ON ipblocks (ipb_address,ipb_user,ipb_auto,ipb_anon_only)' ),
 
@@ -506,7 +509,7 @@ END;
                        $this->output( "Creating sequence $ns\n" );
                        $this->db->query( "CREATE SEQUENCE $ns" );
                        if( $pkey !== false ) {
-                               $this->setDefault( $table,  $pkey, '"nextval"(\'"' . $ns . '"\'::"regclass")' );
+                               $this->setDefault( $table, $pkey, '"nextval"(\'"' . $ns . '"\'::"regclass")' );
                        }
                }
        }
@@ -534,11 +537,34 @@ END;
                }
        }
 
-       protected function renameIndex( $table, $old, $new ) {
-               if ( $this->db->indexExists( $table, $old ) ) {
-                       $this->output( "Renaming index $old to $new\n" );
-                       $this->db->query( "ALTER INDEX $old RENAME TO $new" );
+       protected function renameIndex(
+               $table, $old, $new, $skipBothIndexExistWarning = false, $a = false, $b = false
+       ) {
+               // First requirement: the table must exist
+               if ( !$this->db->tableExists( $table, __METHOD__ ) ) {
+                       $this->output( "...skipping: '$table' table doesn't exist yet.\n" );
+                       return;
+               }
+
+               // Second requirement: the new index must be missing
+               if ( $this->db->indexExists( $table, $new, __METHOD__ ) ) {
+                       $this->output( "...index $new already set on $table table.\n" );
+                       if ( !$skipBothIndexExistWarning
+                               && $this->db->indexExists( $table, $old, __METHOD__ ) )
+                       {
+                               $this->output( "...WARNING: $old still exists, despite it has been renamed into $new (which also exists).\n" .
+                                       "            $old should be manually removed if not needed anymore.\n" );
+                       }
+                       return;
                }
+
+               // Third requirement: the old index must exist
+               if ( !$this->db->indexExists( $table, $old, __METHOD__ ) ) {
+                       $this->output( "...skipping: index $old doesn't exist.\n" );
+                       return;
+               }
+
+               $this->db->query( "ALTER INDEX $old RENAME TO $new" );
        }
 
        protected function addPgField( $table, $field, $type ) {
index b27f773..c080871 100644 (file)
@@ -933,7 +933,7 @@ class WebInstaller extends Installer {
         * @return string
         */
        public function getRadioSet( $params ) {
-               if ( !isset( $params['controlName']  ) ) {
+               if ( !isset( $params['controlName'] ) ) {
                        $params['controlName'] = 'config_' . $params['var'];
                }
 
@@ -1079,7 +1079,7 @@ class WebInstaller extends Installer {
                ) );
                $anchor = Html::rawElement( 'a',
                        array( 'href' => $this->getURL( array( 'localsettings' => 1 ) ) ),
-                       $img . ' ' . wfMessage( 'config-download-localsettings' )->escaped() );
+                       $img . ' ' . wfMessage( 'config-download-localsettings' )->parse() );
                return Html::rawElement( 'div', array( 'class' => 'config-download-link' ), $anchor );
        }
 
@@ -1096,7 +1096,7 @@ class WebInstaller extends Installer {
                } elseif ( !empty( $_SERVER['SCRIPT_NAME'] ) ) {
                        $path = $_SERVER['SCRIPT_NAME'];
                }
-               if ($path !== false) {
+               if ( $path !== false ) {
                        $uri = preg_replace( '{^(.*)/(mw-)?config.*$}', '$1', $path );
                        $this->setVar( 'wgScriptPath', $uri );
                } else {
index f3166c2..42f451f 100644 (file)
@@ -219,7 +219,7 @@ class WebInstallerOutput {
                $dbTypes = $this->parent->getDBTypes();
 
                $this->parent->request->response()->header( 'Content-Type: text/html; charset=utf-8' );
-               if (!$this->allowFrames) {
+               if ( !$this->allowFrames ) {
                        $this->parent->request->response()->header( 'X-Frame-Options: DENY' );
                }
                if ( $this->redirectTarget ) {
@@ -239,7 +239,7 @@ class WebInstallerOutput {
        <meta http-equiv="Content-type" content="text/html; charset=utf-8" />
        <title><?php $this->outputTitle(); ?></title>
        <?php echo $this->getCssUrl() . "\n"; ?>
-       <?php echo Html::inlineScript(  "var dbTypes = " . Xml::encodeJsVar( $dbTypes ) ) . "\n"; ?>
+       <?php echo Html::inlineScript( "var dbTypes = " . Xml::encodeJsVar( $dbTypes ) ) . "\n"; ?>
        <?php echo $this->getJQuery() . "\n"; ?>
        <?php echo Html::linkedScript( '../skins/common/config.js' ) . "\n"; ?>
 </head>
index 68e8e11..e126c23 100644 (file)
@@ -369,7 +369,7 @@ class WebInstaller_ExistingWiki extends WebInstallerPage {
 
                // Set the relevant variables from LocalSettings.php
                $requiredVars = array( 'wgDBtype' );
-               $status = $this->importVariables( $requiredVars , $vars );
+               $status = $this->importVariables( $requiredVars, $vars );
                $installer = $this->parent->getDBInstaller();
                $status->merge( $this->importVariables( $installer->getGlobalNames(), $vars ) );
                if ( !$status->isOK() ) {
@@ -645,7 +645,7 @@ class WebInstaller_Name extends WebInstallerPage {
                        $this->parent->getTextBox( array(
                                'var' => 'wgSitename',
                                'label' => 'config-site-name',
-                         'help' => $this->parent->getHelpBox( 'config-site-name-help' )
+                               'help' => $this->parent->getHelpBox( 'config-site-name-help' )
                        ) ) .
                        $this->parent->getRadioSet( array(
                                'var' => '_NamespaceType',
@@ -955,7 +955,7 @@ class WebInstaller_Options extends WebInstallerPage {
 
                // We'll hide/show this on demand when the value changes, see config.js.
                $cacheval = $this->getVar( 'wgMainCacheType' );
-               if (!$cacheval) {
+               if ( !$cacheval ) {
                        // We need to set a default here; but don't hardcode it
                        // or we lose it every time we reload the page for validation
                        // or going back!
@@ -1025,7 +1025,7 @@ class WebInstaller_Options extends WebInstallerPage {
                } else {
                        $iframeAttribs['src'] = $this->getCCPartnerUrl();
                }
-               $wrapperStyle = ($this->getVar('_LicenseCode') == 'cc-choose') ? '' : 'display: none';
+               $wrapperStyle = ($this->getVar( '_LicenseCode' ) == 'cc-choose') ? '' : 'display: none';
 
                return
                        "<div class=\"config-cc-wrapper\" id=\"config-cc-wrapper\" style=\"$wrapperStyle\">\n" .
@@ -1155,12 +1155,12 @@ class WebInstaller_Install extends WebInstallerPage {
                        return 'continue';
                } elseif( $this->parent->request->wasPosted() ) {
                        $this->startForm();
-                       $this->addHTML("<ul>");
+                       $this->addHTML( "<ul>" );
                        $results = $this->parent->performInstallation(
-                               array( $this, 'startStage'),
+                               array( $this, 'startStage' ),
                                array( $this, 'endStage' )
                        );
-                       $this->addHTML("</ul>");
+                       $this->addHTML( "</ul>" );
                        // PerformInstallation bails on a fatal, so make sure the last item
                        // completed before giving 'next.' Likewise, only provide back on failure
                        $lastStep = end( $results );
@@ -1176,7 +1176,7 @@ class WebInstaller_Install extends WebInstallerPage {
        }
 
        public function startStage( $step ) {
-               $this->addHTML( "<li>" . wfMessage( "config-install-$step" )->escaped() . wfMessage( 'ellipsis')->escaped() );
+               $this->addHTML( "<li>" . wfMessage( "config-install-$step" )->escaped() . wfMessage( 'ellipsis' )->escaped() );
                if ( $step == 'extension-tables' ) {
                        $this->startLiveBox();
                }
@@ -1287,8 +1287,8 @@ class WebInstaller_ReleaseNotes extends WebInstaller_Document {
        protected function getFileName() {
                global $wgVersion;
 
-               if(preg_match( '/^(\d+)\.(\d+).*/i', $wgVersion, $result ) ) {
-                       throw new MWException('Variable $wgVersion has an invalid value.');
+               if( !preg_match( '/^(\d+)\.(\d+).*/i', $wgVersion, $result ) ) {
+                       throw new MWException( 'Variable $wgVersion has an invalid value.' );
                }
 
                return 'RELEASE-NOTES-' . $result[1] . '.' . $result[2];
@@ -1302,4 +1302,3 @@ class WebInstaller_UpgradeDoc extends WebInstaller_Document {
 class WebInstaller_Copying extends WebInstaller_Document {
        protected function getFileName() { return 'COPYING'; }
 }
-
index 5f3cdf5..9bd2031 100644 (file)
@@ -39,6 +39,9 @@ abstract class Job {
                $removeDuplicates,
                $error;
 
+       /** @var Array Additional queue metadata */
+       public $metadata = array();
+
        /*-------------------------------------------------------------------------
         * Abstract functions
         *------------------------------------------------------------------------*/
index 17f6648..7ce654b 100644 (file)
@@ -36,6 +36,8 @@ abstract class JobQueue {
 
        const QoS_Atomic = 1; // integer; "all-or-nothing" job insertions
 
+       const MAX_ATTEMPTS = 3; // integer; number of times to try a job
+
        /**
         * @param $params array
         */
@@ -61,7 +63,9 @@ abstract class JobQueue {
         *                If "random" is used, pop() will pick jobs in random order. This might be
         *                useful for improving concurrency depending on the queue storage medium.
         *   - claimTTL : If supported, the queue will recycle jobs that have been popped
-        *                but not acknowledged as completed after this many seconds.
+        *                but not acknowledged as completed after this many seconds. Recycling
+        *                of jobs simple means re-inserting them into the queue. Jobs can be
+        *                attempted up to three times before being discarded.
         *
         * Queue classes should throw an exception if they do not support the options given.
         *
@@ -100,6 +104,7 @@ abstract class JobQueue {
         * Queue classes should use caching if they are any slower without memcached.
         *
         * @return bool
+        * @throws MWException
         */
        final public function isEmpty() {
                wfProfileIn( __METHOD__ );
@@ -119,6 +124,7 @@ abstract class JobQueue {
         * Queue classes should use caching if they are any slower without memcached.
         *
         * @return integer
+        * @throws MWException
         */
        final public function getSize() {
                wfProfileIn( __METHOD__ );
@@ -138,6 +144,7 @@ abstract class JobQueue {
         * Queue classes should use caching if they are any slower without memcached.
         *
         * @return integer
+        * @throws MWException
         */
        final public function getAcquiredCount() {
                wfProfileIn( __METHOD__ );
@@ -158,8 +165,8 @@ abstract class JobQueue {
         *
         * @param $jobs Job|Array
         * @param $flags integer Bitfield (supports JobQueue::QoS_Atomic)
-        * @throws MWException
         * @return bool Returns false on failure
+        * @throws MWException
         */
        final public function push( $jobs, $flags = 0 ) {
                $jobs = is_array( $jobs ) ? $jobs : array( $jobs );
@@ -173,8 +180,8 @@ abstract class JobQueue {
         *
         * @param $jobs array List of Jobs
         * @param $flags integer Bitfield (supports JobQueue::QoS_Atomic)
-        * @throws MWException
         * @return bool Returns false on failure
+        * @throws MWException
         */
        final public function batchPush( array $jobs, $flags = 0 ) {
                foreach ( $jobs as $job ) {
@@ -199,8 +206,18 @@ abstract class JobQueue {
         * This requires $wgJobClasses to be set for the given job type.
         *
         * @return Job|bool Returns false on failure
+        * @throws MWException
         */
        final public function pop() {
+               global $wgJobClasses;
+
+               if ( $this->wiki !== wfWikiID() ) {
+                       throw new MWException( "Cannot pop '{$this->type}' job off foreign wiki queue." );
+               } elseif ( !isset( $wgJobClasses[$this->type] ) ) {
+                       // Do not pop jobs if there is no class for the queue type
+                       throw new MWException( "Unrecognized job type '{$this->type}'." );
+               }
+
                wfProfileIn( __METHOD__ );
                $job = $this->doPop();
                wfProfileOut( __METHOD__ );
@@ -219,8 +236,8 @@ abstract class JobQueue {
         * This does nothing for certain queue classes or if "claimTTL" is not set.
         *
         * @param $job Job
-        * @throws MWException
         * @return bool
+        * @throws MWException
         */
        final public function ack( Job $job ) {
                if ( $job->getType() !== $this->type ) {
@@ -266,8 +283,8 @@ abstract class JobQueue {
         * This does nothing for certain queue classes.
         *
         * @param $job Job
-        * @throws MWException
         * @return bool
+        * @throws MWException
         */
        final public function deduplicateRootJob( Job $job ) {
                if ( $job->getType() !== $this->type ) {
@@ -294,6 +311,7 @@ abstract class JobQueue {
         * This does nothing for certain queue classes.
         *
         * @return void
+        * @throws MWException
         */
        final public function waitForBackups() {
                wfProfileIn( __METHOD__ );
@@ -306,4 +324,49 @@ abstract class JobQueue {
         * @return void
         */
        protected function doWaitForBackups() {}
+
+       /**
+        * Return a map of task names to task definition maps.
+        * A "task" is a fast periodic queue maintenance action.
+        * Mutually exclusive tasks must implement their own locking in the callback.
+        *
+        * Each task value is an associative array with:
+        *   - name     : the name of the task
+        *   - callback : a PHP callable that performs the task
+        *   - period   : the period in seconds corresponding to the task frequency
+        *
+        * @return Array
+        */
+       final public function getPeriodicTasks() {
+               $tasks = $this->doGetPeriodicTasks();
+               foreach ( $tasks as $name => &$def ) {
+                       $def['name'] = $name;
+               }
+               return $tasks;
+       }
+
+       /**
+        * @see JobQueue::getPeriodicTasks()
+        * @return Array
+        */
+       protected function doGetPeriodicTasks() {
+               return array();
+       }
+
+       /**
+        * Clear any process and persistent caches
+        *
+        * @return void
+        */
+       final public function flushCaches() {
+               wfProfileIn( __METHOD__ );
+               $this->doFlushCaches();
+               wfProfileOut( __METHOD__ );
+       }
+
+       /**
+        * @see JobQueue::flushCaches()
+        * @return void
+        */
+       protected function doFlushCaches() {}
 }
index 1c9c8a7..6e42305 100644 (file)
  * @since 1.21
  */
 class JobQueueDB extends JobQueue {
+       const ROOTJOB_TTL     = 1209600; // integer; seconds to remember root jobs (14 days)
        const CACHE_TTL_SHORT = 30; // integer; seconds to cache info without re-validating
        const CACHE_TTL_LONG  = 300; // integer; seconds to cache info that is kept up to date
        const MAX_AGE_PRUNE   = 604800; // integer; seconds a job can live once claimed
-       const MAX_ATTEMPTS    = 3; // integer; number of times to try a job
        const MAX_JOB_RANDOM  = 2147483647; // integer; 2^31 - 1, used for job_random
        const MAX_OFFSET      = 255; // integer; maximum number of rows to skip
 
@@ -106,6 +106,10 @@ class JobQueueDB extends JobQueue {
        protected function doGetAcquiredCount() {
                global $wgMemc;
 
+               if ( $this->claimTTL <= 0 ) {
+                       return 0; // no acknowledgements
+               }
+
                $key = $this->getCacheKey( 'acquiredcount' );
 
                $count = $wgMemc->get( $key );
@@ -115,7 +119,7 @@ class JobQueueDB extends JobQueue {
 
                list( $dbr, $scope ) = $this->getSlaveDB();
                $count = (int)$dbr->selectField( 'job', 'COUNT(*)',
-                       array( 'job_cmd' => $this->type, "job_token !={$dbr->addQuotes('')}" ),
+                       array( 'job_cmd' => $this->type, "job_token != {$dbr->addQuotes( '' )}" ),
                        __METHOD__
                );
                $wgMemc->set( $key, $count, self::CACHE_TTL_SHORT );
@@ -216,10 +220,6 @@ class JobQueueDB extends JobQueue {
 
                $uuid = wfRandomString( 32 ); // pop attempt
                $job = false; // job popped off
-               // Occasionally recycle jobs back into the queue that have been claimed too long
-               if ( mt_rand( 0, 99 ) == 0 ) {
-                       $this->recycleStaleJobs();
-               }
                do { // retry when our row is invalid or deleted as a duplicate
                        // Try to reserve a row in the DB...
                        if ( in_array( $this->order, array( 'fifo', 'timestamp' ) ) ) {
@@ -402,8 +402,10 @@ class JobQueueDB extends JobQueue {
         *
         * @return integer Number of jobs recycled/deleted
         */
-       protected function recycleStaleJobs() {
-               $now   = time();
+       public function recycleAndDeleteStaleJobs() {
+               global $wgMemc;
+
+               $now = time();
                list( $dbw, $scope ) = $this->getMasterDB();
                $count = 0; // affected rows
 
@@ -440,6 +442,7 @@ class JobQueueDB extends JobQueue {
                                );
                                $count += $dbw->affectedRows();
                                wfIncrStats( 'job-recycle', $dbw->affectedRows() );
+                               $wgMemc->set( $this->getCacheKey( 'empty' ), 'false', self::CACHE_TTL_LONG );
                        }
                }
 
@@ -517,7 +520,7 @@ class JobQueueDB extends JobQueue {
                        }
 
                        // Update the timestamp of the last root job started at the location...
-                       return $wgMemc->set( $key, $params['rootJobTimestamp'], 14*86400 ); // 2 weeks
+                       return $wgMemc->set( $key, $params['rootJobTimestamp'], JobQueueDB::ROOTJOB_TTL );
                } );
 
                return true;
@@ -555,6 +558,29 @@ class JobQueueDB extends JobQueue {
                wfWaitForSlaves();
        }
 
+       /**
+        * @return Array
+        */
+       protected function doGetPeriodicTasks() {
+               return array(
+                       'recycleAndDeleteStaleJobs' => array(
+                               'callback' => array( $this, 'recycleAndDeleteStaleJobs' ),
+                               'period'   => ceil( $this->claimTTL / 2 )
+                       )
+               );
+       }
+
+       /**
+        * @return void
+        */
+       protected function doFlushCaches() {
+               global $wgMemc;
+
+               foreach ( array( 'empty', 'size', 'acquiredcount' ) as $type ) {
+                       $wgMemc->delete( $this->getCacheKey( $type ) );
+               }
+       }
+
        /**
         * @return Array (DatabaseBase, ScopedCallback)
         */
index cf0215b..6d9d590 100644 (file)
@@ -228,4 +228,58 @@ class JobQueueGroup {
                }
                return $types;
        }
+
+       /**
+        * Execute any due periodic queue maintenance tasks for all queues.
+        *
+        * A task is "due" if the time ellapsed since the last run is greater than
+        * the defined run period. Concurrent calls to this function will cause tasks
+        * to be attempted twice, so they may need their own methods of mutual exclusion.
+        *
+        * @return integer Number of tasks run
+        */
+       public function executeReadyPeriodicTasks() {
+               global $wgMemc;
+
+               list( $db, $prefix ) = wfSplitWikiID( $this->wiki );
+               $key = wfForeignMemcKey( $db, $prefix, 'jobqueuegroup', 'taskruns', 'v1' );
+               $lastRuns = $wgMemc->get( $key ); // (queue => task => UNIX timestamp)
+
+               $count = 0;
+               $tasksRun = array(); // (queue => task => UNIX timestamp)
+               foreach ( $this->getQueueTypes() as $type ) {
+                       $queue = $this->get( $type );
+                       foreach ( $queue->getPeriodicTasks() as $task => $definition ) {
+                               if ( $definition['period'] <= 0 ) {
+                                       continue; // disabled
+                               } elseif ( !isset( $lastRuns[$type][$task] )
+                                       || $lastRuns[$type][$task] < ( time() - $definition['period'] ) )
+                               {
+                                       if ( call_user_func( $definition['callback'] ) !== null ) {
+                                               $tasksRun[$type][$task] = time();
+                                               ++$count;
+                                       }
+                               }
+                       }
+               }
+
+               $wgMemc->merge( $key, function( $cache, $key, $lastRuns ) use ( $tasksRun ) {
+                       if ( is_array( $lastRuns ) ) {
+                               foreach ( $tasksRun as $type => $tasks ) {
+                                       foreach ( $tasks as $task => $timestamp ) {
+                                               if ( !isset( $lastRuns[$type][$task] )
+                                                       || $timestamp > $lastRuns[$type][$task] )
+                                               {
+                                                       $lastRuns[$type][$task] = $timestamp;
+                                               }
+                                       }
+                               }
+                       } else {
+                               $lastRuns = $tasksRun;
+                       }
+                       return $lastRuns;
+               } );
+
+               return $count;
+       }
 }
diff --git a/includes/job/JobQueueRedis.php b/includes/job/JobQueueRedis.php
new file mode 100644 (file)
index 0000000..3e7a47c
--- /dev/null
@@ -0,0 +1,609 @@
+<?php
+/**
+ * Redis-backed job queue code.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ * @file
+ * @author Aaron Schulz
+ */
+
+/**
+ * Class to handle job queues stored in Redis
+ *
+ * @ingroup JobQueue
+ * @since 1.21
+ */
+class JobQueueRedis extends JobQueue {
+       /** @var RedisConnectionPool */
+       protected $redisPool;
+
+       protected $server; // string; server address
+
+       const ROOTJOB_TTL   = 1209600; // integer; seconds to remember root jobs (14 days)
+       const MAX_AGE_PRUNE = 604800; // integer; seconds a job can live once claimed (7 days)
+
+       /**
+        * @params include:
+        *   - redisConf : An array of parameters to RedisConnectionPool::__construct().
+        *   - server    : A hostname/port combination or the absolute path of a UNIX socket.
+        *                 If a hostname is specified but no port, the standard port number
+        *                 6379 will be used. Required.
+        * @param array $params
+        */
+       public function __construct( array $params ) {
+               parent::__construct( $params );
+               $this->server = $params['redisConf']['server'];
+               $this->redisPool = RedisConnectionPool::singleton( $params['redisConf'] );
+       }
+
+       /**
+        * @see JobQueue::doIsEmpty()
+        * @return bool
+        * @throws MWException
+        */
+       protected function doIsEmpty() {
+               if ( mt_rand( 0, 99 ) == 0 ) {
+                       $this->doInternalMaintenance();
+               }
+
+               $conn = $this->getConnection();
+               try {
+                       return ( $conn->lSize( $this->getQueueKey( 'l-unclaimed' ) ) == 0 );
+               } catch ( RedisException $e ) {
+                       $this->throwRedisException( $this->server, $conn, $e );
+               }
+       }
+
+       /**
+        * @see JobQueue::doGetSize()
+        * @return integer
+        * @throws MWException
+        */
+       protected function doGetSize() {
+               if ( mt_rand( 0, 99 ) == 0 ) {
+                       $this->doInternalMaintenance();
+               }
+
+               $conn = $this->getConnection();
+               try {
+                       return $conn->lSize( $this->getQueueKey( 'l-unclaimed' ) );
+               } catch ( RedisException $e ) {
+                       $this->throwRedisException( $this->server, $conn, $e );
+               }
+       }
+
+       /**
+        * @see JobQueue::doGetAcquiredCount()
+        * @return integer
+        * @throws MWException
+        */
+       protected function doGetAcquiredCount() {
+               if ( mt_rand( 0, 99 ) == 0 ) {
+                       $this->doInternalMaintenance();
+               }
+
+               $conn = $this->getConnection();
+               try {
+                       if ( $this->claimTTL > 0 ) {
+                               return $conn->lSize( $this->getQueueKey( 'l-claimed' ) );
+                       } else {
+                               return 0;
+                       }
+               } catch ( RedisException $e ) {
+                       $this->throwRedisException( $this->server, $conn, $e );
+               }
+       }
+
+       /**
+        * @see JobQueue::doBatchPush()
+        * @param array $jobs
+        * @param $flags
+        * @return bool
+        * @throws MWException
+        */
+       protected function doBatchPush( array $jobs, $flags ) {
+               if ( !count( $jobs ) ) {
+                       return true;
+               }
+
+               // Convert the jobs into a list of field maps
+               $items = array(); // (uid => job fields map)
+               foreach ( $jobs as $job ) {
+                       $item = $this->getNewJobFields( $job );
+                       $items[$item['uid']] = $item;
+               }
+
+               $dedupUids = array(); // list of uids to check for duplicates
+               foreach ( $items as $item ) {
+                       if ( $this->isHashUid( $item['uid'] ) ) { // hash identifier => de-duplicate
+                               $dedupUids[] = $item['uid'];
+                       }
+               }
+
+               $conn = $this->getConnection();
+               try {
+                       // Find which of these jobs are duplicates of unclaimed jobs in the queue...
+                       if ( count( $dedupUids ) ) {
+                               $conn->multi( Redis::PIPELINE );
+                               foreach ( $dedupUids as $uid ) { // check if job data exists
+                                       $conn->exists( $this->prefixWithQueueKey( 'data', $uid ) );
+                               }
+                               if ( $this->claimTTL > 0 ) { // check which jobs were claimed
+                                       foreach ( $dedupUids as $uid ) {
+                                               $conn->hExists( $this->prefixWithQueueKey( 'h-meta', $uid ), 'ctime' );
+                                       }
+                                       list( $exists, $claimed ) = array_chunk( $conn->exec(), count( $dedupUids ) );
+                               } else {
+                                       $exists = $conn->exec();
+                                       $claimed = array(); // no claim system
+                               }
+                               // Remove the duplicate jobs to cut down on pushing duplicate uids...
+                               foreach ( $dedupUids as $k => $uid ) {
+                                       if ( $exists[$k] && empty( $claimed[$k] ) ) {
+                                               unset( $items[$uid] );
+                                       }
+                               }
+                       }
+                       // Actually push the non-duplicate jobs into the queue...
+                       if ( count( $items ) ) {
+                               $uids = array_keys( $items );
+                               $conn->multi( Redis::MULTI ); // begin (atomic trx)
+                               $conn->mSet( $this->prefixKeysWithQueueKey( 'data', $items ) );
+                               call_user_func_array(
+                                       array( $conn, 'lPush' ),
+                                       array_merge( array( $this->getQueueKey( 'l-unclaimed' ) ), $uids )
+                               );
+                               $res = $conn->exec(); // commit (atomic trx)
+                               if ( in_array( false, $res, true ) ) {
+                                       wfDebugLog( 'JobQueueRedis', "Could not insert {$this->type} job(s)." );
+                                       return false;
+                               }
+                       }
+                       wfIncrStats( 'job-insert', count( $items ) );
+                       wfIncrStats( 'job-insert-duplicate', count( $jobs ) - count( $items ) );
+               } catch ( RedisException $e ) {
+                       $this->throwRedisException( $this->server, $conn, $e );
+               }
+
+               return true;
+       }
+
+       /**
+        * @see JobQueue::doPop()
+        * @return Job|bool
+        * @throws MWException
+        */
+       protected function doPop() {
+               $job = false;
+
+               if ( mt_rand( 0, 99 ) == 0 ) {
+                       $this->doInternalMaintenance();
+               }
+
+               $conn = $this->getConnection();
+               try {
+                       do {
+                               // Atomically pop an item off the queue and onto the "claimed" list
+                               $uid = $conn->rpoplpush(
+                                       $this->getQueueKey( 'l-unclaimed' ),
+                                       $this->getQueueKey( 'l-claimed' )
+                               );
+                               if ( $uid === false ) {
+                                       break; // no jobs; nothing to do
+                               }
+
+                               wfIncrStats( 'job-pop' );
+                               $conn->multi( Redis::PIPELINE );
+                               $conn->get( $this->prefixWithQueueKey( 'data', $uid ) );
+                               if ( $this->claimTTL > 0 ) {
+                                       // Set the claim timestamp metadata. If this step fails, then
+                                       // the timestamp will be assumed to be the current timestamp by
+                                       // recycleAndDeleteStaleJobs() as of the next time that it runs.
+                                       // If two runners claim duplicate jobs, one will abort here.
+                                       $conn->hSetNx( $this->prefixWithQueueKey( 'h-meta', $uid ), 'ctime', time() );
+                               } else {
+                                       // If this fails, the message key will be deleted in cleanupClaimedJobs().
+                                       // If two runners claim duplicate jobs, one of them will abort here.
+                                       $conn->delete(
+                                               $this->prefixWithQueueKey( 'h-meta', $uid ),
+                                               $this->prefixWithQueueKey( 'data', $uid ) );
+                               }
+                               list( $item, $ok ) = $conn->exec();
+                               if ( $item === false || ( $this->claimTTL && !$ok ) ) {
+                                       wfDebug( "Could not find or delete job $uid; probably was a duplicate." );
+                                       continue; // job was probably a duplicate
+                               }
+
+                               // If $item is invalid, recycleAndDeleteStaleJobs() will cleanup as needed
+                               $job = $this->getJobFromFields( $item ); // may be false
+                       } while ( !$job ); // job may be false if invalid
+               } catch ( RedisException $e ) {
+                       $this->throwRedisException( $this->server, $conn, $e );
+               }
+
+               // Flag this job as an old duplicate based on its "root" job...
+               try {
+                       if ( $job && $this->isRootJobOldDuplicate( $job ) ) {
+                               wfIncrStats( 'job-pop-duplicate' );
+                               return DuplicateJob::newFromJob( $job ); // convert to a no-op
+                       }
+               } catch ( MWException $e ) {} // don't lose jobs over this
+
+               return $job;
+       }
+
+       /**
+        * @see JobQueue::doAck()
+        * @param Job $job
+        * @return Job|bool
+        * @throws MWException
+        */
+       protected function doAck( Job $job ) {
+               if ( $this->claimTTL > 0 ) {
+                       $conn = $this->getConnection();
+                       try {
+                               // Get the exact field map this Job came from, regardless of whether
+                               // the job was transformed into a DuplicateJob or anything of the sort.
+                               $item = $job->metadata['sourceFields'];
+
+                               $conn->multi( Redis::MULTI ); // begin (atomic trx)
+                               // Remove the first instance of this job scanning right-to-left.
+                               // This is O(N) in the worst case, but is likely to be much faster since
+                               // jobs are pushed to the left and we are starting from the right, where
+                               // the longest running jobs are likely to be. These should be the first
+                               // jobs to be acknowledged assuming that job run times are roughly equal.
+                               $conn->lRem( $this->getQueueKey( 'l-claimed' ), $item['uid'], -1 );
+                               // Delete the job data and its claim metadata
+                               $conn->delete(
+                                       $this->prefixWithQueueKey( 'h-meta', $item['uid'] ),
+                                       $this->prefixWithQueueKey( 'data', $item['uid'] ) );
+                               $res = $conn->exec(); // commit (atomic trx)
+
+                               if ( in_array( false, $res, true ) ) {
+                                       wfDebugLog( 'JobQueueRedis', "Could not acknowledge {$this->type} job." );
+                                       return false;
+                               }
+                       } catch ( RedisException $e ) {
+                               $this->throwRedisException( $this->server, $conn, $e );
+                       }
+               }
+               return true;
+       }
+
+       /**
+        * @see JobQueue::doDeduplicateRootJob()
+        * @param Job $job
+        * @return bool
+        * @throws MWException
+        */
+       protected function doDeduplicateRootJob( Job $job ) {
+               $params = $job->getParams();
+               if ( !isset( $params['rootJobSignature'] ) ) {
+                       throw new MWException( "Cannot register root job; missing 'rootJobSignature'." );
+               } elseif ( !isset( $params['rootJobTimestamp'] ) ) {
+                       throw new MWException( "Cannot register root job; missing 'rootJobTimestamp'." );
+               }
+               $key = $this->getRootJobKey( $params['rootJobSignature'] );
+
+               $conn = $this->getConnection();
+               try {
+                       $timestamp = $conn->get( $key ); // current last timestamp of this job
+                       if ( $timestamp && $timestamp >= $params['rootJobTimestamp'] ) {
+                               return true; // a newer version of this root job was enqueued
+                       }
+                       // Update the timestamp of the last root job started at the location...
+                       return $conn->set( $key, $params['rootJobTimestamp'], self::ROOTJOB_TTL ); // 2 weeks
+               } catch ( RedisException $e ) {
+                       $this->throwRedisException( $this->server, $conn, $e );
+               }
+       }
+
+       /**
+        * Check if the "root" job of a given job has been superseded by a newer one
+        *
+        * @param $job Job
+        * @return bool
+        * @throws MWException
+        */
+       protected function isRootJobOldDuplicate( Job $job ) {
+               $params = $job->getParams();
+               if ( !isset( $params['rootJobSignature'] ) ) {
+                       return false; // job has no de-deplication info
+               } elseif ( !isset( $params['rootJobTimestamp'] ) ) {
+                       wfDebugLog( 'JobQueueRedis', "Cannot check root job; missing 'rootJobTimestamp'." );
+                       return false;
+               }
+
+               $conn = $this->getConnection();
+               try {
+                       // Get the last time this root job was enqueued
+                       $timestamp = $conn->get( $this->getRootJobKey( $params['rootJobSignature'] ) );
+               } catch ( RedisException $e ) {
+                       $this->throwRedisException( $this->server, $conn, $e );
+               }
+
+               // Check if a new root job was started at the location after this one's...
+               return ( $timestamp && $timestamp > $params['rootJobTimestamp'] );
+       }
+
+       /**
+        * Do any job recycling or queue cleanup as needed
+        *
+        * @return void
+        * @return integer Number of jobs recycled/deleted
+        * @throws MWException
+        */
+       protected function doInternalMaintenance() {
+               return ( $this->claimTTL > 0 ) ?
+                       $this->recycleAndDeleteStaleJobs() : $this->cleanupClaimedJobs();
+       }
+
+       /**
+        * Recycle or destroy any jobs that have been claimed for too long
+        *
+        * @return integer Number of jobs recycled/deleted
+        * @throws MWException
+        */
+       protected function recycleAndDeleteStaleJobs() {
+               $count = 0;
+               // For each job item that can be retried, we need to add it back to the
+               // main queue and remove it from the list of currenty claimed job items.
+               $conn = $this->getConnection();
+               try {
+                       // Avoid duplicate insertions of items to be re-enqueued
+                       $conn->multi( Redis::MULTI );
+                       $conn->setnx( $this->getQueueKey( 'lock' ), 1 );
+                       $conn->expire( $this->getQueueKey( 'lock' ), 3600 );
+                       if ( $conn->exec() !== array( true, true ) ) { // lock
+                               return $count; // already in progress
+                       }
+
+                       $now = time();
+                       $claimCutoff = $now - $this->claimTTL;
+                       $pruneCutoff = $now - self::MAX_AGE_PRUNE;
+
+                       // Get the list of all claimed jobs
+                       $claimedUids = $conn->lRange( $this->getQueueKey( 'l-claimed' ), 0, -1 );
+                       // Get a map of (uid => claim metadata) for all claimed jobs
+                       $metadata = $conn->mGet( $this->prefixValuesWithQueueKey( 'h-meta', $claimedUids ) );
+
+                       $uidsPush = array(); // items IDs to move to the "unclaimed" queue
+                       $uidsRemove = array(); // item IDs to remove from "claimed" queue
+                       foreach ( $claimedUids as $i => $uid ) { // all claimed items
+                               $info = $metadata[$i] ? $metadata[$i] : array();
+                               if ( isset( $info['ctime'] ) || isset( $info['rctime'] ) ) {
+                                       // Prefer "ctime" (set by pop()) over "rctime" (set by this function)
+                                       $ctime = isset( $info['ctime'] ) ? $info['ctime'] : $info['rctime'];
+                                       // Claimed job claimed for too long?
+                                       if ( $ctime < $claimCutoff ) {
+                                               // Get the number of failed attempts
+                                               $attempts = isset( $info['attempts'] ) ? $info['attempts'] : 0;
+                                               if ( $attempts < self::MAX_ATTEMPTS ) {
+                                                       $uidsPush[] = $uid; // retry it
+                                               } elseif ( $ctime < $pruneCutoff ) {
+                                                       $uidsRemove[] = $uid; // just remove it
+                                               }
+                                       }
+                               } else {
+                                       // If pop() failed to set the claim timestamp, set it to the current time.
+                                       // Since that function sets this non-atomically *after* moving the job to
+                                       // the "claimed" queue, it may be the case that it just didn't set it yet.
+                                       $conn->hSet( $this->prefixWithQueueKey( 'h-meta', $uid ), 'rctime', $now );
+                               }
+                       }
+
+                       $conn->multi( Redis::MULTI ); // begin (atomic trx)
+                       if ( count( $uidsPush ) ) { // move from "l-claimed" to "l-unclaimed"
+                               call_user_func_array(
+                                       array( $conn, 'lPush' ),
+                                       array_merge( array( $this->getQueueKey( 'l-unclaimed' ) ), $uidsPush )
+                               );
+                               foreach ( $uidsPush as $uid ) {
+                                       $conn->lRem( $this->getQueueKey( 'l-claimed' ), $uid, -1 );
+                                       $conn->hDel( $this->prefixWithQueueKey( 'h-meta', $uid ), 'ctime', 'rctime' );
+                                       $conn->hIncrBy( $this->prefixWithQueueKey( 'h-meta', $uid ), 'attempts', 1 );
+                               }
+                       }
+                       foreach ( $uidsRemove as $uid ) { // remove from "l-claimed"
+                               $conn->lRem( $this->getQueueKey( 'l-claimed' ), $uid, -1 );
+                               $conn->delete( // delete job data and metadata
+                                       $this->prefixWithQueueKey( 'h-meta', $uid ),
+                                       $this->prefixWithQueueKey( 'data', $uid ) );
+                       }
+                       $res = $conn->exec(); // commit (atomic trx)
+
+                       if ( in_array( false, $res, true ) ) {
+                               wfDebugLog( 'JobQueueRedis', "Could not recycle {$this->type} job(s)." );
+                       } else {
+                               $count += ( count( $uidsPush ) + count( $uidsRemove ) );
+                               wfIncrStats( 'job-recycle', count( $uidsPush ) );
+                       }
+
+                       $conn->delete( $this->getQueueKey( 'lock' ) ); // unlock
+               } catch ( RedisException $e ) {
+                       $this->throwRedisException( $this->server, $conn, $e );
+               }
+
+               return $count;
+       }
+
+       /**
+        * Destroy any jobs that have been claimed
+        *
+        * @return integer Number of jobs deleted
+        * @throws MWException
+        */
+       protected function cleanupClaimedJobs() {
+               $count = 0;
+               // Make sure the message for claimed jobs was deleted
+               // and remove the claimed job IDs from the "claimed" list.
+               $conn = $this->getConnection();
+               try {
+                       // Avoid races and duplicate effort
+                       $conn->multi( Redis::MULTI );
+                       $conn->setnx( $this->getQueueKey( 'lock' ), 1 );
+                       $conn->expire( $this->getQueueKey( 'lock' ), 3600 );
+                       if ( $conn->exec() !== array( true, true ) ) { // lock
+                               return $count; // already in progress
+                       }
+                       // Get the list of all claimed jobs
+                       $uids = $conn->lRange( $this->getQueueKey( 'l-claimed' ), 0, -1 );
+                       if ( count( $uids ) ) {
+                               // Delete the message keys and delist the corresponding ids.
+                               // Since the only other changes to "l-claimed" are left pushes, we can just strip
+                               // off the elements read here using a right trim based on the number of ids read.
+                               $conn->multi( Redis::MULTI ); // begin (atomic trx)
+                               $conn->lTrim( $this->getQueueKey( 'l-claimed' ), 0, -count( $uids ) - 1 );
+                               $conn->delete( array_merge(
+                                       $this->prefixValuesWithQueueKey( 'h-meta', $uids ),
+                                       $this->prefixValuesWithQueueKey( 'data', $uids )
+                               ) );
+                               $res = $conn->exec(); // commit (atomic trx)
+
+                               if ( in_array( false, $res, true ) ) {
+                                       wfDebugLog( 'JobQueueRedis', "Could not purge {$this->type} job(s)." );
+                               } else {
+                                       $count += count( $uids );
+                               }
+                       }
+                       $conn->delete( $this->getQueueKey( 'lock' ) ); // unlock
+               } catch ( RedisException $e ) {
+                       $this->throwRedisException( $this->server, $conn, $e );
+               }
+
+               return $count;
+       }
+
+       /**
+        * @param $job Job
+        * @return array
+        */
+       protected function getNewJobFields( Job $job ) {
+               return array(
+                       // Fields that describe the nature of the job
+                       'type'      => $job->getType(),
+                       'namespace' => $job->getTitle()->getNamespace(),
+                       'title'     => $job->getTitle()->getDBkey(),
+                       'params'    => $job->getParams(),
+                       // Additional metadata
+                       'uid'       => $job->ignoreDuplicates()
+                               ? wfBaseConvert( sha1( serialize( $job->getDeduplicationInfo() ) ), 16, 36, 31 )
+                               : wfRandomString( 32 ),
+                       'timestamp' => time() // UNIX timestamp
+               );
+       }
+
+       /**
+        * @param $fields array
+        * @return Job|bool
+        */
+       protected function getJobFromFields( array $fields ) {
+               $title = Title::makeTitleSafe( $fields['namespace'], $fields['title'] );
+               if ( $title ) {
+                       $job = Job::factory( $fields['type'], $title, $fields['params'] );
+                       $job->metadata['sourceFields'] = $fields;
+                       return $job;
+               }
+               return false;
+       }
+
+       /**
+        * @param $uid string Job UID
+        * @return bool Whether $uid is a SHA-1 hash based identifier for de-duplication
+        */
+       protected function isHashUid( $uid ) {
+               return strlen( $uid ) == 31;
+       }
+
+       /**
+        * Get a connection to the server that handles all sub-queues for this queue
+        *
+        * @return Array (server name, Redis instance)
+        * @throws MWException
+        */
+       protected function getConnection() {
+               $conn = $this->redisPool->getConnection( $this->server );
+               if ( !$conn ) {
+                       throw new MWException( "Unable to connect to redis server." );
+               }
+               return $conn;
+       }
+
+       /**
+        * @param $server string
+        * @param $conn RedisConnRef
+        * @param $e RedisException
+        * @throws MWException
+        */
+       protected function throwRedisException( $server, RedisConnRef $conn, $e ) {
+               $this->redisPool->handleException( $server, $conn, $e );
+               throw new MWException( "Redis server error: {$e->getMessage()}\n" );
+       }
+
+       /**
+        * @param $prop string
+        * @return string
+        */
+       private function getQueueKey( $prop ) {
+               list( $db, $prefix ) = wfSplitWikiID( $this->wiki );
+               return wfForeignMemcKey( $db, $prefix, 'jobqueue', $this->type, $prop );
+       }
+
+       /**
+        * @param string $signature Hash identifier of the root job
+        * @return string
+        */
+       private function getRootJobKey( $signature ) {
+               list( $db, $prefix ) = wfSplitWikiID( $this->wiki );
+               return wfForeignMemcKey( $db, $prefix, 'jobqueue', $this->type, 'rootjob', $signature );
+       }
+
+       /**
+        * @param $prop string
+        * @param $string string
+        * @return string
+        */
+       private function prefixWithQueueKey( $prop, $string ) {
+               return $this->getQueueKey( $prop ) . ':' . $string;
+       }
+
+       /**
+        * @param $prop string
+        * @param $items array
+        * @return Array
+        */
+       private function prefixValuesWithQueueKey( $prop, array $items ) {
+               $res = array();
+               foreach ( $items as $item ) {
+                       $res[] = $this->prefixWithQueueKey( $prop, $item );
+               }
+               return $res;
+       }
+
+       /**
+        * @param $prop string
+        * @param $items array
+        * @return Array
+        */
+       private function prefixKeysWithQueueKey( $prop, array $items ) {
+               $res = array();
+               foreach ( $items as $key => $item ) {
+                       $res[$this->prefixWithQueueKey( $prop, $key )] = $item;
+               }
+               return $res;
+       }
+}
index fb73bf1..3cb5894 100644 (file)
@@ -207,4 +207,3 @@ class DoubleRedirectJob extends Job {
                return self::$user;
        }
 }
-
index 23418e3..1b64b10 100644 (file)
@@ -46,9 +46,10 @@ final class DuplicateJob extends Job {
         */
        public static function newFromJob( Job $job ) {
                $djob = new self( $job->getTitle(), $job->getParams(), $job->getId() );
-               $djob->command = $job->getType();
-               $djob->params  = is_array( $djob->params ) ? $djob->params : array();
-               $djob->params  = array( 'isDuplicate' => true ) + $djob->params;
+               $djob->command  = $job->getType();
+               $djob->params   = is_array( $djob->params ) ? $djob->params : array();
+               $djob->params   = array( 'isDuplicate' => true ) + $djob->params;
+               $djob->metadata = $job->metadata;
                return $djob;
        }
 
index cfc7f53..fae06ad 100644 (file)
@@ -848,4 +848,3 @@ class IEContentAnalyzer {
                return 'unknown';
        }
 }
-
diff --git a/includes/limit.sh b/includes/limit.sh
new file mode 100644 (file)
index 0000000..44b9edc
--- /dev/null
@@ -0,0 +1,100 @@
+#!/bin/bash
+#
+# Resource limiting wrapper for command execution
+#
+# Why is this in shell script? Because bash has a setrlimit() wrapper
+# and is available on most Linux systems. If Perl was distributed with
+# BSD::Resource included, we would happily use that instead, but it isn't.
+
+MW_CPU_LIMIT=0
+MW_CGROUP=
+MW_MEM_LIMIT=0
+MW_FILE_SIZE_LIMIT=0
+MW_WALL_CLOCK_LIMIT=0
+
+# Override settings
+eval "$2"
+
+if [ "$MW_CPU_LIMIT" -gt 0 ]; then
+       ulimit -t "$MW_CPU_LIMIT"
+fi
+if [ "$MW_MEM_LIMIT" -gt 0 ]; then
+       if [ -n "$MW_CGROUP" ]; then
+               # Create cgroup
+               if ! mkdir -m 0700 "$MW_CGROUP"/$$; then
+                       echo "limit.sh: failed to create the cgroup." 1>&2
+                       exit 1
+               fi
+               echo $$ > "$MW_CGROUP"/$$/tasks
+               if [ -n "$MW_CGROUP_NOTIFY" ]; then
+                       echo "1" > "$MW_CGROUP"/$$/notify_on_release
+               fi
+               # Memory
+               echo $(($MW_MEM_LIMIT*1024)) > "$MW_CGROUP"/$$/memory.limit_in_bytes
+               # Memory+swap
+               echo $(($MW_MEM_LIMIT*1024)) > "$MW_CGROUP"/$$/memory.memsw.limit_in_bytes
+       else
+               ulimit -v "$MW_MEM_LIMIT"
+       fi
+fi
+if [ "$MW_FILE_SIZE_LIMIT" -gt 0 ]; then
+       ulimit -f "$MW_FILE_SIZE_LIMIT"
+fi
+if [ "$MW_WALL_CLOCK_LIMIT" -gt 0 -a -x "/usr/bin/timeout" ]; then
+       /usr/bin/timeout $MW_WALL_CLOCK_LIMIT /bin/bash -c "$1"
+       STATUS="$?"
+       if [ "$STATUS" == 124 ]; then
+               echo "limit.sh: timed out." 1>&2
+       fi
+else
+       eval "$1"
+       STATUS="$?"
+fi
+
+# Clean up cgroup
+cleanup() {
+       # First we have to move the current task into a "garbage" group, otherwise 
+       # the cgroup will not be empty, and attempting to remove it will fail with
+       # "Device or resource busy"
+       if [ -w "$MW_CGROUP"/tasks ]; then
+               GARBAGE="$MW_CGROUP"
+       else
+               GARBAGE="$MW_CGROUP"/garbage-"$USER"
+               if [ ! -e "$GARBAGE" ]; then
+                       mkdir -m 0700 "$GARBAGE"
+               fi
+       fi
+       echo $BASHPID > "$GARBAGE"/tasks
+
+       # Suppress errors in case the cgroup has disappeared due to a release script
+       rmdir "$MW_CGROUP"/$$ 2>/dev/null
+}
+
+updateTaskCount() {
+       # There are lots of ways to count lines in a file in shell script, but this
+       # is one of the few that doesn't create another process, which would
+       # increase the returned number of tasks.
+       readarray < "$MW_CGROUP"/$$/tasks
+       NUM_TASKS=${#MAPFILE[*]}
+}
+
+if [ -n "$MW_CGROUP" ]; then
+       updateTaskCount
+
+       if [ $NUM_TASKS -gt 1 ]; then
+               # Spawn a monitor process which will continue to poll for completion 
+               # of all processes in the cgroup after termination of the parent shell
+               (
+                       while [ $NUM_TASKS -gt 1 ]; do
+                               sleep 10
+                               updateTaskCount
+                       done
+                       cleanup
+               ) >&/dev/null < /dev/null &
+               disown -a
+       else
+               cleanup
+       fi
+fi
+exit "$STATUS"
+
index 03d5276..47b2231 100644 (file)
@@ -74,7 +74,7 @@ class LogEventsList extends ContextSource {
        public function showHeader( $type ) {
                wfDeprecated( __METHOD__, '1.19' );
                // If only one log type is used, then show a special message...
-               $headerType = (count($type) == 1) ? $type[0] : '';
+               $headerType = (count( $type ) == 1) ? $type[0] : '';
                $out = $this->getOutput();
                if( LogPage::isLogType( $headerType ) ) {
                        $page = new LogPage( $headerType );
@@ -97,8 +97,8 @@ class LogEventsList extends ContextSource {
         * @param $filter: array
         * @param $tagFilter: array?
         */
-       public function showOptions( $types=array(), $user='', $page='', $pattern='', $year='',
-               $month = '', $filter = null, $tagFilter='' ) {
+       public function showOptions( $types=array(), $user = '', $page = '', $pattern = '', $year = '',
+               $month = '', $filter = null, $tagFilter = '' ) {
                global $wgScript, $wgMiserMode;
 
                $title = SpecialPage::getTitleFor( 'Log' );
@@ -117,7 +117,7 @@ class LogEventsList extends ContextSource {
                $html .= $this->getExtraInputs( $types ) . "\n";
 
                // Title pattern, if allowed
-               if (!$wgMiserMode) {
+               if ( !$wgMiserMode ) {
                        $html .= $this->getTitlePattern( $pattern ) . "\n";
                }
 
@@ -125,12 +125,12 @@ class LogEventsList extends ContextSource {
                $html .= Xml::tags( 'p', null, Xml::dateMenu( $year, $month ) );
 
                // Tag filter
-               if ($tagSelector) {
+               if ( $tagSelector ) {
                        $html .= Xml::tags( 'p', null, implode( '&#160;', $tagSelector ) );
                }
 
                // Filter links
-               if ($filter) {
+               if ( $filter ) {
                        $html .= Xml::tags( 'p', null, $this->getFilterLinks( $filter ) );
                }
 
@@ -162,7 +162,7 @@ class LogEventsList extends ContextSource {
                        $query = $this->getDefaultQuery();
                        $queryKey = "hide_{$type}_log";
 
-                       $hideVal = 1 - intval($val);
+                       $hideVal = 1 - intval( $val );
                        $query[$queryKey] = $hideVal;
 
                        $link = Linker::linkKnown(
@@ -176,7 +176,7 @@ class LogEventsList extends ContextSource {
                        $hiddens .= Html::hidden( "hide_{$type}_log", $val ) . "\n";
                }
                // Build links
-               return '<small>'.$this->getLanguage()->pipeList( $links ) . '</small>' . $hiddens;
+               return '<small>' . $this->getLanguage()->pipeList( $links ) . '</small>' . $hiddens;
        }
 
        private function getDefaultQuery() {
@@ -198,7 +198,7 @@ class LogEventsList extends ContextSource {
         * @return String: Formatted HTML
         */
        private function getTypeMenu( $queryTypes ) {
-               $queryType = count($queryTypes) == 1 ? $queryTypes[0] : '';
+               $queryType = count( $queryTypes ) == 1 ? $queryTypes[0] : '';
                $selector = $this->getTypeSelector();
                $selector->setDefault( $queryType );
                return $selector->getHtml();
@@ -212,7 +212,7 @@ class LogEventsList extends ContextSource {
        public function getTypeSelector() {
                $typesByName = array(); // Temporary array
                // First pass to load the log names
-               foreach(  LogPage::validTypes() as $type ) {
+               foreach( LogPage::validTypes() as $type ) {
                        $page = new LogPage( $type );
                        $restriction = $page->getRestriction();
                        if ( $this->getUser()->isAllowed( $restriction ) ) {
@@ -221,7 +221,7 @@ class LogEventsList extends ContextSource {
                }
 
                // Second pass to sort by name
-               asort($typesByName);
+               asort( $typesByName );
 
                // Always put "All public logs" on top
                $public = $typesByName[''];
@@ -273,10 +273,10 @@ class LogEventsList extends ContextSource {
        private function getExtraInputs( $types ) {
                $offender = $this->getRequest()->getVal( 'offender' );
                $user = User::newFromName( $offender, false );
-               if( !$user || ($user->getId() == 0 && !IP::isIPAddress($offender) ) ) {
+               if( !$user || ( $user->getId() == 0 && !IP::isIPAddress( $offender ) ) ) {
                        $offender = ''; // Blank field if invalid
                }
-               if( count($types) == 1 && $types[0] == 'suppress' ) {
+               if( count( $types ) == 1 && $types[0] == 'suppress' ) {
                        return Xml::inputLabel( $this->msg( 'revdelete-offender' )->text(), 'offender',
                                'mw-log-offender', 20, $offender );
                }
@@ -383,8 +383,8 @@ class LogEventsList extends ContextSource {
         * @param $right string
         * @return Boolean
         */
-       public static function typeAction( $row, $type, $action, $right='' ) {
-               $match = is_array($type) ?
+       public static function typeAction( $row, $type, $action, $right = '' ) {
+               $match = is_array( $type ) ?
                        in_array( $row->log_type, $type ) : $row->log_type == $type;
                if( $match ) {
                        $match = is_array( $action ) ?
@@ -468,13 +468,13 @@ class LogEventsList extends ContextSource {
         * @return Integer Number of total log items (not limited by $lim)
         */
        public static function showLogExtract(
-               &$out, $types=array(), $page='', $user='', $param = array()
+               &$out, $types=array(), $page = '', $user = '', $param = array()
        ) {
                $defaultParameters = array(
                        'lim' => 25,
                        'conds' => array(),
                        'showIfEmpty' => true,
-                       'msgKey' => array(''),
+                       'msgKey' => array( '' ),
                        'wrap' => "$1",
                        'flags' => 0
                );
@@ -520,8 +520,8 @@ class LogEventsList extends ContextSource {
                                }
                        }
                        $s .= $loglist->beginLogEventsList() .
-                                $logBody .
-                                $loglist->endLogEventsList();
+                               $logBody .
+                               $loglist->endLogEventsList();
                } else {
                        if ( $showIfEmpty ) {
                                $s = Html::rawElement( 'div', array( 'class' => 'mw-warning-logempty' ),
@@ -535,7 +535,7 @@ class LogEventsList extends ContextSource {
                        } elseif ( $page != '' ) {
                                $urlParam['page'] = $page;
                        }
-                       if ( $user != '')
+                       if ( $user != '' )
                                $urlParam['user'] = $user;
                        if ( !is_array( $types ) ) # Make it an array, if it isn't
                                $types = array( $types );
@@ -602,4 +602,4 @@ class LogEventsList extends ContextSource {
                }
                return false;
        }
- }
+}
index ce5b053..eb8779f 100644 (file)
@@ -192,18 +192,18 @@ class LogFormatter {
                $parameters = $entry->getParameters();
                // @see LogPage::actionText()
                // Text of title the action is aimed at.
-               $target = $entry->getTarget()->getPrefixedText() ;
+               $target = $entry->getTarget()->getPrefixedText();
                $text = null;
                switch( $entry->getType() ) {
                        case 'move':
                                switch( $entry->getSubtype() ) {
                                        case 'move':
-                                               $movesource =  $parameters['4::target'];
+                                               $movesource = $parameters['4::target'];
                                                $text = wfMessage( '1movedto2' )
                                                        ->rawParams( $target, $movesource )->inContentLanguage()->escaped();
                                                break;
                                        case 'move_redir':
-                                               $movesource =  $parameters['4::target'];
+                                               $movesource = $parameters['4::target'];
                                                $text = wfMessage( '1movedto2_redir' )
                                                        ->rawParams( $target, $movesource )->inContentLanguage()->escaped();
                                                break;
@@ -588,7 +588,7 @@ class LogFormatter {
                        return $this->msg( $message )->text();
                }
 
-               $content =  $this->msg( $message )->escaped();
+               $content = $this->msg( $message )->escaped();
                $attribs = array( 'class' => 'history-deleted' );
                return Html::rawElement( 'span', $attribs, $content );
        }
@@ -713,7 +713,7 @@ class LegacyLogFormatter extends LogFormatter {
 
                $performer = $this->getPerformerElement();
                if ( !$this->irctext ) {
-                       $action = $performer .  $this->msg( 'word-separator' )->text() . $action;
+                       $action = $performer . $this->msg( 'word-separator' )->text() . $action;
                }
 
                return $action;
@@ -913,7 +913,7 @@ class DeleteLogFormatter extends LogFormatter {
                                foreach ( $extra as $v ) {
                                        $changes[] = $this->msg( $v )->plain();
                                }
-                               $changeText =  $this->context->getLanguage()->listToText( $changes );
+                               $changeText = $this->context->getLanguage()->listToText( $changes );
 
 
                                $newParams = array_slice( $params, 0, 3 );
@@ -957,7 +957,7 @@ class DeleteLogFormatter extends LogFormatter {
                                $this->msg( $message )->escaped(),
                                array(),
                                array( 'target' => $this->entry->getTarget()->getPrefixedDBkey() )
-                        );
+                       );
                        return $this->msg( 'parentheses' )->rawParams( $revert )->escaped();
 
                case 'revision': // If an edit was hidden from a page give a review link to the history
index 5854e99..9778f27 100644 (file)
@@ -271,7 +271,7 @@ class LogPage {
                                                $params[2] = isset( $params[2] ) ?
                                                        self::formatBlockFlags( $params[2], $langObj ) : '';
                                        // Page protections
-                                       } elseif ( $type == 'protect' && count($params) == 3 ) {
+                                       } elseif ( $type == 'protect' && count( $params ) == 3 ) {
                                                // Restrictions and expiries
                                                if( $skin ) {
                                                        $details .= $wgLang->getDirMark() . htmlspecialchars( " {$params[1]}" );
index af62ce3..fad1058 100644 (file)
@@ -71,7 +71,7 @@ class LogPager extends ReverseChronologicalPager {
        public function getFilterParams() {
                global $wgFilterLogTypes;
                $filters = array();
-               if( count($this->types) ) {
+               if( count( $this->types ) ) {
                        return $filters;
                }
                foreach( $wgFilterLogTypes as $type => $default ) {
@@ -122,10 +122,10 @@ class LogPager extends ReverseChronologicalPager {
                if( $hideLogs !== false ) {
                        $this->mConds[] = $hideLogs;
                }
-               if( count($types) ) {
+               if( count( $types ) ) {
                        $this->mConds['log_type'] = $types;
                        // Set typeCGI; used in url param for paging
-                       if( count($types) == 1 ) $this->typeCGI = $types[0];
+                       if( count( $types ) == 1 ) $this->typeCGI = $types[0];
                }
        }
 
@@ -140,7 +140,7 @@ class LogPager extends ReverseChronologicalPager {
                        return false;
                }
                $usertitle = Title::makeTitleSafe( NS_USER, $name );
-               if( is_null($usertitle) ) {
+               if( is_null( $usertitle ) ) {
                        return false;
                }
                /* Fetch userid at first, if known, provides awesome query plan afterwards */
@@ -154,9 +154,9 @@ class LogPager extends ReverseChronologicalPager {
                        // Paranoia: avoid brute force searches (bug 17342)
                        $user = $this->getUser();
                        if( !$user->isAllowed( 'deletedhistory' ) ) {
-                               $this->mConds[] = $this->mDb->bitAnd('log_deleted', LogPage::DELETED_USER) . ' = 0';
+                               $this->mConds[] = $this->mDb->bitAnd( 'log_deleted', LogPage::DELETED_USER ) . ' = 0';
                        } elseif( !$user->isAllowed( 'suppressrevision' ) ) {
-                               $this->mConds[] = $this->mDb->bitAnd('log_deleted', LogPage::SUPPRESSED_USER) .
+                               $this->mConds[] = $this->mDb->bitAnd( 'log_deleted', LogPage::SUPPRESSED_USER ) .
                                        ' != ' . LogPage::SUPPRESSED_USER;
                        }
                        $this->performer = $usertitle->getText();
@@ -209,9 +209,9 @@ class LogPager extends ReverseChronologicalPager {
                // Paranoia: avoid brute force searches (bug 17342)
                $user = $this->getUser();
                if( !$user->isAllowed( 'deletedhistory' ) ) {
-                       $this->mConds[] = $db->bitAnd('log_deleted', LogPage::DELETED_ACTION) . ' = 0';
+                       $this->mConds[] = $db->bitAnd( 'log_deleted', LogPage::DELETED_ACTION) . ' = 0';
                } elseif( !$user->isAllowed( 'suppressrevision' ) ) {
-                       $this->mConds[] = $db->bitAnd('log_deleted', LogPage::SUPPRESSED_ACTION) .
+                       $this->mConds[] = $db->bitAnd( 'log_deleted', LogPage::SUPPRESSED_ACTION) .
                                ' != ' . LogPage::SUPPRESSED_ACTION;
                }
        }
@@ -251,10 +251,10 @@ class LogPager extends ReverseChronologicalPager {
                # avoids site-breaking filesorts.
                } elseif( $this->title || $this->pattern || $this->performer ) {
                        $index['logging'] = array( 'page_time', 'user_time' );
-                       if( count($this->types) == 1 ) {
+                       if( count( $this->types ) == 1 ) {
                                $index['logging'][] = 'log_user_type_time';
                        }
-               } elseif( count($this->types) == 1 ) {
+               } elseif( count( $this->types ) == 1 ) {
                        $index['logging'] = 'type_time';
                } else {
                        $index['logging'] = 'times';
index a515c63..46d1b95 100644 (file)
@@ -62,7 +62,7 @@ class BmpHandler extends BitmapHandler {
                        return false;
                }
                $header = fread( $f, 54 );
-               fclose($f);
+               fclose( $f );
 
                // Extract binary form of width and height from the header
                $w = substr( $header, 18, 4);
index cd8a044..0a39a2c 100644 (file)
@@ -183,7 +183,7 @@ class DjVuHandler extends ImageHandler {
                if ( $wgDjvuPostProcessor ) {
                        $cmd .= " | {$wgDjvuPostProcessor}";
                }
-               $cmd .= ' > ' . wfEscapeShellArg($dstPath) . ') 2>&1';
+               $cmd .= ' > ' . wfEscapeShellArg( $dstPath ) . ') 2>&1';
                wfProfileIn( 'ddjvu' );
                wfDebug( __METHOD__.": $cmd\n" );
                $retval = '';
@@ -194,7 +194,7 @@ class DjVuHandler extends ImageHandler {
                if ( $retval != 0 || $removed ) {
                        wfDebugLog( 'thumbnail',
                                sprintf( 'thumbnail failed on %s: error %d "%s" from "%s"',
-                                       wfHostname(), $retval, trim($err), $cmd ) );
+                                       wfHostname(), $retval, trim( $err ), $cmd ) );
                        return new MediaTransformError( 'thumbnail_error', $width, $height, $err );
                } else {
                        $params = array(
@@ -228,7 +228,7 @@ class DjVuHandler extends ImageHandler {
         * @param $gettext Boolean: DOCUMENT (Default: false)
         * @return bool
         */
-       function getMetaTree( $image , $gettext = false ) {
+       function getMetaTree( $image, $gettext = false ) {
                if ( isset( $image->dejaMetaTree ) ) {
                        return $image->dejaMetaTree;
                }
index cad9c1b..9735791 100644 (file)
@@ -43,9 +43,9 @@ class DjVuImage {
                $this->mFilename = $filename;
        }
 
-        /**
-         * @const DJVUTXT_MEMORY_LIMIT Memory limit for the DjVu description software
-         */
+       /**
+        * @const DJVUTXT_MEMORY_LIMIT Memory limit for the DjVu description software
+        */
        const DJVUTXT_MEMORY_LIMIT = 300000;
 
        /**
@@ -259,8 +259,8 @@ class DjVuImage {
                # Text layer
                if ( isset( $wgDjvuTxt ) ) {
                        wfProfileIn( 'djvutxt' );
-                       $cmd = wfEscapeShellArg( $wgDjvuTxt ) . ' --detail=page ' . wfEscapeShellArg( $this->mFilename ) ;
-                       wfDebug( __METHOD__.": $cmd\n" );
+                       $cmd = wfEscapeShellArg( $wgDjvuTxt ) . ' --detail=page ' . wfEscapeShellArg( $this->mFilename );
+                       wfDebug( __METHOD__ . ": $cmd\n" );
                        $retval = '';
                        $txt = wfShellExec( $cmd, $retval, array(), array( 'memory' => self::DJVUTXT_MEMORY_LIMIT ) );
                        wfProfileOut( 'djvutxt' );
@@ -281,7 +281,7 @@ EOR;
                                $txt = preg_replace_callback( $reg, array( $this, 'pageTextCallback' ), $txt );
                                $txt = "<DjVuTxt>\n<HEAD></HEAD>\n<BODY>\n" . $txt . "</BODY>\n</DjVuTxt>\n";
                                $xml = preg_replace( "/<DjVuXML>/", "<mw-djvu><DjVuXML>", $xml, 1 );
-                               $xml = $xml . $txt. '</mw-djvu>' ;
+                               $xml = $xml . $txt. '</mw-djvu>';
                        }
                }
                wfProfileOut( __METHOD__ );
index bdacbc8..2dc2eae 100644 (file)
@@ -290,8 +290,8 @@ class Exif {
                        // Only give a warning for b/c, since originally we didn't
                        // require this. The number of things affected by this is
                        // rather small.
-                       wfWarn( 'Exif class did not have byte order specified. '
-                        . 'Some properties may be decoded incorrectly.' );
+                       wfWarn( 'Exif class did not have byte order specified. ' .
+                               'Some properties may be decoded incorrectly.' );
                        $this->byteOrder = 'BE'; // BE seems about twice as popular as LE in jpg's.
                }
 
@@ -322,7 +322,7 @@ class Exif {
 
                foreach ( array_keys( $this->mRawExifData ) as $section ) {
                        if ( !in_array( $section, array_keys( $this->mExifTags ) ) ) {
-                               $this->debug( $section , __FUNCTION__, "'$section' is not a valid Exif section" );
+                               $this->debug( $section, __FUNCTION__, "'$section' is not a valid Exif section" );
                                continue;
                        }
 
@@ -387,7 +387,7 @@ class Exif {
                $this->exifPropToOrd( 'SceneType' );
 
                $this->charCodeString( 'UserComment' );
-               $this->charCodeString( 'GPSProcessingMethod');
+               $this->charCodeString( 'GPSProcessingMethod' );
                $this->charCodeString( 'GPSAreaInformation' );
 
                //ComponentsConfiguration should really be an array instead of a string...
@@ -396,8 +396,8 @@ class Exif {
                if ( isset ( $this->mFilteredExifData['ComponentsConfiguration'] ) ) {
                        $val = $this->mFilteredExifData['ComponentsConfiguration'];
                        $ccVals = array();
-                       for ($i = 0; $i < strlen($val); $i++) {
-                               $ccVals[$i] = ord( substr($val, $i, 1) );
+                       for ( $i = 0; $i < strlen( $val ); $i++ ) {
+                               $ccVals[$i] = ord( substr( $val, $i, 1 ) );
                        }
                        $ccVals['_type'] = 'ol'; //this is for formatting later.
                        $this->mFilteredExifData['ComponentsConfiguration'] = $ccVals;
@@ -413,11 +413,11 @@ class Exif {
                if ( isset ( $this->mFilteredExifData['GPSVersion'] ) ) {
                        $val = $this->mFilteredExifData['GPSVersion'];
                        $newVal = '';
-                       for ($i = 0; $i < strlen($val); $i++) {
+                       for ( $i = 0; $i < strlen( $val ); $i++ ) {
                                if ( $i !== 0 ) {
                                        $newVal .= '.';
                                }
-                               $newVal .= ord( substr($val, $i, 1) );
+                               $newVal .= ord( substr( $val, $i, 1 ) );
                        }
                        if ( $this->byteOrder === 'LE' ) {
                                // Need to reverse the string
@@ -442,17 +442,17 @@ class Exif {
        private function charCodeString ( $prop ) {
                if ( isset( $this->mFilteredExifData[$prop] ) ) {
 
-                       if ( strlen($this->mFilteredExifData[$prop]) <= 8 ) {
+                       if ( strlen( $this->mFilteredExifData[$prop] ) <= 8 ) {
                                //invalid. Must be at least 9 bytes long.
 
-                               $this->debug( $this->mFilteredExifData[$prop] , __FUNCTION__, false );
-                               unset($this->mFilteredExifData[$prop]);
+                               $this->debug( $this->mFilteredExifData[$prop], __FUNCTION__, false );
+                               unset( $this->mFilteredExifData[$prop] );
                                return;
                        }
-                       $charCode = substr( $this->mFilteredExifData[$prop], 0, 8);
-                       $val = substr( $this->mFilteredExifData[$prop], 8);
+                       $charCode = substr( $this->mFilteredExifData[$prop], 0, 8 );
+                       $val = substr( $this->mFilteredExifData[$prop], 8 );
 
-                       switch ($charCode) {
+                       switch ( $charCode ) {
                                case "\x4A\x49\x53\x00\x00\x00\x00\x00":
                                        //JIS
                                        $charset = "Shift-JIS";
@@ -466,9 +466,9 @@ class Exif {
                        }
                        // This could possibly check to see if iconv is really installed
                        // or if we're using the compatibility wrapper in globalFunctions.php
-                       if ($charset) {
+                       if ( $charset ) {
                                wfSuppressWarnings();
-                               $val = iconv($charset, 'UTF-8//IGNORE', $val);
+                               $val = iconv( $charset, 'UTF-8//IGNORE', $val );
                                wfRestoreWarnings();
                        } else {
                                // if valid utf-8, assume that, otherwise assume windows-1252
@@ -476,17 +476,17 @@ class Exif {
                                UtfNormal::quickIsNFCVerify( $valCopy ); //validates $valCopy.
                                if ( $valCopy !== $val ) {
                                        wfSuppressWarnings();
-                                       $val = iconv('Windows-1252', 'UTF-8//IGNORE', $val);
+                                       $val = iconv( 'Windows-1252', 'UTF-8//IGNORE', $val );
                                        wfRestoreWarnings();
                                }
                        }
 
                        //trim and check to make sure not only whitespace.
-                       $val = trim($val);
+                       $val = trim( $val );
                        if ( strlen( $val ) === 0 ) {
                                //only whitespace.
-                               $this->debug( $this->mFilteredExifData[$prop] , __FUNCTION__, "$prop: Is only whitespace" );
-                               unset($this->mFilteredExifData[$prop]);
+                               $this->debug( $this->mFilteredExifData[$prop], __FUNCTION__, "$prop: Is only whitespace" );
+                               unset( $this->mFilteredExifData[$prop] );
                                return;
                        }
 
@@ -580,7 +580,7 @@ class Exif {
         */
        function getFormattedData() {
                wfDeprecated( __METHOD__, '1.18' );
-               if (!$this->mFormattedExifData) {
+               if ( !$this->mFormattedExifData ) {
                        $this->makeFormattedData();
                }
                return $this->mFormattedExifData;
@@ -612,7 +612,7 @@ class Exif {
         * @return bool
         */
        private function isByte( $in ) {
-               if ( !is_array( $in ) && sprintf('%d', $in) == $in && $in >= 0 && $in <= 255 ) {
+               if ( !is_array( $in ) && sprintf( '%d', $in ) == $in && $in >= 0 && $in <= 255 ) {
                        $this->debug( $in, __FUNCTION__, true );
                        return true;
                } else {
@@ -648,7 +648,7 @@ class Exif {
         * @return bool
         */
        private function isShort( $in ) {
-               if ( !is_array( $in ) && sprintf('%d', $in) == $in && $in >= 0 && $in <= 65536 ) {
+               if ( !is_array( $in ) && sprintf( '%d', $in ) == $in && $in >= 0 && $in <= 65536 ) {
                        $this->debug( $in, __FUNCTION__, true );
                        return true;
                } else {
@@ -662,7 +662,7 @@ class Exif {
         * @return bool
         */
        private function isLong( $in ) {
-               if ( !is_array( $in ) && sprintf('%d', $in) == $in && $in >= 0 && $in <= 4294967296 ) {
+               if ( !is_array( $in ) && sprintf( '%d', $in ) == $in && $in >= 0 && $in <= 4294967296 ) {
                        $this->debug( $in, __FUNCTION__, true );
                        return true;
                } else {
@@ -813,13 +813,13 @@ class Exif {
                }
 
                if ( $action === true ) {
-                       wfDebugLog( $this->log, "$class::$fname: accepted: '$in' (type: $type)\n");
+                       wfDebugLog( $this->log, "$class::$fname: accepted: '$in' (type: $type)\n" );
                } elseif ( $action === false ) {
-                       wfDebugLog( $this->log, "$class::$fname: rejected: '$in' (type: $type)\n");
+                       wfDebugLog( $this->log, "$class::$fname: rejected: '$in' (type: $type)\n" );
                } elseif ( $action === null ) {
-                       wfDebugLog( $this->log, "$class::$fname: input was: '$in' (type: $type)\n");
+                       wfDebugLog( $this->log, "$class::$fname: input was: '$in' (type: $type)\n" );
                } else {
-                       wfDebugLog( $this->log, "$class::$fname: $action (type: $type; content: '$in')\n");
+                       wfDebugLog( $this->log, "$class::$fname: $action (type: $type; content: '$in')\n" );
                }
        }
 
@@ -843,4 +843,3 @@ class Exif {
                }
        }
 }
-
index 34a1f51..1671ab2 100644 (file)
@@ -34,8 +34,8 @@ class ExifBitmapHandler extends BitmapHandler {
 
        function convertMetadataVersion( $metadata, $version = 1 ) {
                // basically flattens arrays.
-               $version = explode(';', $version, 2);
-               $version = intval($version[0]);
+               $version = explode( ';', $version, 2 );
+               $version = intval( $version[0] );
                if ( $version < 1 || $version >= 2 ) {
                        return $metadata;
                }
@@ -56,7 +56,7 @@ class ExifBitmapHandler extends BitmapHandler {
                        && is_array( $metadata['Software'][0])
                        && isset( $metadata['Software'][0][0] )
                        && isset( $metadata['Software'][0][1])
-                ) {
+               ) {
                        $metadata['Software'] = $metadata['Software'][0][0] . ' (Version '
                                . $metadata['Software'][0][1] . ')';
                }
@@ -86,7 +86,7 @@ class ExifBitmapHandler extends BitmapHandler {
                if ( $metadata === self::OLD_BROKEN_FILE ) {
                        # Old special value indicating that there is no EXIF data in the file.
                        # or that there was an error well extracting the metadata.
-                       wfDebug( __METHOD__ . ": back-compat version\n");
+                       wfDebug( __METHOD__ . ": back-compat version\n" );
                        return self::METADATA_COMPATIBLE;
                }
                if ( $metadata === self::BROKEN_FILE ) {
@@ -102,11 +102,11 @@ class ExifBitmapHandler extends BitmapHandler {
                                $exif['MEDIAWIKI_EXIF_VERSION'] == 1 )
                        {
                                //back-compatible but old
-                               wfDebug( __METHOD__.": back-compat version\n" );
+                               wfDebug( __METHOD__ . ": back-compat version\n" );
                                return self::METADATA_COMPATIBLE;
                        }
                        # Wrong (non-compatible) version
-                       wfDebug( __METHOD__.": wrong version\n" );
+                       wfDebug( __METHOD__ . ": wrong version\n" );
                        return self::METADATA_BAD;
                }
                return self::METADATA_GOOD;
@@ -163,7 +163,7 @@ class ExifBitmapHandler extends BitmapHandler {
                        $rotation = 0;
                }
 
-               if ($rotation == 90 || $rotation == 270) {
+               if ( $rotation == 90 || $rotation == 270 ) {
                        $width = $gis[0];
                        $gis[0] = $gis[1];
                        $gis[1] = $width;
@@ -225,4 +225,3 @@ class ExifBitmapHandler extends BitmapHandler {
                return 0;
        }
 }
-
index d44dfd1..97aa28b 100644 (file)
@@ -80,20 +80,20 @@ class FormatMetadata {
                        }
 
                        //This is done differently as the tag is an array.
-                       if ($tag == 'GPSTimeStamp' && count($vals) === 3) {
+                       if ( $tag == 'GPSTimeStamp' && count( $vals ) === 3) {
                                //hour min sec array
 
-                               $h = explode('/', $vals[0]);
-                               $m = explode('/', $vals[1]);
-                               $s = explode('/', $vals[2]);
+                               $h = explode( '/', $vals[0] );
+                               $m = explode( '/', $vals[1] );
+                               $s = explode( '/', $vals[2] );
 
                                // this should already be validated
                                // when loaded from file, but it could
                                // come from a foreign repo, so be
                                // paranoid.
-                               if ( !isset($h[1])
-                                       || !isset($m[1])
-                                       || !isset($s[1])
+                               if ( !isset( $h[1] )
+                                       || !isset( $m[1] )
+                                       || !isset( $s[1] )
                                        || $h[1] == 0
                                        || $m[1] == 0
                                        || $s[1] == 0
@@ -322,7 +322,7 @@ class FormatMetadata {
                                                if ( $subTag != 'fired' && $subValue == 0 ) {
                                                        continue;
                                                }
-                                               $fullTag = $tag . '-' . $subTag ;
+                                               $fullTag = $tag . '-' . $subTag;
                                                $flashMsgs[] = self::msg( $fullTag, $subValue );
                                        }
                                        $val = $wgLang->commaList( $flashMsgs );
@@ -631,7 +631,7 @@ class FormatMetadata {
                                case 'MaxApertureValue':
                                        if ( strpos( $val, '/' ) !== false ) {
                                                // need to expand this earlier to calculate fNumber
-                                               list($n, $d) = explode('/', $val);
+                                               list( $n, $d ) = explode( '/', $val );
                                                if ( is_numeric( $n ) && is_numeric( $d ) ) {
                                                        $val = $n / $d;
                                                }
@@ -809,7 +809,7 @@ class FormatMetadata {
 
                                case 'LanguageCode':
                                        $lang = Language::fetchLanguageName( strtolower( $val ), $wgLang->getCode() );
-                                       if ($lang) {
+                                       if ( $lang ) {
                                                $val = htmlspecialchars( $lang );
                                        } else {
                                                $val = htmlspecialchars( $val );
@@ -850,7 +850,7 @@ class FormatMetadata {
                }
 
                if ( !is_array( $vals ) ) {
-                        return $vals; // do nothing if not an array;
+                       return $vals; // do nothing if not an array;
                }
                elseif ( count( $vals ) === 1 && $type !== 'lang' ) {
                        return $vals[0];
@@ -899,7 +899,7 @@ class FormatMetadata {
                                        }
                                        $content .= self::langItem(
                                                $vals[$cLang], $cLang,
-                                                $isDefault, $noHtml );
+                                               $isDefault, $noHtml );
 
                                        unset( $vals[$cLang] );
                                }
@@ -915,8 +915,8 @@ class FormatMetadata {
                                }
                                if ( $defaultItem !== false ) {
                                        $content = self::langItem( $defaultItem,
-                                               $defaultLang, true, $noHtml )
-                                                . $content;
+                                               $defaultLang, true, $noHtml ) .
+                                               $content;
                                }
                                if ( $noHtml ) {
                                        return $content;
@@ -951,8 +951,8 @@ class FormatMetadata {
         */
        private static function langItem( $value, $lang, $default = false, $noHtml = false ) {
                if ( $lang === false && $default === false) {
-                       throw new MWException('$lang and $default cannot both '
-                               . 'be false.');
+                       throw new MWException( '$lang and $default cannot both '
+                               . 'be false.' );
                }
 
                if ( $noHtml ) {
@@ -1017,7 +1017,7 @@ class FormatMetadata {
        static function msg( $tag, $val, $arg = null, $arg2 = null ) {
                global $wgContLang;
 
-               if ($val === '')
+               if ( $val === '' )
                        $val = 'value';
                return wfMessage( $wgContLang->lc( "exif-$tag-$val" ), $arg, $arg2 )->text();
        }
@@ -1033,10 +1033,10 @@ class FormatMetadata {
        static function formatNum( $num, $round = false ) {
                global $wgLang;
                $m = array();
-               if( is_array($num) ) {
+               if( is_array( $num ) ) {
                        $out = array();
                        foreach( $num as $number ) {
-                               $out[] = self::formatNum($number);
+                               $out[] = self::formatNum( $number );
                        }
                        return $wgLang->commaList( $out );
                }
@@ -1126,7 +1126,7 @@ class FormatMetadata {
                        return $val;
                }
                $cat = '';
-               switch( substr( $val , 0, 2 ) ) {
+               switch( substr( $val, 0, 2 ) ) {
                        case '01':
                                $cat = 'ace';
                                break;
@@ -1238,7 +1238,7 @@ class FormatMetadata {
         * @return String of html-ish looking wikitext
         */
        public static function collapseContactInfo( $vals ) {
-               if( ! ( isset( $vals['CiAdrExtadr'] )
+               if( !( isset( $vals['CiAdrExtadr'] )
                        || isset( $vals['CiAdrCity'] )
                        || isset( $vals['CiAdrCtry'] )
                        || isset( $vals['CiEmailWork'] )
index da8fc6f..2e532fe 100644 (file)
@@ -39,7 +39,7 @@ class GIFHandler extends BitmapHandler {
                        return self::BROKEN_FILE;
                }
 
-               return serialize($parsedGIFMetadata);
+               return serialize( $parsedGIFMetadata );
        }
 
        /**
@@ -53,7 +53,7 @@ class GIFHandler extends BitmapHandler {
                        return false;
                }
                $meta = unserialize( $meta );
-                if ( !isset( $meta['metadata'] ) || count( $meta['metadata'] ) <= 1 ) {
+               if ( !isset( $meta['metadata'] ) || count( $meta['metadata'] ) <= 1 ) {
                        return false;
                }
 
@@ -85,7 +85,7 @@ class GIFHandler extends BitmapHandler {
        function isAnimatedImage( $image ) {
                $ser = $image->getMetadata();
                if ( $ser ) {
-                       $metadata = unserialize($ser);
+                       $metadata = unserialize( $ser );
                        if( $metadata['frameCount'] > 1 ) {
                                return true;
                        }
@@ -119,13 +119,13 @@ class GIFHandler extends BitmapHandler {
                wfRestoreWarnings();
 
                if ( !$data || !is_array( $data ) ) {
-                       wfDebug(__METHOD__ . ' invalid GIF metadata' );
+                       wfDebug( __METHOD__ . ' invalid GIF metadata' );
                        return self::METADATA_BAD;
                }
 
                if ( !isset( $data['metadata']['_MW_GIF_VERSION'] )
                        || $data['metadata']['_MW_GIF_VERSION'] != GIFMetadataExtractor::VERSION ) {
-                       wfDebug(__METHOD__ . ' old but compatible GIF metadata' );
+                       wfDebug( __METHOD__ . ' old but compatible GIF metadata' );
                        return self::METADATA_COMPATIBLE;
                }
                return self::METADATA_GOOD;
@@ -141,10 +141,10 @@ class GIFHandler extends BitmapHandler {
                $original = parent::getLongDesc( $image );
 
                wfSuppressWarnings();
-               $metadata = unserialize($image->getMetadata());
+               $metadata = unserialize( $image->getMetadata() );
                wfRestoreWarnings();
 
-               if (!$metadata || $metadata['frameCount'] <=  1) {
+               if ( !$metadata || $metadata['frameCount'] <= 1 ) {
                        return $original;
                }
 
index 7a162c3..8b44585 100644 (file)
@@ -49,9 +49,9 @@ class GIFMetadataExtractor {
         * @return array
         */
        static function getMetadata( $filename ) {
-               self::$gif_frame_sep = pack( "C", ord("," ) );
-               self::$gif_extension_sep = pack( "C", ord("!" ) );
-               self::$gif_term = pack( "C", ord(";" ) );
+               self::$gif_frame_sep = pack( "C", ord( "," ) );
+               self::$gif_extension_sep = pack( "C", ord( "!" ) );
+               self::$gif_term = pack( "C", ord( ";" ) );
 
                $frameCount = 0;
                $duration = 0.0;
@@ -73,7 +73,7 @@ class GIFMetadataExtractor {
 
                // Check for the GIF header
                $buf = fread( $fh, 6 );
-               if ( !($buf == 'GIF87a' || $buf == 'GIF89a') ) {
+               if ( !( $buf == 'GIF87a' || $buf == 'GIF89a' ) ) {
                        throw new Exception( "Not a valid GIF file; header: $buf" );
                }
 
@@ -93,7 +93,7 @@ class GIFMetadataExtractor {
                while( !feof( $fh ) ) {
                        $buf = fread( $fh, 1 );
 
-                       if ($buf == self::$gif_frame_sep) {
+                       if ( $buf == self::$gif_frame_sep ) {
                                // Found a frame
                                $frameCount++;
 
@@ -114,7 +114,7 @@ class GIFMetadataExtractor {
                                $extension_code = unpack( 'C', $buf );
                                $extension_code = $extension_code[1];
 
-                               if ($extension_code == 0xF9) {
+                               if ( $extension_code == 0xF9 ) {
                                        // Graphics Control Extension.
                                        fread( $fh, 1 ); // Block size
 
@@ -132,10 +132,10 @@ class GIFMetadataExtractor {
                                        if ( strlen( $term ) < 1 ) throw new Exception( "Ran out of input" );
                                        $term = unpack( 'C', $term );
                                        $term = $term[1];
-                                       if ($term != 0 ) {
+                                       if ( $term != 0 ) {
                                                throw new Exception( "Malformed Graphics Control Extension block" );
                                        }
-                               } elseif ($extension_code == 0xFE) {
+                               } elseif ( $extension_code == 0xFE ) {
                                        // Comment block(s).
                                        $data = self::readBlock( $fh );
                                        if ( $data === "" ) {
@@ -164,7 +164,7 @@ class GIFMetadataExtractor {
                                                // is identical to the last, only extract once.
                                                $comment[] = $data;
                                        }
-                               } elseif ($extension_code == 0xFF) {
+                               } elseif ( $extension_code == 0xFF ) {
                                        // Application extension (Netscape info about the animated gif)
                                        // or XMP (or theoretically any other type of extension block)
                                        $blockLength = fread( $fh, 1 );
@@ -173,7 +173,7 @@ class GIFMetadataExtractor {
                                        $blockLength = $blockLength[1];
                                        $data = fread( $fh, $blockLength );
 
-                                       if ($blockLength != 11 ) {
+                                       if ( $blockLength != 11 ) {
                                                wfDebug( __METHOD__ . ' GIF application block with wrong length' );
                                                fseek( $fh, -($blockLength + 1), SEEK_CUR );
                                                self::skipBlock( $fh );
@@ -184,7 +184,7 @@ class GIFMetadataExtractor {
                                        if ( $data == 'NETSCAPE2.0' ) {
                                                $data = fread( $fh, 2 ); // Block length and introduction, should be 03 01
 
-                                               if ($data != "\x03\x01") {
+                                               if ( $data != "\x03\x01" ) {
                                                        throw new Exception( "Expected \x03\x01, got $data" );
                                                }
 
@@ -194,7 +194,7 @@ class GIFMetadataExtractor {
                                                $loopData = unpack( 'v', $loopData );
                                                $loopCount = $loopData[1];
 
-                                               if ($loopCount != 1) {
+                                               if ( $loopCount != 1 ) {
                                                        $isLooped = true;
                                                }
 
@@ -231,7 +231,7 @@ class GIFMetadataExtractor {
                                if ( strlen( $buf ) < 1 ) throw new Exception( "Ran out of input" );
                                $byte = unpack( 'C', $buf );
                                $byte = $byte[1];
-                               throw new Exception( "At position: ".ftell($fh). ", Unknown byte ".$byte );
+                               throw new Exception( "At position: " . ftell( $fh ) . ", Unknown byte " . $byte );
                        }
                }
 
@@ -284,7 +284,7 @@ class GIFMetadataExtractor {
                        if ( strlen( $buf ) < 1 ) throw new Exception( "Ran out of input" );
                        $block_len = unpack( 'C', $buf );
                        $block_len = $block_len[1];
-                       if ($block_len == 0) {
+                       if ( $block_len == 0 ) {
                                return;
                        }
                        fread( $fh, $block_len );
index 8fd3552..06cbc3b 100644 (file)
@@ -41,15 +41,15 @@ class IPTC {
        static function parse( $rawData ) {
                $parsed = iptcparse( $rawData );
                $data = Array();
-               if (!is_array($parsed)) {
+               if ( !is_array( $parsed ) ) {
                                return $data;
                }
 
                $c = '';
                //charset info contained in tag 1:90.
-               if (isset($parsed['1#090']) && isset($parsed['1#090'][0])) {
-                       $c = self::getCharset($parsed['1#090'][0]);
-                       if ($c === false) {
+               if ( isset( $parsed['1#090'] ) && isset( $parsed['1#090'][0] ) ) {
+                       $c = self::getCharset( $parsed['1#090'][0] );
+                       if ( $c === false ) {
                                //Unknown charset. refuse to parse.
                                //note: There is a different between
                                //unknown and no charset specified.
@@ -59,8 +59,8 @@ class IPTC {
                }
 
                foreach ( $parsed as $tag => $val ) {
-                       if ( isset( $val[0] ) && trim($val[0]) == '' ) {
-                               wfDebugLog('iptc', "IPTC tag $tag had only whitespace as its value.");
+                       if ( isset( $val[0] ) && trim( $val[0] ) == '' ) {
+                               wfDebugLog( 'iptc', "IPTC tag $tag had only whitespace as its value." );
                                continue;
                        }
                        switch( $tag ) {
@@ -175,7 +175,7 @@ class IPTC {
                                        if ( isset( $parsed['2#070'] ) ) {
                                                //if a version is set for the software.
                                                $softwareVersion = self::convIPTC( $parsed['2#070'], $c );
-                                               unset($parsed['2#070']);
+                                               unset( $parsed['2#070'] );
                                                $data['Software'] = array( array( $software[0], $softwareVersion[0] ) );
                                        } else {
                                                $data['Software'] = $software;
@@ -227,8 +227,8 @@ class IPTC {
                                        } else {
                                                $time = Array();
                                        }
-                                       $timestamp =  self::timeHelper( $val, $time, $c );
-                                       if ($timestamp) {
+                                       $timestamp = self::timeHelper( $val, $time, $c );
+                                       if ( $timestamp ) {
                                                $data['DateTimeOriginal'] = $timestamp;
                                        }
                                        break;
@@ -241,8 +241,8 @@ class IPTC {
                                        } else {
                                                $time = Array();
                                        }
-                                       $timestamp =  self::timeHelper( $val, $time, $c );
-                                       if ($timestamp) {
+                                       $timestamp = self::timeHelper( $val, $time, $c );
+                                       if ( $timestamp ) {
                                                $data['DateTimeDigitized'] = $timestamp;
                                        }
                                        break;
@@ -254,8 +254,8 @@ class IPTC {
                                        } else {
                                                $time = Array();
                                        }
-                                       $timestamp =  self::timeHelper( $val, $time, $c );
-                                       if ($timestamp) {
+                                       $timestamp = self::timeHelper( $val, $time, $c );
+                                       if ( $timestamp ) {
                                                $data['DateTimeReleased'] = $timestamp;
                                        }
                                        break;
@@ -267,8 +267,8 @@ class IPTC {
                                        } else {
                                                $time = Array();
                                        }
-                                       $timestamp =  self::timeHelper( $val, $time, $c );
-                                       if ($timestamp) {
+                                       $timestamp = self::timeHelper( $val, $time, $c );
+                                       if ( $timestamp ) {
                                                $data['DateTimeExpires'] = $timestamp;
                                        }
                                        break;
@@ -313,7 +313,7 @@ class IPTC {
                                        // describing the subject matter of the content.
                                        $codes = self::convIPTC( $val, $c );
                                        foreach ( $codes as $ic ) {
-                                               $fields = explode(':', $ic, 3 );
+                                               $fields = explode( ':', $ic, 3 );
 
                                                if ( count( $fields ) < 2 ||
                                                        $fields[0] !== 'IPTC' )
@@ -362,31 +362,31 @@ class IPTC {
                if ( count( $date ) === 1 ) {
                        //the standard says this should always be 1
                        //just double checking.
-                       list($date) = self::convIPTC( $date, $c );
+                       list( $date ) = self::convIPTC( $date, $c );
                } else {
                        return null;
                }
 
                if ( count( $time ) === 1 ) {
-                       list($time) = self::convIPTC( $time, $c );
+                       list( $time ) = self::convIPTC( $time, $c );
                        $dateOnly = false;
                } else {
                        $time = '000000+0000'; //placeholder
                        $dateOnly = true;
                }
 
-               if ( ! ( preg_match('/\d\d\d\d\d\d[-+]\d\d\d\d/', $time)
-                       && preg_match('/\d\d\d\d\d\d\d\d/', $date)
-                       && substr($date, 0, 4) !== '0000'
-                       && substr($date, 4, 2) !== '00'
-                       && substr($date, 6, 2) !== '00'
-                ) ) {
+               if ( !( preg_match( '/\d\d\d\d\d\d[-+]\d\d\d\d/', $time )
+                       && preg_match( '/\d\d\d\d\d\d\d\d/', $date )
+                       && substr( $date, 0, 4 ) !== '0000'
+                       && substr( $date, 4, 2 ) !== '00'
+                       && substr( $date, 6, 2 ) !== '00'
+               ) ) {
                        //something wrong.
                        // Note, this rejects some valid dates according to iptc spec
                        // for example: the date 00000400 means the photo was taken in
                        // April, but the year and day is unknown. We don't process these
                        // types of incomplete dates atm.
-                       wfDebugLog( 'iptc', "IPTC: invalid time ( $time ) or date ( $date )");
+                       wfDebugLog( 'iptc', "IPTC: invalid time ( $time ) or date ( $date )" );
                        return null;
                }
 
@@ -425,7 +425,7 @@ class IPTC {
        */
        private static function convIPTC ( $data, $charset ) {
                if ( is_array( $data ) ) {
-                       foreach ($data as &$val) {
+                       foreach ( $data as &$val ) {
                                $val = self::convIPTCHelper( $val, $charset );
                        }
                } else {
@@ -444,18 +444,18 @@ class IPTC {
        private static function convIPTCHelper ( $data, $charset ) {
                if ( $charset ) {
                        wfSuppressWarnings();
-                       $data = iconv($charset, "UTF-8//IGNORE", $data);
+                       $data = iconv( $charset, "UTF-8//IGNORE", $data );
                        wfRestoreWarnings();
-                       if ($data === false) {
+                       if ( $data === false ) {
                                $data = "";
-                               wfDebugLog('iptc', __METHOD__ . " Error converting iptc data charset $charset to utf-8");
+                               wfDebugLog( 'iptc', __METHOD__ . " Error converting iptc data charset $charset to utf-8" );
                        }
                } else {
                        //treat as utf-8 if is valid utf-8. otherwise pretend its windows-1252
                        // most of the time if there is no 1:90 tag, it is either ascii, latin1, or utf-8
                        $oldData = $data;
                        UtfNormal::quickIsNFCVerify( $data ); //make $data valid utf-8
-                       if ($data === $oldData) {
+                       if ( $data === $oldData ) {
                                return $data; //if validation didn't change $data
                        } else {
                                return self::convIPTCHelper( $oldData, 'Windows-1252' );
@@ -472,7 +472,7 @@ class IPTC {
        * all iso 2022 escape codes. In practise, the code for utf-8 is the
        * only code that seems to have wide use. It does detect that code.
        */
-       static function getCharset($tag) {
+       static function getCharset( $tag ) {
 
                //According to iim standard, charset is defined by the tag 1:90.
                //in which there are iso 2022 escape sequences to specify the character set.
@@ -590,7 +590,7 @@ class IPTC {
                                $c = 'CSN_369103';
                                break;
                        default:
-                               wfDebugLog('iptc', __METHOD__ . 'Unknown charset in iptc 1:90: ' . bin2hex( $tag ) );
+                               wfDebugLog( 'iptc', __METHOD__ . 'Unknown charset in iptc 1:90: ' . bin2hex( $tag ) );
                                //at this point just give up and refuse to parse iptc?
                                $c = false;
                }
index d1de0ae..472372c 100644 (file)
@@ -162,11 +162,11 @@ abstract class ImageHandler extends MediaHandler {
 
                # Sanity check $width
                if( $width <= 0) {
-                       wfDebug( __METHOD__.": Invalid destination width: $width\n" );
+                       wfDebug( __METHOD__ . ": Invalid destination width: $width\n" );
                        return false;
                }
                if ( $srcWidth <= 0 ) {
-                       wfDebug( __METHOD__.": Invalid source width: $srcWidth\n" );
+                       wfDebug( __METHOD__ . ": Invalid source width: $srcWidth\n" );
                        return false;
                }
 
index a15b652..5ea30f2 100644 (file)
@@ -37,7 +37,7 @@ class JpegHandler extends ExifBitmapHandler {
                        $meta = BitmapMetadataHandler::Jpeg( $filename );
                        if ( !is_array( $meta ) ) {
                                // This should never happen, but doesn't hurt to be paranoid.
-                               throw new MWException('Metadata array is not an array');
+                               throw new MWException( 'Metadata array is not an array' );
                        }
                        $meta['MEDIAWIKI_EXIF_VERSION'] = Exif::version();
                        return serialize( $meta );
@@ -60,4 +60,3 @@ class JpegHandler extends ExifBitmapHandler {
        }
 
 }
-
index dd764e9..46993e7 100644 (file)
@@ -46,7 +46,7 @@ abstract class MediaHandler {
        static function getHandler( $type ) {
                global $wgMediaHandlers;
                if ( !isset( $wgMediaHandlers[$type] ) ) {
-                       wfDebug( __METHOD__ . ": no handler found for $type.\n");
+                       wfDebug( __METHOD__ . ": no handler found for $type.\n" );
                        return false;
                }
                $class = $wgMediaHandlers[$type];
@@ -135,9 +135,9 @@ abstract class MediaHandler {
        */
        static function getMetadataVersion () {
                $version = Array( '2' ); // core metadata version
-               wfRunHooks('GetMetadataVersion', Array(&$version));
+               wfRunHooks( 'GetMetadataVersion', Array( &$version ) );
                return implode( ';', $version);
-        }
+       }
 
        /**
        * Convert metadata version.
@@ -365,7 +365,7 @@ abstract class MediaHandler {
         * @return array for use displaying metadata.
         */
        function formatMetadataHelper( $metadataArray ) {
-                $result = array(
+               $result = array(
                        'visible' => array(),
                        'collapsed' => array()
                );
index 110c659..1fbe029 100644 (file)
@@ -198,10 +198,10 @@ abstract class MediaTransformOutput {
        public function getDescLinkAttribs( $title = null, $params = '' ) {
                $query = '';
                if ( $this->page && $this->page !== 1 ) {
-                         $query = 'page=' . urlencode( $this->page );
+                       $query = 'page=' . urlencode( $this->page );
                }
                if( $params ) {
-                       $query .= $query ? '&'.$params : $params;
+                       $query .= $query ? '&' . $params : $params;
                }
                $attribs = array(
                        'href' => $this->file->getTitle()->getLocalURL( $query ),
@@ -301,7 +301,7 @@ class ThumbnailImage extends MediaTransformOutput {
 
                $alt = empty( $options['alt'] ) ? '' : $options['alt'];
 
-               $query = empty( $options['desc-query'] )  ? '' : $options['desc-query'];
+               $query = empty( $options['desc-query'] ) ? '' : $options['desc-query'];
 
                if ( !empty( $options['custom-url-link'] ) ) {
                        $linkAttribs = array( 'href' => $options['custom-url-link'] );
@@ -404,7 +404,7 @@ class MediaTransformError extends MediaTransformOutput {
 class TransformParameterError extends MediaTransformError {
        function __construct( $params ) {
                parent::__construct( 'thumbnail_error',
-                       max( isset( $params['width']  ) ? $params['width']  : 0, 120 ),
+                       max( isset( $params['width'] ) ? $params['width'] : 0, 120 ),
                        max( isset( $params['height'] ) ? $params['height'] : 0, 120 ),
                        wfMessage( 'thumbnail_invalid_params' )->text() );
        }
index a23821f..b8a5b40 100644 (file)
@@ -44,7 +44,7 @@ class PNGHandler extends BitmapHandler {
                        return self::BROKEN_FILE;
                }
 
-               return serialize($metadata);
+               return serialize( $metadata );
        }
 
        /**
@@ -74,8 +74,8 @@ class PNGHandler extends BitmapHandler {
         */
        function isAnimatedImage( $image ) {
                $ser = $image->getMetadata();
-               if ($ser) {
-                       $metadata = unserialize($ser);
+               if ( $ser ) {
+                       $metadata = unserialize( $ser );
                        if( $metadata['frameCount'] > 1 ) return true;
                }
                return false;
@@ -105,13 +105,13 @@ class PNGHandler extends BitmapHandler {
                wfRestoreWarnings();
 
                if ( !$data || !is_array( $data ) ) {
-                       wfDebug(__METHOD__ . ' invalid png metadata' );
+                       wfDebug( __METHOD__ . ' invalid png metadata' );
                        return self::METADATA_BAD;
                }
 
                if ( !isset( $data['metadata']['_MW_PNG_VERSION'] )
                        || $data['metadata']['_MW_PNG_VERSION'] != PNGMetadataExtractor::VERSION ) {
-                       wfDebug(__METHOD__ . ' old but compatible png metadata' );
+                       wfDebug( __METHOD__ . ' old but compatible png metadata' );
                        return self::METADATA_COMPATIBLE;
                }
                return self::METADATA_GOOD;
@@ -126,7 +126,7 @@ class PNGHandler extends BitmapHandler {
                $original = parent::getLongDesc( $image );
 
                wfSuppressWarnings();
-               $metadata = unserialize($image->getMetadata());
+               $metadata = unserialize( $image->getMetadata() );
                wfRestoreWarnings();
 
                if( !$metadata || $metadata['frameCount'] <= 0 )
index f7e988f..cddab51 100644 (file)
@@ -170,14 +170,14 @@ class SvgHandler extends ImageHandler {
                                $cmd = str_replace(
                                        array( '$path/', '$width', '$height', '$input', '$output' ),
                                        array( $wgSVGConverterPath ? wfEscapeShellArg( "$wgSVGConverterPath/" ) : "",
-                                                  intval( $width ),
-                                                  intval( $height ),
-                                                  wfEscapeShellArg( $srcPath ),
-                                                  wfEscapeShellArg( $dstPath ) ),
+                                               intval( $width ),
+                                               intval( $height ),
+                                               wfEscapeShellArg( $srcPath ),
+                                               wfEscapeShellArg( $dstPath ) ),
                                        $wgSVGConverters[$wgSVGConverter]
                                ) . " 2>&1";
                                wfProfileIn( 'rsvg' );
-                               wfDebug( __METHOD__.": $cmd\n" );
+                               wfDebug( __METHOD__ . ": $cmd\n" );
                                $err = wfShellExec( $cmd, $retval );
                                wfProfileOut( 'rsvg' );
                        }
@@ -185,7 +185,7 @@ class SvgHandler extends ImageHandler {
                $removed = $this->removeBadFile( $dstPath, $retval );
                if ( $retval != 0 || $removed ) {
                        wfDebugLog( 'thumbnail', sprintf( 'thumbnail failed on %s: error %d "%s" from "%s"',
-                                       wfHostname(), $retval, trim($err), $cmd ) );
+                                       wfHostname(), $retval, trim( $err ), $cmd ) );
                        return new MediaTransformError( 'thumbnail_error', $width, $height, $err );
                }
                return true;
index d6624ee..e4235a7 100644 (file)
@@ -67,7 +67,7 @@ class SVGReader {
                if ( $size > $wgSVGMetadataCutoff ) {
                        $this->debug( "SVG is $size bytes, which is bigger than $wgSVGMetadataCutoff. Truncating." );
                        $contents = file_get_contents( $source, false, null, -1, $wgSVGMetadataCutoff );
-                       if ($contents === false) {
+                       if ( $contents === false ) {
                                throw new MWException( 'Error reading SVG file.' );
                        }
                        $this->reader->XML( $contents, null, LIBXML_NOERROR | LIBXML_NOWARNING );
@@ -132,7 +132,7 @@ class SVGReader {
                $this->debug( "<svg> tag is correct." );
                $this->handleSVGAttribs();
 
-               $exitDepth =  $this->reader->depth;
+               $exitDepth = $this->reader->depth;
                $keepReading = $this->reader->read();
                while ( $keepReading ) {
                        $tag = $this->reader->localName;
@@ -227,7 +227,7 @@ class SVGReader {
                if ( $this->reader->isEmptyElement ) {
                        return;
                }
-               $exitDepth =  $this->reader->depth;
+               $exitDepth = $this->reader->depth;
                $keepReading = $this->reader->read();
                while( $keepReading ) {
                        if( $this->reader->localName == $name && $this->reader->depth <= $exitDepth
@@ -285,9 +285,9 @@ class SVGReader {
                $width = null;
                $height = null;
 
-               if( $this->reader->getAttribute('viewBox') ) {
+               if( $this->reader->getAttribute( 'viewBox' ) ) {
                        // min-x min-y width height
-                       $viewBox = preg_split( '/\s+/', trim( $this->reader->getAttribute('viewBox') ) );
+                       $viewBox = preg_split( '/\s+/', trim( $this->reader->getAttribute( 'viewBox' ) ) );
                        if( count( $viewBox ) == 4 ) {
                                $viewWidth = $this->scaleSVGUnit( $viewBox[2] );
                                $viewHeight = $this->scaleSVGUnit( $viewBox[3] );
@@ -297,12 +297,12 @@ class SVGReader {
                                }
                        }
                }
-               if( $this->reader->getAttribute('width') ) {
-                       $width = $this->scaleSVGUnit( $this->reader->getAttribute('width'), $defaultWidth );
+               if( $this->reader->getAttribute( 'width' ) ) {
+                       $width = $this->scaleSVGUnit( $this->reader->getAttribute( 'width' ), $defaultWidth );
                        $this->metadata['originalWidth'] = $this->reader->getAttribute( 'width' );
                }
-               if( $this->reader->getAttribute('height') ) {
-                       $height = $this->scaleSVGUnit( $this->reader->getAttribute('height'), $defaultHeight );
+               if( $this->reader->getAttribute( 'height' ) ) {
+                       $height = $this->scaleSVGUnit( $this->reader->getAttribute( 'height' ), $defaultHeight );
                        $this->metadata['originalHeight'] = $this->reader->getAttribute( 'height' );
                }
 
@@ -329,7 +329,7 @@ class SVGReader {
         * @param $viewportSize: Float optional scale for percentage units...
         * @return float: length in pixels
         */
-       static function scaleSVGUnit( $length, $viewportSize=512 ) {
+       static function scaleSVGUnit( $length, $viewportSize = 512 ) {
                static $unitLength = array(
                        'px' => 1.0,
                        'pt' => 1.25,
index 55dff77..0042208 100644 (file)
@@ -82,7 +82,7 @@ class TiffHandler extends ExifBitmapHandler {
                                $meta = BitmapMetadataHandler::Tiff( $filename );
                                if ( !is_array( $meta ) ) {
                                        // This should never happen, but doesn't hurt to be paranoid.
-                                       throw new MWException('Metadata array is not an array');
+                                       throw new MWException( 'Metadata array is not an array' );
                                }
                                $meta['MEDIAWIKI_EXIF_VERSION'] = Exif::version();
                                return serialize( $meta );
index 555fa1f..ba0d419 100644 (file)
@@ -84,7 +84,7 @@ class XCFHandler extends BitmapHandler {
                # The image structure always starts at offset 0 in the XCF file.
                # So we just read it :-)
                $binaryHeader = fread( $f, 26 );
-               fclose($f);
+               fclose( $f );
 
                # Master image structure:
                #
index c5743d7..0decb75 100644 (file)
@@ -114,7 +114,7 @@ class XMPReader {
        */
        private function resetXMLParser() {
 
-               if ($this->xmlParser) {
+               if ( $this->xmlParser ) {
                        //is this needed?
                        xml_parser_free( $this->xmlParser );
                }
@@ -156,7 +156,7 @@ class XMPReader {
 
                $data = $this->results;
 
-               wfRunHooks('XMPGetResults', Array(&$data));
+               wfRunHooks( 'XMPGetResults', Array( &$data ) );
 
                if ( isset( $data['xmp-special']['AuthorsPosition'] )
                        && is_string( $data['xmp-special']['AuthorsPosition'] )
@@ -201,7 +201,7 @@ class XMPReader {
                                        // To avoid copying over the _type meta-fields.
                                        continue;
                                }
-                               foreach(  $loc as $field => $val ) {
+                               foreach( $loc as $field => $val ) {
                                        $data['xmp-general'][$field . 'Created'][] = $val;
                                }
                        }
@@ -255,7 +255,7 @@ class XMPReader {
                        if ( !$this->charset ) {
                                $bom = array();
                                if ( preg_match( '/\xEF\xBB\xBF|\xFE\xFF|\x00\x00\xFE\xFF|\xFF\xFE\x00\x00|\xFF\xFE/',
-                                        $content, $bom )
+                                       $content, $bom )
                                ) {
                                        switch ( $bom[0] ) {
                                                case "\xFE\xFF":
@@ -275,11 +275,8 @@ class XMPReader {
                                                        break;
                                                default:
                                                        //this should be impossible to get to
-                                                       throw new MWException("Invalid BOM");
-                                                       break;
-
+                                                       throw new MWException( "Invalid BOM" );
                                        }
-
                                } else {
                                        // standard specifically says, if no bom assume utf-8
                                        $this->charset = 'UTF-8';
@@ -324,13 +321,13 @@ class XMPReader {
                $guid = substr( $content, 0, 32 );
                if ( !isset( $this->results['xmp-special']['HasExtendedXMP'] )
                        || $this->results['xmp-special']['HasExtendedXMP'] !== $guid ) {
-                       wfDebugLog('XMP', __METHOD__ . " Ignoring XMPExtended block due to wrong guid (guid= '$guid' )");
+                       wfDebugLog( 'XMP', __METHOD__ . " Ignoring XMPExtended block due to wrong guid (guid= '$guid')" );
                        return false;
                }
-               $len  = unpack( 'Nlength/Noffset', substr( $content, 32, 8 ) );
+               $len = unpack( 'Nlength/Noffset', substr( $content, 32, 8 ) );
 
-               if (!$len || $len['length'] < 4 || $len['offset'] < 0 || $len['offset'] > $len['length'] ) {
-                       wfDebugLog('XMP', __METHOD__ . 'Error reading extended XMP block, invalid length or offset.');
+               if ( !$len || $len['length'] < 4 || $len['offset'] < 0 || $len['offset'] > $len['length'] ) {
+                       wfDebugLog( 'XMP', __METHOD__ . 'Error reading extended XMP block, invalid length or offset.' );
                        return false;
                }
 
@@ -345,8 +342,8 @@ class XMPReader {
                // so the probability that it will have > 128k, and be in the wrong order is very low...
 
                if ( $len['offset'] !== $this->extendedXMPOffset ) {
-                       wfDebugLog('XMP', __METHOD__ . 'Ignoring XMPExtended block due to wrong order. (Offset was '
-                               . $len['offset'] . ' but expected ' . $this->extendedXMPOffset . ')');
+                       wfDebugLog( 'XMP', __METHOD__ . 'Ignoring XMPExtended block due to wrong order. (Offset was '
+                               . $len['offset'] . ' but expected ' . $this->extendedXMPOffset . ')' );
                        return false;
                }
 
@@ -366,7 +363,7 @@ class XMPReader {
                        $atEnd = false;
                }
 
-               wfDebugLog('XMP', __METHOD__ . 'Parsing a XMPExtended block');
+               wfDebugLog( 'XMP', __METHOD__ . 'Parsing a XMPExtended block' );
                return $this->parse( $actualContent, $atEnd );
        }
 
@@ -421,13 +418,10 @@ class XMPReader {
        * @param $elm String Namespace of element followed by a space and then tag name of element.
        */
        private function endElementModeIgnore ( $elm ) {
-
                if ( $this->curItem[0] === $elm ) {
                        array_shift( $this->curItem );
                        array_shift( $this->mode );
                }
-               return;
-
        }
 
        /**
@@ -488,7 +482,7 @@ class XMPReader {
                if ( $this->curItem[0] !== $elm
                        && !( $elm === self::NS_RDF . ' Description'
                                && $this->mode[0] === self::MODE_STRUCT )
-                ) {
+               ) {
                        throw new MWException( "nesting mismatch. got a </$elm> but expected a </" . $this->curItem[0] . '>' );
                }
 
@@ -1035,7 +1029,7 @@ class XMPReader {
 
                if ( $elm === self::NS_RDF . ' RDF'
                        || $elm === 'adobe:ns:meta/ xmpmeta'
-                       || $elm === 'adobe:ns:meta/ xapmeta')
+                       || $elm === 'adobe:ns:meta/ xapmeta' )
                {
                        /* ignore. */
                        return;
@@ -1065,7 +1059,7 @@ class XMPReader {
 
                if ( count( $this->mode ) === 0 ) {
                        // This should not happen.
-                       throw new MWException('Error extracting XMP, '
+                       throw new MWException( 'Error extracting XMP, '
                                . "encountered <$elm> with no mode" );
                }
 
@@ -1103,7 +1097,6 @@ class XMPReader {
                                break;
                        default:
                                throw new MWException( 'StartElement in unknown mode: ' . $this->mode[0] );
-                               break;
                }
        }
 
index aa411df..a4ba741 100644 (file)
@@ -35,7 +35,7 @@ class XMPInfo {
                if( !self::$ranHooks ) {
                        // This is for if someone makes a custom metadata extension.
                        // For example, a medical wiki might want to decode DICOM xmp properties.
-                       wfRunHooks('XMPGetInfo', Array(&self::$items));
+                       wfRunHooks( 'XMPGetInfo', Array( &self::$items ) );
                        self::$ranHooks = true; // Only want to do this once.
                }
                return self::$items;
@@ -260,7 +260,7 @@ class XMPInfo {
                                'mode'      => XMPReader::MODE_SIMPLE,
                                'validate'  => 'validateDate',
                        ),
-                       'DateTimeDigitized' => array(  /* xmp:CreateDate */
+                       'DateTimeDigitized' => array( /* xmp:CreateDate */
                                'map_group' => 'exif',
                                'mode'      => XMPReader::MODE_SIMPLE,
                                'validate'  => 'validateDate',
@@ -552,12 +552,12 @@ class XMPInfo {
                                'map_group' => 'exif',
                                'mode'      => XMPReader::MODE_LANG,
                        ),
-                       'DateTime'          => array(  /* proper prop is xmp:ModifyDate */
+                       'DateTime'          => array( /* proper prop is xmp:ModifyDate */
                                'map_group' => 'exif',
                                'mode'      => XMPReader::MODE_SIMPLE,
                                'validate'  => 'validateDate',
                        ),
-                       'ImageDescription'  => array(  /* proper one is dc:description */
+                       'ImageDescription'  => array( /* proper one is dc:description */
                                'map_group' => 'exif',
                                'mode'      => XMPReader::MODE_LANG,
                        ),
@@ -622,7 +622,7 @@ class XMPInfo {
                                'mode'      => XMPReader::MODE_SIMPLE,
                                'validate'  => 'validateInteger',
                        ),
-                       'Software'          => array(  /* see xmp:CreatorTool */
+                       'Software'          => array( /* see xmp:CreatorTool */
                                'map_group' => 'exif',
                                'mode'      => XMPReader::MODE_SIMPLE,
                        ),
index e3fd59f..e2ae535 100644 (file)
@@ -95,8 +95,8 @@ class XMPValidate {
                        return;
                }
                if ( !preg_match( '/^[-+]?\d*(?:\.?\d*)$/D', $val )
-                       || !is_numeric($val)
-                ) {
+                       || !is_numeric( $val )
+               ) {
                        wfDebugLog( 'XMP', __METHOD__ . " Expected rating but got $val" );
                        $val = null;
                        return;
@@ -106,12 +106,12 @@ class XMPValidate {
                                // We do < 0 here instead of < -1 here, since
                                // the values between 0 and -1 are also illegal
                                // as -1 is meant as a special reject rating.
-                               wfDebugLog( 'XMP', __METHOD__ . " Rating too low, setting to -1 (Rejected)");
+                               wfDebugLog( 'XMP', __METHOD__ . " Rating too low, setting to -1 (Rejected)" );
                                $val = '-1';
                                return;
                        }
                        if ( $nVal > 5 ) {
-                               wfDebugLog( 'XMP', __METHOD__ . " Rating too high, setting to 5");
+                               wfDebugLog( 'XMP', __METHOD__ . " Rating too high, setting to 5" );
                                $val = '5';
                                return;
                        }
@@ -247,8 +247,8 @@ class XMPValidate {
                $res = array();
                if ( !preg_match(
                        /* ahh! scary regex... */
-                       '/^([0-3]\d{3})(?:-([01]\d)(?:-([0-3]\d)(?:T([0-2]\d):([0-6]\d)(?::([0-6]\d)(?:\.\d+)?)?([-+]\d{2}:\d{2}|Z)?)?)?)?$/D'
-                       , $val, $res)
+                       '/^([0-3]\d{3})(?:-([01]\d)(?:-([0-3]\d)(?:T([0-2]\d):([0-6]\d)(?::([0-6]\d)(?:\.\d+)?)?([-+]\d{2}:\d{2}|Z)?)?)?)?$/D',
+                       $val, $res )
                ) {
                        wfDebugLog( 'XMP', __METHOD__ . " Expected date but got $val" );
                        $val = null;
index 23471e9..9dc1c86 100644 (file)
@@ -26,7 +26,7 @@
  * @ingroup UtfNormal
  */
 
-if( php_sapi_name() != 'cli' ) {
+if( PHP_SAPI != 'cli' ) {
        die( "Run me from the command line please.\n" );
 }
 
index d9deb3c..adc3ef2 100644 (file)
@@ -25,7 +25,7 @@
  * @ingroup UtfNormal
  */
 
-if( php_sapi_name() != 'cli' ) {
+if( PHP_SAPI != 'cli' ) {
        die( "Run me from the command line please.\n" );
 }
 
@@ -60,7 +60,7 @@ while( false !== ($line = fgets( $in ) ) ) {
 }
 fclose( $in );
 
-$out = fopen("Utf8Case.php", "wt");
+$out = fopen( "Utf8Case.php", "wt" );
 if( $out ) {
        $outUpperChars = escapeArray( $wikiUpperChars );
        $outLowerChars = escapeArray( $wikiLowerChars );
index 6eae6e7..904a27f 100644 (file)
@@ -34,7 +34,7 @@ mb_internal_encoding( "utf-8" );
 
 $verbose = false;
 #$verbose = true;
-if( php_sapi_name() != 'cli' ) {
+if( PHP_SAPI != 'cli' ) {
        die( "Run me from the command line please.\n" );
 }
 
index 64d9618..f5b698a 100644 (file)
@@ -627,8 +627,8 @@ class UtfNormal {
                $lastHangul = 0;
                $startChar = '';
                $combining = '';
-               $x1 = ord(substr(UTF8_HANGUL_VBASE,0,1));
-               $x2 = ord(substr(UTF8_HANGUL_TEND,0,1));
+               $x1 = ord(substr(UTF8_HANGUL_VBASE, 0, 1));
+               $x2 = ord(substr(UTF8_HANGUL_TEND, 0, 1));
                for( $i = 0; $i < $len; $i++ ) {
                        $c = $string[$i];
                        $n = ord( $c );
index 9a05b81..392ba2b 100644 (file)
@@ -34,7 +34,7 @@ require_once 'UtfNormal.php';
 
 define( 'BENCH_CYCLES', 5 );
 
-if( php_sapi_name() != 'cli' ) {
+if( PHP_SAPI != 'cli' ) {
        die( "Run me from the command line please.\n" );
 }
 
index 64624b8..b07e339 100644 (file)
@@ -26,7 +26,7 @@
  */
 
 define( 'UNICODE_HANGUL_FIRST', 0xac00 );
-define( 'UNICODE_HANGUL_LAST',  0xd7a3 );
+define( 'UNICODE_HANGUL_LAST', 0xd7a3 );
 
 define( 'UNICODE_HANGUL_LBASE', 0x1100 );
 define( 'UNICODE_HANGUL_VBASE', 0x1161 );
index 11d06d4..f392df5 100644 (file)
@@ -25,7 +25,7 @@
  * @ingroup UtfNormal
  */
 
-if( php_sapi_name() != 'cli' ) {
+if( PHP_SAPI != 'cli' ) {
        die( "Run me from the command line please.\n" );
 }
 
index 7162a8b..257e105 100644 (file)
@@ -38,7 +38,7 @@ define( 'BENCH_CYCLES', 1 );
 define( 'BIGSIZE', 1024 * 1024 * 10); // 10m
 ini_set('memory_limit', BIGSIZE + 120 * 1024 * 1024);
 
-if( php_sapi_name() != 'cli' ) {
+if( PHP_SAPI != 'cli' ) {
        die( "Run me from the command line please.\n" );
 }
 
index 5872ec3..22e6471 100644 (file)
@@ -54,7 +54,7 @@ require_once 'UtfNormalDefines.php';
 require_once 'UtfNormalUtil.php';
 require_once 'UtfNormal.php';
 
-if( php_sapi_name() != 'cli' ) {
+if( PHP_SAPI != 'cli' ) {
        die( "Run me from the command line please.\n" );
 }
 
index 691bfaa..f4a8379 100644 (file)
@@ -22,7 +22,7 @@
  * @ingroup UtfNormal
  */
 
-if( php_sapi_name() != 'cli' ) {
+if( PHP_SAPI != 'cli' ) {
        die( "Run me from the command line please.\n" );
 }
 
index b8a1bc2..960668f 100644 (file)
@@ -39,13 +39,13 @@ class EhcacheBagOStuff extends BagOStuff {
         */
        function __construct( $params ) {
                if ( !defined( 'CURLOPT_TIMEOUT_MS' ) ) {
-                       throw new MWException( __CLASS__.' requires curl version 7.16.2 or later.' );
+                       throw new MWException( __CLASS__ . ' requires curl version 7.16.2 or later.' );
                }
                if ( !extension_loaded( 'zlib' ) ) {
-                       throw new MWException( __CLASS__.' requires the zlib extension' );
+                       throw new MWException( __CLASS__ . ' requires the zlib extension' );
                }
                if ( !isset( $params['servers'] ) ) {
-                       throw new MWException( __METHOD__.': servers parameter is required' );
+                       throw new MWException( __METHOD__ . ': servers parameter is required' );
                }
                $this->servers = $params['servers'];
                $this->cacheName = isset( $params['cache'] ) ? $params['cache'] : 'mw';
@@ -76,7 +76,7 @@ class EhcacheBagOStuff extends BagOStuff {
                        return false;
                }
                if ( $response['http_code'] >= 300 ) {
-                       wfDebug( __METHOD__.": GET failure, got HTTP {$response['http_code']}\n" );
+                       wfDebug( __METHOD__ . ": GET failure, got HTTP {$response['http_code']}\n" );
                        wfProfileOut( __METHOD__ );
                        return false;
                }
@@ -85,7 +85,7 @@ class EhcacheBagOStuff extends BagOStuff {
                if ( $type == 'application/vnd.php.serialized+deflate' ) {
                        $body = gzinflate( $body );
                        if ( !$body ) {
-                               wfDebug( __METHOD__.": error inflating $key\n" );
+                               wfDebug( __METHOD__ . ": error inflating $key\n" );
                                wfProfileOut( __METHOD__ );
                                return false;
                        }
@@ -93,7 +93,7 @@ class EhcacheBagOStuff extends BagOStuff {
                } elseif ( $type == 'application/vnd.php.serialized' ) {
                        $data = unserialize( $body );
                } else {
-                       wfDebug( __METHOD__.": unknown content type \"$type\"\n" );
+                       wfDebug( __METHOD__ . ": unknown content type \"$type\"\n" );
                        wfProfileOut( __METHOD__ );
                        return false;
                }
@@ -127,7 +127,7 @@ class EhcacheBagOStuff extends BagOStuff {
                if ( $code == 404 ) {
                        // Maybe the cache does not exist yet, let's try creating it
                        if ( !$this->createCache( $key ) ) {
-                               wfDebug( __METHOD__.": cache creation failed\n" );
+                               wfDebug( __METHOD__ . ": cache creation failed\n" );
                                wfProfileOut( __METHOD__ );
                                return false;
                        }
@@ -136,9 +136,9 @@ class EhcacheBagOStuff extends BagOStuff {
 
                $result = false;
                if ( !$code ) {
-                       wfDebug( __METHOD__.": PUT failure for key $key\n" );
+                       wfDebug( __METHOD__ . ": PUT failure for key $key\n" );
                } elseif ( $code >= 300 ) {
-                       wfDebug( __METHOD__.": PUT failure for key $key: HTTP $code\n" );
+                       wfDebug( __METHOD__ . ": PUT failure for key $key: HTTP $code\n" );
                } else {
                        $result = true;
                }
@@ -172,7 +172,7 @@ class EhcacheBagOStuff extends BagOStuff {
                        array( CURLOPT_CUSTOMREQUEST => 'DELETE' ) );
                $code = isset( $response['http_code'] ) ? $response['http_code'] : 0;
                if ( !$response || ( $code != 404 && $code >= 300 ) ) {
-                       wfDebug( __METHOD__.": DELETE failure for key $key\n" );
+                       wfDebug( __METHOD__ . ": DELETE failure for key $key\n" );
                        $result = false;
                } else {
                        $result = true;
@@ -256,7 +256,7 @@ class EhcacheBagOStuff extends BagOStuff {
         * @return bool
         */
        protected function createCache( $key ) {
-               wfDebug( __METHOD__.": creating cache for $key\n" );
+               wfDebug( __METHOD__ . ": creating cache for $key\n" );
                $response = $this->doCacheRequest( $key,
                        array(
                                CURLOPT_POST => 1,
@@ -264,7 +264,7 @@ class EhcacheBagOStuff extends BagOStuff {
                                CURLOPT_POSTFIELDS => '',
                        ) );
                if ( !$response ) {
-                       wfDebug( __CLASS__.": failed to create cache for $key\n" );
+                       wfDebug( __CLASS__ . ": failed to create cache for $key\n" );
                        return false;
                }
                return ( $response['http_code'] == 201 /* created */
@@ -304,7 +304,7 @@ class EhcacheBagOStuff extends BagOStuff {
        protected function doRequest( $curl, $url, $curlOptions = array() ) {
                if ( array_diff_key( $curlOptions, $this->curlOptions ) ) {
                        // var_dump( array_diff_key( $curlOptions, $this->curlOptions ) );
-                       throw new MWException( __METHOD__.": to prevent options set in one doRequest() " .
+                       throw new MWException( __METHOD__ . ": to prevent options set in one doRequest() " .
                                "call from affecting subsequent doRequest() calls, only options listed " .
                                "in \$this->curlOptions may be specified in the \$curlOptions parameter." );
                }
@@ -314,7 +314,7 @@ class EhcacheBagOStuff extends BagOStuff {
                curl_setopt_array( $curl, $curlOptions );
                $result = curl_exec( $curl );
                if ( $result === false ) {
-                       wfDebug( __CLASS__.": curl error: " . curl_error( $curl ) . "\n" );
+                       wfDebug( __CLASS__ . ": curl error: " . curl_error( $curl ) . "\n" );
                        return false;
                }
                $info = curl_getinfo( $curl );
index d3f3583..d061eff 100644 (file)
@@ -110,4 +110,3 @@ class HashBagOStuff extends BagOStuff {
                return true;
        }
 }
-
index aebcbe7..4f8209d 100644 (file)
@@ -185,4 +185,3 @@ class MemcachedBagOStuff extends BagOStuff {
                wfDebugLog( 'memcached', $text );
        }
 }
-
index faa676d..2342d63 100644 (file)
@@ -991,7 +991,7 @@ class MWMemcached {
                $len = strlen( $val );
 
                if ( $this->_have_zlib && $this->_compress_enable &&
-                        $this->_compress_threshold && $len >= $this->_compress_threshold )
+                       $this->_compress_threshold && $len >= $this->_compress_threshold )
                {
                        $c_val = gzcompress( $val, 9 );
                        $c_len = strlen( $c_val );
index 5a9ee50..33a134c 100644 (file)
@@ -100,4 +100,3 @@ class MemcachedPhpBagOStuff extends MemcachedBagOStuff {
                return $this->client->decr( $this->encodeKey( $key ), $value );
        }
 }
-
index e4af262..eafa836 100644 (file)
@@ -123,7 +123,7 @@ class ObjectCache {
         * @return ObjectCache
         */
        static function newAccelerator( $params ) {
-               if ( function_exists( 'apc_fetch') ) {
+               if ( function_exists( 'apc_fetch' ) ) {
                        $id = 'apc';
                } elseif( function_exists( 'xcache_get' ) && wfIniGetBool( 'xcache.var_size' ) ) {
                        $id = 'xcache';
index bd5b354..2946407 100644 (file)
@@ -449,4 +449,3 @@ class RedisBagOStuff extends BagOStuff {
                        ( $result === false ? "failure" : "success" ) );
        }
 }
-
index 80c670e..bae1b75 100644 (file)
@@ -127,7 +127,7 @@ class SqlBagOStuff extends BagOStuff {
                                $info = $this->serverInfos[$serverIndex];
                                $type = isset( $info['type'] ) ? $info['type'] : 'mysql';
                                $host = isset( $info['host'] ) ? $info['host'] : '[unknown]';
-                               wfDebug( __CLASS__.": connecting to $host\n" );
+                               wfDebug( __CLASS__ . ": connecting to $host\n" );
                                $db = DatabaseBase::factory( $type, $info );
                                $db->clearFlag( DBO_TRX );
                        } else {
@@ -659,12 +659,12 @@ class SqlBagOStuff extends BagOStuff {
                                unset( $this->connFailureTimes[$serverIndex] );
                                unset( $this->connFailureErrors[$serverIndex] );
                        } else {
-                               wfDebug( __METHOD__.": Server #$serverIndex already down\n" );
+                               wfDebug( __METHOD__ . ": Server #$serverIndex already down\n" );
                                return;
                        }
                }
                $now = time();
-               wfDebug( __METHOD__.": Server #$serverIndex down until " . ( $now + 60 ) . "\n" );
+               wfDebug( __METHOD__ . ": Server #$serverIndex down until " . ( $now + 60 ) . "\n" );
                $this->connFailureTimes[$serverIndex] = $now;
                $this->connFailureErrors[$serverIndex] = $exception;
        }
@@ -697,4 +697,3 @@ class SqlBagOStuff extends BagOStuff {
  * Backwards compatibility alias
  */
 class MediaWikiBagOStuff extends SqlBagOStuff { }
-
index 4bfa9d3..1cabf76 100644 (file)
@@ -47,15 +47,15 @@ class CoreLinkFunctions {
         */
        static function defaultLinkHook( $parser, $holders, $markers,
                        Title $title, $titleText, &$displayText = null, &$leadingColon = false ) {
-               if( isset($displayText) && $markers->findMarker( $displayText ) ) {
+               if( isset( $displayText ) && $markers->findMarker( $displayText ) ) {
                        # There are links inside of the displayText
                        # For backwards compatibility the deepest links are dominant so this
                        # link should not be handled
-                       $displayText = $markers->expand($displayText);
+                       $displayText = $markers->expand( $displayText );
                        # Return false so that this link is reverted back to WikiText
                        return false;
                }
-               return $holders->makeHolder( $title, isset($displayText) ? $displayText : $titleText, array(), '', '' );
+               return $holders->makeHolder( $title, isset( $displayText ) ? $displayText : $titleText, array(), '', '' );
        }
 
        /**
@@ -73,15 +73,15 @@ class CoreLinkFunctions {
                global $wgContLang;
                # When a category link starts with a : treat it as a normal link
                if( $leadingColon ) return true;
-               if( isset($sortText) && $markers->findMarker( $sortText ) ) {
+               if( isset( $sortText ) && $markers->findMarker( $sortText ) ) {
                        # There are links inside of the sortText
                        # For backwards compatibility the deepest links are dominant so this
                        # link should not be handled
-                       $sortText = $markers->expand($sortText);
+                       $sortText = $markers->expand( $sortText );
                        # Return false so that this link is reverted back to WikiText
                        return false;
                }
-               if( !isset($sortText) ) $sortText = $parser->getDefaultSort();
+               if( !isset( $sortText ) ) $sortText = $parser->getDefaultSort();
                $sortText = Sanitizer::decodeCharReferences( $sortText );
                $sortText = str_replace( "\n", '', $sortText );
                $sortText = $wgContLang->convertCategoryKey( $sortText );
index b77309b..b2a72a4 100644 (file)
@@ -422,7 +422,7 @@ class CoreParserFunctions {
                return self::formatRaw( SiteStats::images(), $raw );
        }
        static function numberofadmins( $parser, $raw = null ) {
-               return self::formatRaw( SiteStats::numberingroup('sysop'), $raw );
+               return self::formatRaw( SiteStats::numberingroup( 'sysop' ), $raw );
        }
        static function numberofedits( $parser, $raw = null ) {
                return self::formatRaw( SiteStats::edits(), $raw );
@@ -800,7 +800,7 @@ class CoreParserFunctions {
 
        // Usage {{filepath|300}}, {{filepath|nowiki}}, {{filepath|nowiki|300}} or {{filepath|300|nowiki}}
        // or {{filepath|300px}}, {{filepath|200x300px}}, {{filepath|nowiki|200x300px}}, {{filepath|200x300px|nowiki}}
-       public static function filepath( $parser, $name='', $argA='', $argB='' ) {
+       public static function filepath( $parser, $name = '', $argA = '', $argB = '' ) {
                $file = wfFindFile( $name );
 
                if( $argA == 'nowiki' ) {
index 0f22675..88d68a7 100644 (file)
@@ -102,11 +102,11 @@ class DateFormatter {
 
                # Rules
                #            pref    source       target
-               $this->rules[self::DMY][self::MD]       = self::DM;
-               $this->rules[self::ALL][self::MD]       = self::MD;
-               $this->rules[self::MDY][self::DM]       = self::MD;
-               $this->rules[self::ALL][self::DM]       = self::DM;
-               $this->rules[self::NONE][self::ISO2]    = self::ISO1;
+               $this->rules[self::DMY][self::MD] = self::DM;
+               $this->rules[self::ALL][self::MD] = self::MD;
+               $this->rules[self::MDY][self::DM] = self::MD;
+               $this->rules[self::ALL][self::DM] = self::DM;
+               $this->rules[self::NONE][self::ISO2] = self::ISO1;
 
                $this->preferences = array(
                        'default' => self::NONE,
@@ -145,7 +145,7 @@ class DateFormatter {
         * @param $options Array: can contain 'linked' and/or 'match-whole'
         * @return mixed|String
         */
-       function reformat( $preference, $text, $options = array('linked') ) {
+       function reformat( $preference, $text, $options = array( 'linked' ) ) {
                $linked = in_array( 'linked', $options );
                $match_whole = in_array( 'match-whole', $options );
 
@@ -172,21 +172,21 @@ class DateFormatter {
                        $regex = $this->regexes[$i];
 
                        // Horrible hack
-                       if (!$linked) {
+                       if ( !$linked ) {
                                $regex = str_replace( array( '\[\[', '\]\]' ), '', $regex );
                        }
 
-                       if ($match_whole) {
+                       if ( $match_whole ) {
                                // Let's hope this works
                                $regex = preg_replace( '!^/!', '/^', $regex );
                                $regex = str_replace( $this->regexTrail,
-                                       '$'.$this->regexTrail, $regex );
+                                       '$' . $this->regexTrail, $regex );
                        }
 
                        // Another horrible hack
                        $this->mLinked = $linked;
                        $text = preg_replace_callback( $regex, array( &$this, 'replace' ), $text );
-                       unset($this->mLinked);
+                       unset( $this->mLinked );
                }
                return $text;
        }
@@ -203,7 +203,7 @@ class DateFormatter {
 
                $bits = array();
                $key = $this->keys[$this->mSource];
-               for ( $p=0; $p < strlen($key); $p++ ) {
+               for ( $p=0; $p < strlen( $key ); $p++ ) {
                        if ( $key[$p] != ' ' ) {
                                $bits[$key[$p]] = $matches[$p+1];
                        }
@@ -220,7 +220,7 @@ class DateFormatter {
        function formatDate( $bits, $link = true ) {
                $format = $this->targets[$this->mTarget];
 
-               if (!$link) {
+               if ( !$link ) {
                        // strip piped links
                        $format = preg_replace( '/\[\[[^|]+\|([^\]]+)\]\]/', '$1', $format );
                        // strip remaining links
@@ -246,7 +246,7 @@ class DateFormatter {
                        }
                }
 
-               if ( !isset($bits['d']) ) {
+               if ( !isset( $bits['d'] ) ) {
                        $bits['d'] = sprintf( '%02d', $bits['j'] );
                }
 
@@ -263,7 +263,7 @@ class DateFormatter {
                                        $text .= $bits['y'];
                                        break;
                                case 'j': # ordinary day of month
-                                       if ( !isset($bits['j']) ) {
+                                       if ( !isset( $bits['j'] ) ) {
                                                $text .= intval( $bits['d'] );
                                        } else {
                                                $text .= $bits['j'];
@@ -271,7 +271,7 @@ class DateFormatter {
                                        break;
                                case 'F': # long month
                                        if ( !isset( $bits['F'] ) ) {
-                                               $m = intval($bits['m']);
+                                               $m = intval( $bits['m'] );
                                                if ( $m > 12 || $m < 1 ) {
                                                        $fail = true;
                                                } else {
@@ -293,7 +293,7 @@ class DateFormatter {
                }
 
                $isoBits = array();
-               if ( isset($bits['y']) )
+               if ( isset( $bits['y'] ) )
                        $isoBits[] = $bits['y'];
                $isoBits[] = $bits['m'];
                $isoBits[] = $bits['d'];
index 0c05a51..ff1e0af 100644 (file)
@@ -215,9 +215,9 @@ class LinkHolderArray {
         * @param $prefix String [optional]
         * @return string
         */
-       function makeHolder( $nt, $text = '', $query = array(), $trail = '', $prefix = ''  ) {
+       function makeHolder( $nt, $text = '', $query = array(), $trail = '', $prefix = '' ) {
                wfProfileIn( __METHOD__ );
-               if ( ! is_object($nt) ) {
+               if ( !is_object( $nt ) ) {
                        # Fail gracefully
                        $retVal = "<!-- ERROR -->{$prefix}{$text}{$trail}";
                } else {
@@ -226,7 +226,7 @@ class LinkHolderArray {
 
                        $entry = array(
                                'title' => $nt,
-                               'text' => $prefix.$text.$inside,
+                               'text' => $prefix . $text . $inside,
                                'pdbk' => $nt->getPrefixedDBkey(),
                        );
                        if ( $query !== array() ) {
@@ -281,7 +281,7 @@ class LinkHolderArray {
                $linkCache = LinkCache::singleton();
                $output = $this->parent->getOutput();
 
-               wfProfileIn( __METHOD__.'-check' );
+               wfProfileIn( __METHOD__ . '-check' );
                $dbr = wfGetDB( DB_SLAVE );
                $threshold = $this->parent->getOptions()->getStubThreshold();
 
@@ -355,19 +355,19 @@ class LinkHolderArray {
                        }
                        unset( $res );
                }
-               if ( count($linkcolour_ids) ) {
+               if ( count( $linkcolour_ids ) ) {
                        //pass an array of page_ids to an extension
                        wfRunHooks( 'GetLinkColours', array( $linkcolour_ids, &$colours ) );
                }
-               wfProfileOut( __METHOD__.'-check' );
+               wfProfileOut( __METHOD__ . '-check' );
 
                # Do a second query for different language variants of links and categories
-               if($wgContLang->hasVariants()) {
+               if( $wgContLang->hasVariants() ) {
                        $this->doVariants( $colours );
                }
 
                # Construct search and replace arrays
-               wfProfileIn( __METHOD__.'-construct' );
+               wfProfileIn( __METHOD__ . '-construct' );
                $replacePairs = array();
                foreach ( $this->internals as $ns => $entries ) {
                        foreach ( $entries as $index => $entry ) {
@@ -399,16 +399,16 @@ class LinkHolderArray {
                        }
                }
                $replacer = new HashtableReplacer( $replacePairs, 1 );
-               wfProfileOut( __METHOD__.'-construct' );
+               wfProfileOut( __METHOD__ . '-construct' );
 
                # Do the thing
-               wfProfileIn( __METHOD__.'-replace' );
+               wfProfileIn( __METHOD__ . '-replace' );
                $text = preg_replace_callback(
                        '/(<!--LINK .*?-->)/',
                        $replacer->cb(),
                        $text);
 
-               wfProfileOut( __METHOD__.'-replace' );
+               wfProfileOut( __METHOD__ . '-replace' );
                wfProfileOut( __METHOD__ );
        }
 
index 8214019..ed5071e 100644 (file)
@@ -62,7 +62,6 @@
  * $wgAllowSpecialInclusion
  * $wgInterwikiMagic
  * $wgMaxArticleSize
- * $wgUseDynamicDates
  *
  * @ingroup Parser
  */
@@ -1090,7 +1089,7 @@ class Parser {
                                $out .= "</tr>\n";
                        }
                        if ( !array_pop( $has_opened_tr ) ) {
-                               $out .= "<tr><td></td></tr>\n" ;
+                               $out .= "<tr><td></td></tr>\n";
                        }
 
                        $out .= "</table>\n";
@@ -1131,7 +1130,7 @@ class Parser {
                # Hook to suspend the parser in this state
                if ( !wfRunHooks( 'ParserBeforeInternalParse', array( &$this, &$text, &$this->mStripState ) ) ) {
                        wfProfileOut( __METHOD__ );
-                       return $text ;
+                       return $text;
                }
 
                # if $frame is provided, then use $frame for replacing any variables
@@ -1165,10 +1164,6 @@ class Parser {
                $text = $this->doDoubleUnderscore( $text );
 
                $text = $this->doHeadings( $text );
-               if ( $this->mOptions->getUseDynamicDates() ) {
-                       $df = DateFormatter::getInstance();
-                       $text = $df->reformat( $this->mOptions->getDateFormat(), $text );
-               }
                $text = $this->replaceInternalLinks( $text );
                $text = $this->doAllQuotes( $text );
                $text = $this->replaceExternalLinks( $text );
@@ -1419,7 +1414,7 @@ class Parser {
                                                        if ( $firstspace == -1 ) {
                                                                $firstspace = $i;
                                                        }
-                                               } elseif ( $x2 === ' ') {
+                                               } elseif ( $x2 === ' ' ) {
                                                        if ( $firstsingleletterword == -1 ) {
                                                                $firstsingleletterword = $i;
                                                        }
@@ -1760,7 +1755,7 @@ class Parser {
                wfProfileIn( __METHOD__ );
 
                wfProfileIn( __METHOD__ . '-setup' );
-               static $tc = FALSE, $e1, $e1_img;
+               static $tc = false, $e1, $e1_img;
                # the % is needed to support urlencoded titles as well
                if ( !$tc ) {
                        $tc = Title::legalChars() . '#%';
@@ -1806,17 +1801,11 @@ class Parser {
                        $prefix = '';
                }
 
-               if ( $this->getConverterLanguage()->hasVariants() ) {
-                       $selflink = $this->getConverterLanguage()->autoConvertToAllVariants(
-                               $this->mTitle->getPrefixedText() );
-               } else {
-                       $selflink = array( $this->mTitle->getPrefixedText() );
-               }
                $useSubpages = $this->areSubpagesAllowed();
                wfProfileOut( __METHOD__ . '-setup' );
 
                # Loop for each link
-               for ( ; $line !== false && $line !== null ; $a->next(), $line = $a->current() ) {
+               for ( ; $line !== false && $line !== null; $a->next(), $line = $a->current() ) {
                        # Check for excessive memory usage
                        if ( $holders->isBig() ) {
                                # Too big
@@ -1865,7 +1854,7 @@ class Parser {
                                # fix up urlencoded title texts
                                if ( strpos( $m[1], '%' ) !== false ) {
                                        # Should anchors '#' also be rejected?
-                                       $m[1] = str_replace( array('<', '>'), array('&lt;', '&gt;'), rawurldecode( $m[1] ) );
+                                       $m[1] = str_replace( array( '<', '>' ), array( '&lt;', '&gt;' ), rawurldecode( $m[1] ) );
                                }
                                $trail = $m[3];
                        } elseif ( preg_match( $e1_img, $line, $m ) ) { # Invalid, but might be an image with a link in its caption
@@ -1876,7 +1865,7 @@ class Parser {
                                }
                                $trail = "";
                        } else { # Invalid form; output directly
-                               $s .= $prefix . '[[' . $line ;
+                               $s .= $prefix . '[[' . $line;
                                wfProfileOut( __METHOD__ . "-e1" );
                                continue;
                        }
@@ -1887,7 +1876,7 @@ class Parser {
                        # PROTO: where PROTO is a valid URL protocol; these
                        # should be external links.
                        if ( preg_match( '/^(?i:' . $this->mUrlProtocols . ')/', $m[1] ) ) {
-                               $s .= $prefix . '[[' . $line ;
+                               $s .= $prefix . '[[' . $line;
                                wfProfileOut( __METHOD__ . "-misc" );
                                continue;
                        }
@@ -2047,7 +2036,11 @@ class Parser {
 
                        # Self-link checking
                        if ( $nt->getFragment() === '' && $ns != NS_SPECIAL ) {
-                               if ( in_array( $nt->getPrefixedText(), $selflink, true ) ) {
+                               if ( $nt->equals( $this->mTitle ) || ( !$nt->isKnown() && in_array(
+                                       $this->mTitle->getPrefixedText(),
+                                       $this->getConverterLanguage()->autoConvertToAllVariants( $nt->getPrefixedText() ),
+                                       true
+                               ) ) ) {
                                        $s .= $prefix . Linker::makeSelfLinkObj( $nt, $text, '', $trail );
                                        continue;
                                }
@@ -2339,7 +2332,7 @@ class Parser {
                                $output .= $this->nextItem( substr( $prefix, -1 ) );
                                $paragraphStack = false;
 
-                               if ( substr( $prefix, -1 ) === ';') {
+                               if ( substr( $prefix, -1 ) === ';' ) {
                                        # The one nasty exception: definition lists work like this:
                                        # ; title : definition text
                                        # So we check for : in the remainder text to split up the
@@ -2390,7 +2383,7 @@ class Parser {
                                wfProfileIn( __METHOD__ . "-paragraph" );
                                # No prefix (not in list)--go to paragraph mode
                                # XXX: use a stack for nestable elements like span, table and div
-                               $openmatch = preg_match('/(?:<table|<blockquote|<h1|<h2|<h3|<h4|<h5|<h6|<pre|<tr|<p|<ul|<ol|<dl|<li|<\\/tr|<\\/td|<\\/th)/iS', $t );
+                               $openmatch = preg_match( '/(?:<table|<blockquote|<h1|<h2|<h3|<h4|<h5|<h6|<pre|<tr|<p|<ul|<ol|<dl|<li|<\\/tr|<\\/td|<\\/th)/iS', $t );
                                $closematch = preg_match(
                                        '/(?:<\\/table|<\\/blockquote|<\\/h1|<\\/h2|<\\/h3|<\\/h4|<\\/h5|<\\/h6|'.
                                        '<td|<th|<\\/?div|<hr|<\\/pre|<\\/p|'.$this->mUniqPrefix . '-pre|<\\/li|<\\/ul|<\\/ol|<\\/dl|<\\/?center)/iS', $t );
@@ -3717,7 +3710,7 @@ class Parser {
                global $wgEnableScaryTranscluding;
 
                if ( !$wgEnableScaryTranscluding ) {
-                       return wfMessage('scarytranscludedisabled')->inContentLanguage()->text();
+                       return wfMessage( 'scarytranscludedisabled' )->inContentLanguage()->text();
                }
 
                $url = $title->getFullUrl( "action=$action" );
@@ -3736,7 +3729,7 @@ class Parser {
                global $wgTranscludeCacheExpiry;
                $dbr = wfGetDB( DB_SLAVE );
                $tsCond = $dbr->timestamp( time() - $wgTranscludeCacheExpiry );
-               $obj = $dbr->selectRow( 'transcache', array('tc_time', 'tc_contents' ),
+               $obj = $dbr->selectRow( 'transcache', array( 'tc_time', 'tc_contents' ),
                                array( 'tc_url' => $url, "tc_time >= " . $dbr->addQuotes( $tsCond ) ) );
                if ( $obj ) {
                        return $obj->tc_contents;
@@ -3753,7 +3746,7 @@ class Parser {
                }
 
                $dbw = wfGetDB( DB_MASTER );
-               $dbw->replace( 'transcache', array('tc_url'), array(
+               $dbw->replace( 'transcache', array( 'tc_url' ), array(
                        'tc_url' => $url,
                        'tc_time' => $dbw->timestamp( time() ),
                        'tc_contents' => $text)
@@ -3779,7 +3772,7 @@ class Parser {
                $argName = trim( $nameWithSpaces );
                $object = false;
                $text = $frame->getArgument( $argName );
-               if (  $text === false && $parts->getLength() > 0
+               if ( $text === false && $parts->getLength() > 0
                  && (
                        $this->ot['html']
                        || $this->ot['pre']
@@ -3832,7 +3825,7 @@ class Parser {
                $content = !isset( $params['inner'] ) ? null : $frame->expand( $params['inner'] );
                $marker = "{$this->mUniqPrefix}-$name-" . sprintf( '%08X', $this->mMarkerIndex++ ) . self::MARKER_SUFFIX;
 
-               $isFunctionTag = isset( $this->mFunctionTagHooks[strtolower($name)] ) &&
+               $isFunctionTag = isset( $this->mFunctionTagHooks[strtolower( $name )] ) &&
                        ( $this->ot['html'] || $this->ot['pre'] );
                if ( $isFunctionTag ) {
                        $markerType = 'none';
@@ -4111,7 +4104,7 @@ class Parser {
                        $sectionIndex = false;
                        $numbering = '';
                        $markerMatches = array();
-                       if ( preg_match("/^$markerRegex/", $headline, $markerMatches ) ) {
+                       if ( preg_match( "/^$markerRegex/", $headline, $markerMatches ) ) {
                                $serial = $markerMatches[1];
                                list( $titleText, $sectionIndex ) = $this->mHeadings[$serial];
                                $isTemplate = ( $titleText != $baseTitleText );
@@ -4203,7 +4196,7 @@ class Parser {
                        # to allow setting directionality in toc items.
                        $tocline = preg_replace(
                                array( '#<(?!/?(span|sup|sub|i|b)(?: [^>]*)?>).*?'.'>#', '#<(/?(?:span(?: dir="(?:rtl|ltr)")?|sup|sub|i|b))(?: .*?)?'.'>#' ),
-                               array( '',                          '<$1>' ),
+                               array( '', '<$1>' ),
                                $safeHeadline
                        );
                        $tocline = trim( $tocline );
@@ -4324,9 +4317,9 @@ class Parser {
                                // We use a page and section attribute to stop the language converter from converting these important bits
                                // of data, but put the headline hint inside a content block because the language converter is supposed to
                                // be able to convert that piece of data.
-                               $editlink = '<mw:editsection page="' . htmlspecialchars($editlinkArgs[0]);
-                               $editlink .= '" section="' . htmlspecialchars($editlinkArgs[1]) . '"';
-                               if ( isset($editlinkArgs[2]) ) {
+                               $editlink = '<mw:editsection page="' . htmlspecialchars( $editlinkArgs[0] );
+                               $editlink .= '" section="' . htmlspecialchars( $editlinkArgs[1] ) . '"';
+                               if ( isset( $editlinkArgs[2] ) ) {
                                        $editlink .= '>' . $editlinkArgs[2] . '</mw:editsection>';
                                } else {
                                        $editlink .= '/>';
@@ -4978,7 +4971,7 @@ class Parser {
                                // is defined for images in galleries
 
                                $matches[3] = $this->recursiveTagParse( trim( $matches[3] ) );
-                               $parameterMatches = StringUtils::explode('|', $matches[3]);
+                               $parameterMatches = StringUtils::explode( '|', $matches[3] );
                                $magicWordAlt = MagicWord::get( 'img_alt' );
                                $magicWordLink = MagicWord::get( 'img_link' );
 
@@ -5024,7 +5017,7 @@ class Parser {
                } else {
                        $handlerClass = '';
                }
-               if ( !isset( $this->mImageParams[$handlerClass]  ) ) {
+               if ( !isset( $this->mImageParams[$handlerClass] ) ) {
                        # Initialise static lists
                        static $internalParamNames = array(
                                'horizAlign' => array( 'left', 'right', 'center', 'none' ),
@@ -5242,7 +5235,7 @@ class Parser {
                } else { # Inline image
                        if ( !isset( $params['frame']['alt'] ) ) {
                                # No alt text, use the "caption" for the alt text
-                               if ( $caption !== '') {
+                               if ( $caption !== '' ) {
                                        $params['frame']['alt'] = $this->stripAltText( $caption, $holders );
                                } else {
                                        # No caption, fall back to using the filename for the
@@ -5388,7 +5381,7 @@ class Parser {
         * @return String: for "get", the extracted section text.
         *                 for "replace", the whole page with the section replaced.
         */
-       private function extractSections( $text, $section, $mode, $newText='' ) {
+       private function extractSections( $text, $section, $mode, $newText = '' ) {
                global $wgTitle; # not generally used but removes an ugly failure mode
                $this->startParse( $wgTitle, new ParserOptions, self::OT_PLAIN, true );
                $outText = '';
@@ -5509,7 +5502,7 @@ class Parser {
         * @param $deftext String: default to return if section is not found
         * @return string text of the requested section
         */
-       public function getSection( $text, $section, $deftext='' ) {
+       public function getSection( $text, $section, $deftext = '' ) {
                return $this->extractSections( $text, $section, "get", $deftext );
        }
 
index d419621..0faa40a 100644 (file)
@@ -67,7 +67,7 @@ class ParserCache {
 
                // idhash seem to mean 'page id' + 'rendering hash' (r3710)
                $pageid = $article->getID();
-               $renderkey = (int)($wgRequest->getVal('action') == 'render');
+               $renderkey = (int)($wgRequest->getVal( 'action' ) == 'render');
 
                $key = wfMemcKey( 'pcache', 'idhash', "{$pageid}-{$renderkey}!{$hash}" );
                return $key;
index 064182e..bd4bcac 100644 (file)
  */
 class ParserOptions {
 
-       /**
-        * Use DateFormatter to format dates
-        */
-       var $mUseDynamicDates;
-
        /**
         * Interlanguage links are removed and returned in an array
         */
@@ -220,7 +215,6 @@ class ParserOptions {
         */
        protected $onAccessCallback = null;
 
-       function getUseDynamicDates()               { return $this->mUseDynamicDates; }
        function getInterwikiMagic()                { return $this->mInterwikiMagic; }
        function getAllowExternalImages()           { return $this->mAllowExternalImages; }
        function getAllowExternalImagesFrom()       { return $this->mAllowExternalImagesFrom; }
@@ -308,7 +302,6 @@ class ParserOptions {
                return $this->getUserLangObj()->getCode();
        }
 
-       function setUseDynamicDates( $x )           { return wfSetVar( $this->mUseDynamicDates, $x ); }
        function setInterwikiMagic( $x )            { return wfSetVar( $this->mInterwikiMagic, $x ); }
        function setAllowExternalImages( $x )       { return wfSetVar( $this->mAllowExternalImages, $x ); }
        function setAllowExternalImagesFrom( $x )   { return wfSetVar( $this->mAllowExternalImagesFrom, $x ); }
@@ -422,7 +415,7 @@ class ParserOptions {
         * @param $lang Language object
         */
        private function initialiseFromUser( $user, $lang ) {
-               global $wgUseDynamicDates, $wgInterwikiMagic, $wgAllowExternalImages,
+               global $wgInterwikiMagic, $wgAllowExternalImages,
                        $wgAllowExternalImagesFrom, $wgEnableImageWhitelist, $wgAllowSpecialInclusion,
                        $wgMaxArticleSize, $wgMaxPPNodeCount, $wgMaxTemplateDepth, $wgMaxPPExpandDepth,
                        $wgCleanSignatures, $wgExternalLinkTarget, $wgExpensiveParserFunctionLimit,
@@ -430,7 +423,6 @@ class ParserOptions {
 
                wfProfileIn( __METHOD__ );
 
-               $this->mUseDynamicDates = $wgUseDynamicDates;
                $this->mInterwikiMagic = $wgInterwikiMagic;
                $this->mAllowExternalImages = $wgAllowExternalImages;
                $this->mAllowExternalImagesFrom = $wgAllowExternalImagesFrom;
@@ -481,12 +473,7 @@ class ParserOptions {
         * @return array
         */
        public static function legacyOptions() {
-               global $wgUseDynamicDates;
-               $legacyOpts = array( 'math', 'stubthreshold', 'numberheadings', 'userlang', 'thumbsize', 'editsection', 'printable' );
-               if ( $wgUseDynamicDates ) {
-                       $legacyOpts[] = 'dateformat';
-               }
-               return $legacyOpts;
+               return array( 'math', 'stubthreshold', 'numberheadings', 'userlang', 'thumbsize', 'editsection', 'printable' );
        }
 
        /**
@@ -525,7 +512,7 @@ class ParserOptions {
                if ( in_array( 'stubthreshold', $forOptions ) ) {
                        $confstr .= '!' . $this->mStubThreshold;
                } else {
-                       $confstr .= '!*' ;
+                       $confstr .= '!*';
                }
 
                if ( in_array( 'dateformat', $forOptions ) ) {
index 53b6293..27b75ac 100644 (file)
@@ -83,13 +83,13 @@ class ParserOutput extends CacheTime {
        function replaceEditSectionLinksCallback( $m ) {
                global $wgOut, $wgLang;
                $args = array(
-                       htmlspecialchars_decode($m[1]),
-                       htmlspecialchars_decode($m[2]),
-                       isset($m[4]) ? $m[3] : null,
+                       htmlspecialchars_decode( $m[1] ),
+                       htmlspecialchars_decode( $m[2] ),
+                       isset( $m[4] ) ? $m[3] : null,
                );
                $args[0] = Title::newFromText( $args[0] );
-               if ( !is_object($args[0]) ) {
-                       throw new MWException("Bad parser output text.");
+               if ( !is_object( $args[0] ) ) {
+                       throw new MWException( "Bad parser output text." );
                }
                $args[] = $wgLang->getCode();
                $skin = $wgOut->getSkin();
@@ -261,7 +261,7 @@ class ParserOutput extends CacheTime {
                if( $prefix == '' ) {
                        throw new MWException( 'Non-interwiki link passed, internal parser error.' );
                }
-               if (!isset($this->mInterwikiLinks[$prefix])) {
+               if ( !isset( $this->mInterwikiLinks[$prefix] ) ) {
                        $this->mInterwikiLinks[$prefix] = array();
                }
                $this->mInterwikiLinks[$prefix][$title->getDBkey()] = 1;
index d1ca8aa..b2cdc41 100644 (file)
@@ -105,9 +105,9 @@ class Parser_LinkHooks extends Parser {
         */
        public function setLinkHook( $ns, $callback, $flags = 0 ) {
                if( $flags & SLH_PATTERN && !is_string($ns) )
-                       throw new MWException( __METHOD__.'() expecting a regex string pattern.' );
-               elseif( $flags | ~SLH_PATTERN && !is_int($ns) )
-                       throw new MWException( __METHOD__.'() expecting a namespace index.' );
+                       throw new MWException( __METHOD__ . '() expecting a regex string pattern.' );
+               elseif( $flags | ~SLH_PATTERN && !is_int( $ns ) )
+                       throw new MWException( __METHOD__ . '() expecting a namespace index.' );
                $oldVal = isset( $this->mLinkHooks[$ns] ) ? $this->mLinkHooks[$ns][0] : null;
                $this->mLinkHooks[$ns] = array( $callback, $flags );
                return $oldVal;
@@ -133,8 +133,8 @@ class Parser_LinkHooks extends Parser {
        function replaceInternalLinks2( &$s ) {
                wfProfileIn( __METHOD__ );
 
-               wfProfileIn( __METHOD__.'-setup' );
-               static $tc = FALSE, $titleRegex;//$e1, $e1_img;
+               wfProfileIn( __METHOD__ . '-setup' );
+               static $tc = false, $titleRegex; //$e1, $e1_img;
                if( !$tc ) {
                        # the % is needed to support urlencoded titles as well
                        $tc = Title::legalChars() . '#%';
@@ -149,12 +149,12 @@ class Parser_LinkHooks extends Parser {
                $holders = new LinkHolderArray( $this );
 
                if( is_null( $this->mTitle ) ) {
-                       wfProfileOut( __METHOD__.'-setup' );
+                       wfProfileOut( __METHOD__ . '-setup' );
                        wfProfileOut( __METHOD__ );
-                       throw new MWException( __METHOD__.": \$this->mTitle is null\n" );
+                       throw new MWException( __METHOD__ . ": \$this->mTitle is null\n" );
                }
 
-               wfProfileOut( __METHOD__.'-setup' );
+               wfProfileOut( __METHOD__ . '-setup' );
 
                $offset = 0;
                $offsetStack = array();
@@ -167,7 +167,7 @@ class Parser_LinkHooks extends Parser {
                        # Determine if the bracket is a starting or ending bracket
                        # When we find both, use the first one
                        elseif( $startBracketOffset !== false && $endBracketOffset !== false )
-                            $isStart = $startBracketOffset <= $endBracketOffset;
+                               $isStart = $startBracketOffset <= $endBracketOffset;
                        # When we only found one, check which it is
                        else $isStart = $startBracketOffset !== false;
                        $bracketOffset = $isStart ? $startBracketOffset : $endBracketOffset;
@@ -178,26 +178,26 @@ class Parser_LinkHooks extends Parser {
                        } else {
                                /** Closing bracket **/
                                # Pop the start pos for our current link zone off the stack
-                               $startBracketOffset = array_pop($offsetStack);
+                               $startBracketOffset = array_pop( $offsetStack );
                                # Just to clean up the code, lets place offsets on the outer ends
                                $endBracketOffset += 2;
 
                                # Only do logic if we actually have a opening bracket for this
-                               if( isset($startBracketOffset) ) {
+                               if( isset( $startBracketOffset ) ) {
                                        # Extract text inside the link
-                                       @list( $titleText, $paramText ) = explode('|',
-                                               substr($s, $startBracketOffset+2, $endBracketOffset-$startBracketOffset-4), 2);
+                                       @list( $titleText, $paramText ) = explode( '|',
+                                               substr( $s, $startBracketOffset + 2, $endBracketOffset - $startBracketOffset - 4 ), 2 );
                                        # Create markers only for valid links
                                        if( preg_match( $titleRegex, $titleText ) ) {
                                                # Store the text for the marker
-                                               $marker = $markers->addMarker($titleText, $paramText);
+                                               $marker = $markers->addMarker( $titleText, $paramText );
                                                # Replace the current link with the marker
-                                               $s = substr($s,0,$startBracketOffset).
-                                                       $marker.
-                                                       substr($s, $endBracketOffset);
+                                               $s = substr( $s, 0, $startBracketOffset ) .
+                                                       $marker .
+                                                       substr( $s, $endBracketOffset );
                                                # We have modified $s, because of this we need to set the
                                                # offset manually since the end position is different now
-                                               $offset = $startBracketOffset+strlen($marker);
+                                               $offset = $startBracketOffset+strlen( $marker );
                                                continue;
                                        }
                                        # ToDo: Some LinkHooks may allow recursive links inside of
@@ -212,9 +212,9 @@ class Parser_LinkHooks extends Parser {
                }
 
                # Now expand our tree
-               wfProfileIn( __METHOD__.'-expand' );
+               wfProfileIn( __METHOD__ . '-expand' );
                $s = $markers->expand( $s );
-               wfProfileOut( __METHOD__.'-expand' );
+               wfProfileOut( __METHOD__ . '-expand' );
 
                wfProfileOut( __METHOD__ );
                return $holders;
@@ -222,14 +222,14 @@ class Parser_LinkHooks extends Parser {
 
        function replaceInternalLinksCallback( $parser, $holders, $markers, $titleText, $paramText ) {
                wfProfileIn( __METHOD__ );
-               $wt = isset($paramText) ? "[[$titleText|$paramText]]" : "[[$titleText]]";
-               wfProfileIn( __METHOD__."-misc" );
+               $wt = isset( $paramText ) ? "[[$titleText|$paramText]]" : "[[$titleText]]";
+               wfProfileIn( __METHOD__ . "-misc" );
 
                # Don't allow internal links to pages containing
                # PROTO: where PROTO is a valid URL protocol; these
                # should be external links.
-               if( preg_match('/^\b(?i:' . wfUrlProtocols() . ')/', $titleText) ) {
-                       wfProfileOut( __METHOD__."-misc" );
+               if( preg_match( '/^\b(?i:' . wfUrlProtocols() . ')/', $titleText ) ) {
+                       wfProfileOut( __METHOD__ . "-misc" );
                        wfProfileOut( __METHOD__ );
                        return $wt;
                }
@@ -243,17 +243,17 @@ class Parser_LinkHooks extends Parser {
                $leadingColon = $titleText[0] == ':';
                if( $leadingColon ) $titleText = substr( $titleText, 1 );
 
-               wfProfileOut( __METHOD__."-misc" );
+               wfProfileOut( __METHOD__ . "-misc" );
                # Make title object
-               wfProfileIn( __METHOD__."-title" );
+               wfProfileIn( __METHOD__ . "-title" );
                $title = Title::newFromText( $this->mStripState->unstripNoWiki( $titleText ) );
                if( !$title ) {
-                       wfProfileOut( __METHOD__."-title" );
+                       wfProfileOut( __METHOD__ . "-title" );
                        wfProfileOut( __METHOD__ );
                        return $wt;
                }
                $ns = $title->getNamespace();
-               wfProfileOut( __METHOD__."-title" );
+               wfProfileOut( __METHOD__ . "-title" );
 
                # Default for Namespaces is a default link
                # ToDo: Default for patterns is plain wikitext
@@ -279,7 +279,7 @@ class Parser_LinkHooks extends Parser {
                if( $return === false ) {
                        # False (no link) was returned, output plain wikitext
                        # Build it again as the hook is allowed to modify $paramText
-                       $return = isset($paramText) ? "[[$titleText|$paramText]]" : "[[$titleText]]";
+                       $return = isset( $paramText ) ? "[[$titleText|$paramText]]" : "[[$titleText]]";
                }
                # Content was returned, return it
                wfProfileOut( __METHOD__ );
@@ -300,14 +300,14 @@ class LinkMarkerReplacer {
                $this->callback = $callback;
        }
 
-       function addMarker($titleText, $paramText) {
+       function addMarker( $titleText, $paramText ) {
                $id = $this->nextId++;
                $this->markers[$id] = array( $titleText, $paramText );
                return "<!-- LINKMARKER $id -->";
        }
 
        function findMarker( $string ) {
-               return (bool) preg_match('/<!-- LINKMARKER [0-9]+ -->/', $string );
+               return (bool) preg_match( '/<!-- LINKMARKER [0-9]+ -->/', $string );
        }
 
        function expand( $string ) {
@@ -315,8 +315,8 @@ class LinkMarkerReplacer {
        }
 
        function callback( $m ) {
-               $id = intval($m[1]);
-               if( !array_key_exists($id, $this->markers) ) return $m[0];
+               $id = intval( $m[1] );
+               if( !array_key_exists( $id, $this->markers ) ) return $m[0];
                $args = $this->markers[$id];
                array_unshift( $args, $this );
                array_unshift( $args, $this->holders );
index 53f3feb..468802d 100644 (file)
@@ -137,9 +137,9 @@ class Preprocessor_DOM implements Preprocessor {
                $cacheable = ( $wgPreprocessorCacheThreshold !== false
                        && strlen( $text ) > $wgPreprocessorCacheThreshold );
                if ( $cacheable ) {
-                       wfProfileIn( __METHOD__.'-cacheable' );
+                       wfProfileIn( __METHOD__ . '-cacheable' );
 
-                       $cacheKey = wfMemcKey( 'preprocess-xml', md5($text), $flags );
+                       $cacheKey = wfMemcKey( 'preprocess-xml', md5( $text ), $flags );
                        $cacheValue = $wgMemc->get( $cacheKey );
                        if ( $cacheValue ) {
                                $version = substr( $cacheValue, 0, 8 );
@@ -152,11 +152,11 @@ class Preprocessor_DOM implements Preprocessor {
                }
                if ( $xml === false ) {
                        if ( $cacheable ) {
-                               wfProfileIn( __METHOD__.'-cache-miss' );
+                               wfProfileIn( __METHOD__ . '-cache-miss' );
                                $xml = $this->preprocessToXml( $text, $flags );
                                $cacheValue = sprintf( "%08d", self::CACHE_VERSION ) . $xml;
                                $wgMemc->set( $cacheKey, $cacheValue, 86400 );
-                               wfProfileOut( __METHOD__.'-cache-miss' );
+                               wfProfileOut( __METHOD__ . '-cache-miss' );
                                wfDebugLog( "Preprocessor", "Saved preprocessor XML to memcached (key $cacheKey)" );
                        } else {
                                $xml = $this->preprocessToXml( $text, $flags );
@@ -169,10 +169,10 @@ class Preprocessor_DOM implements Preprocessor {
                $this->parser->mGeneratedPPNodeCount += substr_count( $xml, '<' );
                $max = $this->parser->mOptions->getMaxGeneratedPPNodeCount();
                if ( $this->parser->mGeneratedPPNodeCount > $max ) {
-                       throw new MWException( __METHOD__.': generated node count limit exceeded' );
+                       throw new MWException( __METHOD__ . ': generated node count limit exceeded' );
                }
 
-               wfProfileIn( __METHOD__.'-loadXML' );
+               wfProfileIn( __METHOD__ . '-loadXML' );
                $dom = new DOMDocument;
                wfSuppressWarnings();
                $result = $dom->loadXML( $xml );
@@ -183,13 +183,13 @@ class Preprocessor_DOM implements Preprocessor {
                        // 1 << 19 == XML_PARSE_HUGE, needed so newer versions of libxml2 don't barf when the XML is >256 levels deep
                        $result = $dom->loadXML( $xml, 1 << 19 );
                        if ( !$result ) {
-                               throw new MWException( __METHOD__.' generated invalid XML' );
+                               throw new MWException( __METHOD__ . ' generated invalid XML' );
                        }
                }
                $obj = new PPNode_DOM( $dom->documentElement );
-               wfProfileOut( __METHOD__.'-loadXML' );
+               wfProfileOut( __METHOD__ . '-loadXML' );
                if ( $cacheable ) {
-                       wfProfileOut( __METHOD__.'-cacheable' );
+                       wfProfileOut( __METHOD__ . '-cacheable' );
                }
                wfProfileOut( __METHOD__ );
                return $obj;
@@ -397,7 +397,7 @@ class Preprocessor_DOM implements Preprocessor {
 
                                                if ( $stack->top ) {
                                                        $part = $stack->top->getCurrentPart();
-                                                       if ( ! (isset( $part->commentEnd ) && $part->commentEnd == $wsStart - 1 )) {
+                                                       if ( !(isset( $part->commentEnd ) && $part->commentEnd == $wsStart - 1 )) {
                                                                $part->visualEnd = $wsStart;
                                                        }
                                                        // Else comments abutting, no change in visual end
@@ -658,19 +658,13 @@ class Preprocessor_DOM implements Preprocessor {
                                        $piece->parts = array( new PPDPart );
                                        $piece->count -= $matchingCount;
                                        # do we still qualify for any callback with remaining count?
-                                       $names = $rules[$piece->open]['names'];
-                                       $skippedBraces = 0;
-                                       $enclosingAccum =& $accum;
-                                       while ( $piece->count ) {
-                                               if ( array_key_exists( $piece->count, $names ) ) {
-                                                       $stack->push( $piece );
-                                                       $accum =& $stack->getAccum();
-                                                       break;
-                                               }
-                                               --$piece->count;
-                                               $skippedBraces ++;
+                                       $min = $rules[$piece->open]['min'];
+                                       if ( $piece->count >= $min ) {
+                                               $stack->push( $piece );
+                                               $accum =& $stack->getAccum();
+                                       } else {
+                                               $accum .= str_repeat( $piece->open, $piece->count );
                                        }
-                                       $enclosingAccum .= str_repeat( $piece->open, $skippedBraces );
                                }
                                $flags = $stack->getFlags();
                                extract( $flags );
@@ -758,7 +752,7 @@ class PPDStack {
 
        function pop() {
                if ( !count( $this->stack ) ) {
-                       throw new MWException( __METHOD__.': no elements remaining' );
+                       throw new MWException( __METHOD__ . ': no elements remaining' );
                }
                $temp = array_pop( $this->stack );
 
@@ -815,7 +809,7 @@ class PPDStackElement {
        }
 
        function &getAccum() {
-               return $this->parts[count($this->parts) - 1]->out;
+               return $this->parts[count( $this->parts ) - 1]->out;
        }
 
        function addPart( $s = '' ) {
@@ -824,7 +818,7 @@ class PPDStackElement {
        }
 
        function getCurrentPart() {
-               return $this->parts[count($this->parts) - 1];
+               return $this->parts[count( $this->parts ) - 1];
        }
 
        /**
@@ -1118,7 +1112,7 @@ class PPFrame_DOM implements PPFrame {
                                        }
                                        # Add a strip marker in PST mode so that pstPass2() can run some old-fashioned regexes on the result
                                        # Not in RECOVER_COMMENTS mode (extractSections) though
-                                       elseif ( $this->parser->ot['wiki'] && ! ( $flags & PPFrame::RECOVER_COMMENTS ) ) {
+                                       elseif ( $this->parser->ot['wiki'] && !( $flags & PPFrame::RECOVER_COMMENTS ) ) {
                                                $out .= $this->parser->insertStripItem( $contextNode->textContent );
                                        }
                                        # Recover the literal comment in RECOVER_COMMENTS and pre+no-remove
@@ -1175,7 +1169,7 @@ class PPFrame_DOM implements PPFrame {
                                }
                        } else {
                                wfProfileOut( __METHOD__ );
-                               throw new MWException( __METHOD__.': Invalid parameter type' );
+                               throw new MWException( __METHOD__ . ': Invalid parameter type' );
                        }
 
                        if ( $newIterator !== false ) {
@@ -1459,25 +1453,25 @@ class PPTemplateFrame_DOM extends PPFrame_DOM {
        function getArguments() {
                $arguments = array();
                foreach ( array_merge(
-                               array_keys($this->numberedArgs),
-                               array_keys($this->namedArgs)) as $key ) {
-                       $arguments[$key] = $this->getArgument($key);
+                               array_keys( $this->numberedArgs ),
+                               array_keys( $this->namedArgs ) ) as $key ) {
+                       $arguments[$key] = $this->getArgument( $key );
                }
                return $arguments;
        }
 
        function getNumberedArguments() {
                $arguments = array();
-               foreach ( array_keys($this->numberedArgs) as $key ) {
-                       $arguments[$key] = $this->getArgument($key);
+               foreach ( array_keys( $this->numberedArgs ) as $key ) {
+                       $arguments[$key] = $this->getArgument( $key );
                }
                return $arguments;
        }
 
        function getNamedArguments() {
                $arguments = array();
-               foreach ( array_keys($this->namedArgs) as $key ) {
-                       $arguments[$key] = $this->getArgument($key);
+               foreach ( array_keys( $this->namedArgs ) as $key ) {
+                       $arguments[$key] = $this->getArgument( $key );
                }
                return $arguments;
        }
index a4e408e..c22da64 100644 (file)
@@ -116,9 +116,9 @@ class Preprocessor_Hash implements Preprocessor {
 
                $cacheable = $wgPreprocessorCacheThreshold !== false && strlen( $text ) > $wgPreprocessorCacheThreshold;
                if ( $cacheable ) {
-                       wfProfileIn( __METHOD__.'-cacheable' );
+                       wfProfileIn( __METHOD__ . '-cacheable' );
 
-                       $cacheKey = wfMemcKey( 'preprocess-hash', md5($text), $flags );
+                       $cacheKey = wfMemcKey( 'preprocess-hash', md5( $text ), $flags );
                        $cacheValue = $wgMemc->get( $cacheKey );
                        if ( $cacheValue ) {
                                $version = substr( $cacheValue, 0, 8 );
@@ -127,12 +127,12 @@ class Preprocessor_Hash implements Preprocessor {
                                        // From the cache
                                        wfDebugLog( "Preprocessor",
                                                "Loaded preprocessor hash from memcached (key $cacheKey)" );
-                                       wfProfileOut( __METHOD__.'-cacheable' );
+                                       wfProfileOut( __METHOD__ . '-cacheable' );
                                        wfProfileOut( __METHOD__ );
                                        return $hash;
                                }
                        }
-                       wfProfileIn( __METHOD__.'-cache-miss' );
+                       wfProfileIn( __METHOD__ . '-cache-miss' );
                }
 
                $rules = array(
@@ -332,7 +332,7 @@ class Preprocessor_Hash implements Preprocessor {
 
                                                if ( $stack->top ) {
                                                        $part = $stack->top->getCurrentPart();
-                                                       if ( ! (isset( $part->commentEnd ) && $part->commentEnd == $wsStart - 1 )) {
+                                                       if ( !(isset( $part->commentEnd ) && $part->commentEnd == $wsStart - 1 )) {
                                                                $part->visualEnd = $wsStart;
                                                        }
                                                        // Else comments abutting, no change in visual end
@@ -391,7 +391,7 @@ class Preprocessor_Hash implements Preprocessor {
                                }
                                // <includeonly> and <noinclude> just become <ignore> tags
                                if ( in_array( $lowerName, $ignoredElements ) ) {
-                                       $accum->addNodeWithText(  'ignore', substr( $text, $tagStartPos, $i - $tagStartPos ) );
+                                       $accum->addNodeWithText( 'ignore', substr( $text, $tagStartPos, $i - $tagStartPos ) );
                                        continue;
                                }
 
@@ -549,7 +549,7 @@ class Preprocessor_Hash implements Preprocessor {
                                        }
                                }
 
-                               if ($matchingCount <= 0) {
+                               if ( $matchingCount <= 0 ) {
                                        # No matching element found in callback array
                                        # Output a literal closing brace and continue
                                        $accum->addLiteral( str_repeat( $curChar, $count ) );
@@ -591,10 +591,10 @@ class Preprocessor_Hash implements Preprocessor {
                                                                $lastNode = $node;
                                                        }
                                                        if ( !$node ) {
-                                                               throw new MWException( __METHOD__. ': eqpos not found' );
+                                                               throw new MWException( __METHOD__ . ': eqpos not found' );
                                                        }
                                                        if ( $node->name !== 'equals' ) {
-                                                               throw new MWException( __METHOD__ .': eqpos is not equals' );
+                                                               throw new MWException( __METHOD__ . ': eqpos is not equals' );
                                                        }
                                                        $equalsNode = $node;
 
@@ -639,23 +639,17 @@ class Preprocessor_Hash implements Preprocessor {
                                $accum =& $stack->getAccum();
 
                                # Re-add the old stack element if it still has unmatched opening characters remaining
-                               if ($matchingCount < $piece->count) {
+                               if ( $matchingCount < $piece->count ) {
                                        $piece->parts = array( new PPDPart_Hash );
                                        $piece->count -= $matchingCount;
                                        # do we still qualify for any callback with remaining count?
-                                       $names = $rules[$piece->open]['names'];
-                                       $skippedBraces = 0;
-                                       $enclosingAccum =& $accum;
-                                       while ( $piece->count ) {
-                                               if ( array_key_exists( $piece->count, $names ) ) {
-                                                       $stack->push( $piece );
-                                                       $accum =& $stack->getAccum();
-                                                       break;
-                                               }
-                                               --$piece->count;
-                                               $skippedBraces ++;
+                                       $min = $rules[$piece->open]['min'];
+                                       if ( $piece->count >= $min ) {
+                                               $stack->push( $piece );
+                                               $accum =& $stack->getAccum();
+                                       } else {
+                                               $accum->addLiteral( str_repeat( $piece->open, $piece->count ) );
                                        }
-                                       $enclosingAccum->addLiteral( str_repeat( $piece->open, $skippedBraces ) );
                                }
 
                                extract( $stack->getFlags() );
@@ -696,11 +690,11 @@ class Preprocessor_Hash implements Preprocessor {
                $rootNode->lastChild = $stack->rootAccum->lastNode;
 
                // Cache
-               if ($cacheable) {
+               if ( $cacheable ) {
                        $cacheValue = sprintf( "%08d", self::CACHE_VERSION ) . serialize( $rootNode );
                        $wgMemc->set( $cacheKey, $cacheValue, 86400 );
-                       wfProfileOut( __METHOD__.'-cache-miss' );
-                       wfProfileOut( __METHOD__.'-cacheable' );
+                       wfProfileOut( __METHOD__ . '-cache-miss' );
+                       wfProfileOut( __METHOD__ . '-cacheable' );
                        wfDebugLog( "Preprocessor", "Saved preprocessor Hash to memcached (key $cacheKey)" );
                }
 
@@ -1038,7 +1032,7 @@ class PPFrame_Hash implements PPFrame {
                                        }
                                        # Add a strip marker in PST mode so that pstPass2() can run some old-fashioned regexes on the result
                                        # Not in RECOVER_COMMENTS mode (extractSections) though
-                                       elseif ( $this->parser->ot['wiki'] && ! ( $flags & PPFrame::RECOVER_COMMENTS ) ) {
+                                       elseif ( $this->parser->ot['wiki'] && !( $flags & PPFrame::RECOVER_COMMENTS ) ) {
                                                $out .= $this->parser->insertStripItem( $contextNode->firstChild->value );
                                        }
                                        # Recover the literal comment in RECOVER_COMMENTS and pre+no-remove
@@ -1085,7 +1079,7 @@ class PPFrame_Hash implements PPFrame {
                                        $newIterator = $contextNode->getChildren();
                                }
                        } else {
-                               throw new MWException( __METHOD__.': Invalid parameter type' );
+                               throw new MWException( __METHOD__ . ': Invalid parameter type' );
                        }
 
                        if ( $newIterator !== false ) {
@@ -1374,9 +1368,9 @@ class PPTemplateFrame_Hash extends PPFrame_Hash {
        function getArguments() {
                $arguments = array();
                foreach ( array_merge(
-                               array_keys($this->numberedArgs),
-                               array_keys($this->namedArgs)) as $key ) {
-                       $arguments[$key] = $this->getArgument($key);
+                               array_keys( $this->numberedArgs ),
+                               array_keys( $this->namedArgs ) ) as $key ) {
+                       $arguments[$key] = $this->getArgument( $key );
                }
                return $arguments;
        }
@@ -1386,8 +1380,8 @@ class PPTemplateFrame_Hash extends PPFrame_Hash {
         */
        function getNumberedArguments() {
                $arguments = array();
-               foreach ( array_keys($this->numberedArgs) as $key ) {
-                       $arguments[$key] = $this->getArgument($key);
+               foreach ( array_keys( $this->numberedArgs ) as $key ) {
+                       $arguments[$key] = $this->getArgument( $key );
                }
                return $arguments;
        }
@@ -1397,8 +1391,8 @@ class PPTemplateFrame_Hash extends PPFrame_Hash {
         */
        function getNamedArguments() {
                $arguments = array();
-               foreach ( array_keys($this->namedArgs) as $key ) {
-                       $arguments[$key] = $this->getArgument($key);
+               foreach ( array_keys( $this->namedArgs ) as $key ) {
+                       $arguments[$key] = $this->getArgument( $key );
                }
                return $arguments;
        }
diff --git a/includes/parser/Preprocessor_HipHop.hphp b/includes/parser/Preprocessor_HipHop.hphp
deleted file mode 100644 (file)
index 8059e35..0000000
+++ /dev/null
@@ -1,2014 +0,0 @@
-<?php
-/**
- * A preprocessor optimised for HipHop, using HipHop-specific syntax.
- * vim: ft=php
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- * http://www.gnu.org/copyleft/gpl.html
- *
- * @file
- * @ingroup Parser
- */
-
-/**
- * @ingroup Parser
- */
-class Preprocessor_HipHop implements Preprocessor {
-       /**
-        * @var Parser
-        */
-       var $parser;
-
-       const CACHE_VERSION = 1;
-
-       /**
-        * @param $parser Parser
-        */
-       function __construct( $parser ) {
-               $this->parser = $parser;
-       }
-
-       /**
-        * @return PPFrame_HipHop
-        */
-       function newFrame() {
-               return new PPFrame_HipHop( $this );
-       }
-
-       /**
-        * @param $args array
-        * @return PPCustomFrame_HipHop
-        */
-       function newCustomFrame( $args ) {
-               return new PPCustomFrame_HipHop( $this, $args );
-       }
-
-       /**
-        * @param $values array
-        * @return PPNode_HipHop_Array
-        */
-       function newPartNodeArray( $values ) {
-               $list = array();
-
-               foreach ( $values as $k => $val ) {
-                       $partNode = new PPNode_HipHop_Tree( 'part' );
-                       $nameNode = new PPNode_HipHop_Tree( 'name' );
-
-                       if ( is_int( $k ) ) {
-                               $nameNode->addChild( new PPNode_HipHop_Attr( 'index', $k ) );
-                               $partNode->addChild( $nameNode );
-                       } else {
-                               $nameNode->addChild( new PPNode_HipHop_Text( $k ) );
-                               $partNode->addChild( $nameNode );
-                               $partNode->addChild( new PPNode_HipHop_Text( '=' ) );
-                       }
-
-                       $valueNode = new PPNode_HipHop_Tree( 'value' );
-                       $valueNode->addChild( new PPNode_HipHop_Text( $val ) );
-                       $partNode->addChild( $valueNode );
-
-                       $list[] = $partNode;
-               }
-
-               $node = new PPNode_HipHop_Array( $list );
-               return $node;
-       }
-
-       /**
-        * Preprocess some wikitext and return the document tree.
-        * This is the ghost of Parser::replace_variables().
-        *
-        * @param $text String: the text to parse
-        * @param $flags Integer: bitwise combination of:
-        *          Parser::PTD_FOR_INCLUSION    Handle <noinclude>/<includeonly> as if the text is being
-        *                                     included. Default is to assume a direct page view.
-        *
-        * The generated DOM tree must depend only on the input text and the flags.
-        * The DOM tree must be the same in OT_HTML and OT_WIKI mode, to avoid a regression of bug 4899.
-        *
-        * Any flag added to the $flags parameter here, or any other parameter liable to cause a
-        * change in the DOM tree for a given text, must be passed through the section identifier
-        * in the section edit link and thus back to extractSections().
-        *
-        * The output of this function is currently only cached in process memory, but a persistent
-        * cache may be implemented at a later date which takes further advantage of these strict
-        * dependency requirements.
-        *
-        * @throws MWException
-        * @return PPNode_HipHop_Tree
-        */
-       function preprocessToObj( $text, $flags = 0 ) {
-               wfProfileIn( __METHOD__ );
-
-               // Check cache.
-               global $wgMemc, $wgPreprocessorCacheThreshold;
-
-               $lengthText = strlen( $text );
-
-               $cacheable = ($wgPreprocessorCacheThreshold !== false && $lengthText > $wgPreprocessorCacheThreshold);
-               if ( $cacheable ) {
-                       wfProfileIn( __METHOD__.'-cacheable' );
-
-                       $cacheKey = strval( wfMemcKey( 'preprocess-hash', md5($text), $flags ) );
-                       $cacheValue = strval( $wgMemc->get( $cacheKey ) );
-                       if ( $cacheValue !== '' ) {
-                               $version = substr( $cacheValue, 0, 8 );
-                               if ( intval( $version ) == self::CACHE_VERSION ) {
-                                       $hash = unserialize( substr( $cacheValue, 8 ) );
-                                       // From the cache
-                                       wfDebugLog( "Preprocessor",
-                                               "Loaded preprocessor hash from memcached (key $cacheKey)" );
-                                       wfProfileOut( __METHOD__.'-cacheable' );
-                                       wfProfileOut( __METHOD__ );
-                                       return $hash;
-                               }
-                       }
-                       wfProfileIn( __METHOD__.'-cache-miss' );
-               }
-
-               $rules = array(
-                       '{' => array(
-                               'end' => '}',
-                               'names' => array(
-                                       2 => 'template',
-                                       3 => 'tplarg',
-                               ),
-                               'min' => 2,
-                               'max' => 3,
-                       ),
-                       '[' => array(
-                               'end' => ']',
-                               'names' => array( 2 => 'LITERAL' ),
-                               'min' => 2,
-                               'max' => 2,
-                       )
-               );
-
-               $forInclusion = (bool)( $flags & Parser::PTD_FOR_INCLUSION );
-
-               $xmlishElements = (array)$this->parser->getStripList();
-               $enableOnlyinclude = false;
-               if ( $forInclusion ) {
-                       $ignoredTags = array( 'includeonly', '/includeonly' );
-                       $ignoredElements = array( 'noinclude' );
-                       $xmlishElements[] = 'noinclude';
-                       if ( strpos( $text, '<onlyinclude>' ) !== false && strpos( $text, '</onlyinclude>' ) !== false ) {
-                               $enableOnlyinclude = true;
-                       }
-               } else if ( $this->parser->ot['wiki'] ) {
-                       $ignoredTags = array( 'noinclude', '/noinclude', 'onlyinclude', '/onlyinclude', 'includeonly', '/includeonly' );
-                       $ignoredElements = array();
-               } else {
-                       $ignoredTags = array( 'noinclude', '/noinclude', 'onlyinclude', '/onlyinclude' );
-                       $ignoredElements = array( 'includeonly' );
-                       $xmlishElements[] = 'includeonly';
-               }
-               $xmlishRegex = implode( '|', array_merge( $xmlishElements, $ignoredTags ) );
-
-               // Use "A" modifier (anchored) instead of "^", because ^ doesn't work with an offset
-               $elementsRegex = "~($xmlishRegex)(?:\s|\/>|>)|(!--)~iA";
-
-               $stack = new PPDStack_HipHop;
-
-               $searchBase = "[{<\n";
-               $revText = strrev( $text ); // For fast reverse searches
-
-               $i = 0;                     # Input pointer, starts out pointing to a pseudo-newline before the start
-               $accum = $stack->getAccum();   # Current accumulator
-               $headingIndex = 1;
-               $stackFlags = array(
-                       'findPipe' => false, # True to take notice of pipe characters
-                       'findEquals' => false, # True to find equals signs in arguments
-                       'inHeading' => false, # True if $i is inside a possible heading
-               );
-               $noMoreGT = false;         # True if there are no more greater-than (>) signs right of $i
-               $findOnlyinclude = $enableOnlyinclude; # True to ignore all input up to the next <onlyinclude>
-               $fakeLineStart = true;     # Do a line-start run without outputting an LF character
-
-               while ( true ) {
-                       //$this->memCheck();
-
-                       if ( $findOnlyinclude ) {
-                               // Ignore all input up to the next <onlyinclude>
-                               $variantStartPos = strpos( $text, '<onlyinclude>', $i );
-                               if ( $variantStartPos === false ) {
-                                       // Ignored section runs to the end
-                                       $accum->addNodeWithText( 'ignore', strval( substr( $text, $i ) ) );
-                                       break;
-                               }
-                               $startPos1 = intval( $variantStartPos );
-                               $tagEndPos = $startPos1 + strlen( '<onlyinclude>' ); // past-the-end
-                               $accum->addNodeWithText( 'ignore', strval( substr( $text, $i, $tagEndPos - $i ) ) );
-                               $i = $tagEndPos;
-                               $findOnlyinclude = false;
-                       }
-
-                       if ( $fakeLineStart ) {
-                               $found = 'line-start';
-                               $curChar = '';
-                       } else {
-                               # Find next opening brace, closing brace or pipe
-                               $search = $searchBase;
-                               if ( $stack->top === false ) {
-                                       $currentClosing = '';
-                               } else {
-                                       $currentClosing = strval( $stack->getTop()->close );
-                                       $search .= $currentClosing;
-                               }
-                               if ( $stackFlags['findPipe'] ) {
-                                       $search .= '|';
-                               }
-                               if ( $stackFlags['findEquals'] ) {
-                                       // First equals will be for the template
-                                       $search .= '=';
-                               }
-                               $rule = null;
-                               # Output literal section, advance input counter
-                               $literalLength = intval( strcspn( $text, $search, $i ) );
-                               if ( $literalLength > 0 ) {
-                                       $accum->addLiteral( strval( substr( $text, $i, $literalLength ) ) );
-                                       $i += $literalLength;
-                               }
-                               if ( $i >= $lengthText ) {
-                                       if ( $currentClosing === "\n" ) {
-                                               // Do a past-the-end run to finish off the heading
-                                               $curChar = '';
-                                               $found = 'line-end';
-                                       } else {
-                                               # All done
-                                               break;
-                                       }
-                               } else {
-                                       $curChar = $text[$i];
-                                       if ( $curChar === '|' ) {
-                                               $found = 'pipe';
-                                       } elseif ( $curChar === '=' ) {
-                                               $found = 'equals';
-                                       } elseif ( $curChar === '<' ) {
-                                               $found = 'angle';
-                                       } elseif ( $curChar === "\n" ) {
-                                               if ( $stackFlags['inHeading'] ) {
-                                                       $found = 'line-end';
-                                               } else {
-                                                       $found = 'line-start';
-                                               }
-                                       } elseif ( $curChar === $currentClosing ) {
-                                               $found = 'close';
-                                       } elseif ( isset( $rules[$curChar] ) ) {
-                                               $found = 'open';
-                                               $rule = $rules[$curChar];
-                                       } else {
-                                               # Some versions of PHP have a strcspn which stops on null characters
-                                               # Ignore and continue
-                                               ++$i;
-                                               continue;
-                                       }
-                               }
-                       }
-
-                       if ( $found === 'angle' ) {
-                               $matches = false;
-                               // Handle </onlyinclude>
-                               if ( $enableOnlyinclude
-                                       && substr( $text, $i, strlen( '</onlyinclude>' ) ) === '</onlyinclude>' )
-                               {
-                                       $findOnlyinclude = true;
-                                       continue;
-                               }
-
-                               // Determine element name
-                               if ( !preg_match( $elementsRegex, $text, $matches, 0, $i + 1 ) ) {
-                                       // Element name missing or not listed
-                                       $accum->addLiteral( '<' );
-                                       ++$i;
-                                       continue;
-                               }
-                               // Handle comments
-                               if ( isset( $matches[2] ) && $matches[2] === '!--' ) {
-                                       // To avoid leaving blank lines, when a comment is both preceded
-                                       // and followed by a newline (ignoring spaces), trim leading and
-                                       // trailing spaces and one of the newlines.
-
-                                       // Find the end
-                                       $variantEndPos = strpos( $text, '-->', $i + 4 );
-                                       if ( $variantEndPos === false ) {
-                                               // Unclosed comment in input, runs to end
-                                               $inner = strval( substr( $text, $i ) );
-                                               $accum->addNodeWithText( 'comment', $inner );
-                                               $i = $lengthText;
-                                       } else {
-                                               $endPos = intval( $variantEndPos );
-                                               // Search backwards for leading whitespace
-                                               if ( $i ) {
-                                                       $wsStart = $i - intval( strspn( $revText, ' ', $lengthText - $i ) );
-                                               } else {
-                                                       $wsStart = 0;
-                                               }
-                                               // Search forwards for trailing whitespace
-                                               // $wsEnd will be the position of the last space (or the '>' if there's none)
-                                               $wsEnd = $endPos + 2 + intval( strspn( $text, ' ', $endPos + 3 ) );
-                                               // Eat the line if possible
-                                               // TODO: This could theoretically be done if $wsStart == 0, i.e. for comments at
-                                               // the overall start. That's not how Sanitizer::removeHTMLcomments() did it, but
-                                               // it's a possible beneficial b/c break.
-                                               if ( $wsStart > 0 && substr( $text, $wsStart - 1, 1 ) === "\n"
-                                                       && substr( $text, $wsEnd + 1, 1 ) === "\n" )
-                                               {
-                                                       $startPos2 = $wsStart;
-                                                       $endPos = $wsEnd + 1;
-                                                       // Remove leading whitespace from the end of the accumulator
-                                                       // Sanity check first though
-                                                       $wsLength = $i - $wsStart;
-                                                       if ( $wsLength > 0
-                                                               && $accum->lastNode instanceof PPNode_HipHop_Text
-                                                               && substr( $accum->lastNode->value, -$wsLength ) === str_repeat( ' ', $wsLength ) )
-                                                       {
-                                                               $accum->lastNode->value = strval( substr( $accum->lastNode->value, 0, -$wsLength ) );
-                                                       }
-                                                       // Do a line-start run next time to look for headings after the comment
-                                                       $fakeLineStart = true;
-                                               } else {
-                                                       // No line to eat, just take the comment itself
-                                                       $startPos2 = $i;
-                                                       $endPos += 2;
-                                               }
-
-                                               if ( $stack->top ) {
-                                                       $part = $stack->getTop()->getCurrentPart();
-                                                       if ( ! (isset( $part->commentEnd ) && $part->commentEnd == $wsStart - 1 )) {
-                                                               $part->visualEnd = $wsStart;
-                                                       }
-                                                       // Else comments abutting, no change in visual end
-                                                       $part->commentEnd = $endPos;
-                                               }
-                                               $i = $endPos + 1;
-                                               $inner = strval( substr( $text, $startPos2, $endPos - $startPos2 + 1 ) );
-                                               $accum->addNodeWithText( 'comment', $inner );
-                                       }
-                                       continue;
-                               }
-                               $name = strval( $matches[1] );
-                               $lowerName = strtolower( $name );
-                               $attrStart = $i + strlen( $name ) + 1;
-
-                               // Find end of tag
-                               $variantTagEndPos = $noMoreGT ? false : strpos( $text, '>', $attrStart );
-                               if ( $variantTagEndPos === false ) {
-                                       // Infinite backtrack
-                                       // Disable tag search to prevent worst-case O(N^2) performance
-                                       $noMoreGT = true;
-                                       $accum->addLiteral( '<' );
-                                       ++$i;
-                                       continue;
-                               }
-                               $tagEndPos = intval( $variantTagEndPos );
-
-                               // Handle ignored tags
-                               if ( in_array( $lowerName, $ignoredTags ) ) {
-                                       $accum->addNodeWithText( 'ignore', strval( substr( $text, $i, $tagEndPos - $i + 1 ) ) );
-                                       $i = $tagEndPos + 1;
-                                       continue;
-                               }
-
-                               $tagStartPos = $i;
-                               $close = '';
-                               if ( $text[$tagEndPos-1] === '/' ) {
-                                       // Short end tag
-                                       $attrEnd = $tagEndPos - 1;
-                                       $shortEnd = true;
-                                       $inner = '';
-                                       $i = $tagEndPos + 1;
-                                       $haveClose = false;
-                               } else {
-                                       $attrEnd = $tagEndPos;
-                                       $shortEnd = false;
-                                       // Find closing tag
-                                       if ( preg_match( "/<\/" . preg_quote( $name, '/' ) . "\s*>/i",
-                                                       $text, $matches, PREG_OFFSET_CAPTURE, $tagEndPos + 1 ) )
-                                       {
-                                               $inner = strval( substr( $text, $tagEndPos + 1, $matches[0][1] - $tagEndPos - 1 ) );
-                                               $i = intval( $matches[0][1] ) + strlen( $matches[0][0] );
-                                               $close = strval( $matches[0][0] );
-                                               $haveClose = true;
-                                       } else {
-                                               // No end tag -- let it run out to the end of the text.
-                                               $inner = strval( substr( $text, $tagEndPos + 1 ) );
-                                               $i = $lengthText;
-                                               $haveClose = false;
-                                       }
-                               }
-                               // <includeonly> and <noinclude> just become <ignore> tags
-                               if ( in_array( $lowerName, $ignoredElements ) ) {
-                                       $accum->addNodeWithText(  'ignore', strval( substr( $text, $tagStartPos, $i - $tagStartPos ) ) );
-                                       continue;
-                               }
-
-                               if ( $attrEnd <= $attrStart ) {
-                                       $attr = '';
-                               } else {
-                                       // Note that the attr element contains the whitespace between name and attribute,
-                                       // this is necessary for precise reconstruction during pre-save transform.
-                                       $attr = strval( substr( $text, $attrStart, $attrEnd - $attrStart ) );
-                               }
-
-                               $extNode = new PPNode_HipHop_Tree( 'ext' );
-                               $extNode->addChild( PPNode_HipHop_Tree::newWithText( 'name', $name ) );
-                               $extNode->addChild( PPNode_HipHop_Tree::newWithText( 'attr', $attr ) );
-                               if ( !$shortEnd ) {
-                                       $extNode->addChild( PPNode_HipHop_Tree::newWithText( 'inner', $inner ) );
-                               }
-                               if ( $haveClose ) {
-                                       $extNode->addChild( PPNode_HipHop_Tree::newWithText( 'close', $close ) );
-                               }
-                               $accum->addNode( $extNode );
-                       }
-
-                       elseif ( $found === 'line-start' ) {
-                               // Is this the start of a heading?
-                               // Line break belongs before the heading element in any case
-                               if ( $fakeLineStart ) {
-                                       $fakeLineStart = false;
-                               } else {
-                                       $accum->addLiteral( $curChar );
-                                       $i++;
-                               }
-
-                               $count = intval( strspn( $text, '=', $i, 6 ) );
-                               if ( $count == 1 && $stackFlags['findEquals'] ) {
-                                       // DWIM: This looks kind of like a name/value separator
-                                       // Let's let the equals handler have it and break the potential heading
-                                       // This is heuristic, but AFAICT the methods for completely correct disambiguation are very complex.
-                               } elseif ( $count > 0 ) {
-                                       $partData = array(
-                                               'open' => "\n",
-                                               'close' => "\n",
-                                               'parts' => array( new PPDPart_HipHop( str_repeat( '=', $count ) ) ),
-                                               'startPos' => $i,
-                                               'count' => $count );
-                                       $stack->push( $partData );
-                                       $accum = $stack->getAccum();
-                                       $stackFlags = $stack->getFlags();
-                                       $i += $count;
-                               }
-                       } elseif ( $found === 'line-end' ) {
-                               $piece = $stack->getTop();
-                               // A heading must be open, otherwise \n wouldn't have been in the search list
-                               assert( $piece->open === "\n" ); // Passing the assert condition directly instead of string, as
-                                                                // HPHP /compiler/ chokes on strings when ASSERT_ACTIVE != 0.
-                               $part = $piece->getCurrentPart();
-                               // Search back through the input to see if it has a proper close
-                               // Do this using the reversed string since the other solutions (end anchor, etc.) are inefficient
-                               $wsLength = intval( strspn( $revText, " \t", $lengthText - $i ) );
-                               $searchStart = $i - $wsLength;
-                               if ( isset( $part->commentEnd ) && $searchStart - 1 == $part->commentEnd ) {
-                                       // Comment found at line end
-                                       // Search for equals signs before the comment
-                                       $searchStart = intval( $part->visualEnd );
-                                       $searchStart -= intval( strspn( $revText, " \t", $lengthText - $searchStart ) );
-                               }
-                               $count = intval( $piece->count );
-                               $equalsLength = intval( strspn( $revText, '=', $lengthText - $searchStart ) );
-                               $isTreeNode = false;
-                               $resultAccum = $accum;
-                               if ( $equalsLength > 0 ) {
-                                       if ( $searchStart - $equalsLength == $piece->startPos ) {
-                                               // This is just a single string of equals signs on its own line
-                                               // Replicate the doHeadings behaviour /={count}(.+)={count}/
-                                               // First find out how many equals signs there really are (don't stop at 6)
-                                               $count = $equalsLength;
-                                               if ( $count < 3 ) {
-                                                       $count = 0;
-                                               } else {
-                                                       $count = intval( ( $count - 1 ) / 2 );
-                                                       if ( $count > 6 ) {
-                                                               $count = 6;
-                                                       }
-                                               }
-                                       } else {
-                                               if ( $count > $equalsLength ) {
-                                                       $count = $equalsLength;
-                                               }
-                                       }
-                                       if ( $count > 0 ) {
-                                               // Normal match, output <h>
-                                               $tree = new PPNode_HipHop_Tree( 'possible-h' );
-                                               $tree->addChild( new PPNode_HipHop_Attr( 'level', $count ) );
-                                               $tree->addChild( new PPNode_HipHop_Attr( 'i', $headingIndex++ ) );
-                                               $tree->lastChild->nextSibling = $accum->firstNode;
-                                               $tree->lastChild = $accum->lastNode;
-                                               $isTreeNode = true;
-                                       } else {
-                                               // Single equals sign on its own line, count=0
-                                               // Output $resultAccum
-                                       }
-                               } else {
-                                       // No match, no <h>, just pass down the inner text
-                                       // Output $resultAccum
-                               }
-                               // Unwind the stack
-                               $stack->pop();
-                               $accum = $stack->getAccum();
-                               $stackFlags = $stack->getFlags();
-
-                               // Append the result to the enclosing accumulator
-                               if ( $isTreeNode ) {
-                                       $accum->addNode( $tree );
-                               } else {
-                                       $accum->addAccum( $resultAccum );
-                               }
-                               // Note that we do NOT increment the input pointer.
-                               // This is because the closing linebreak could be the opening linebreak of
-                               // another heading. Infinite loops are avoided because the next iteration MUST
-                               // hit the heading open case above, which unconditionally increments the
-                               // input pointer.
-                       } elseif ( $found === 'open' ) {
-                               # count opening brace characters
-                               $count = intval( strspn( $text, $curChar, $i ) );
-
-                               # we need to add to stack only if opening brace count is enough for one of the rules
-                               if ( $count >= $rule['min'] ) {
-                                       # Add it to the stack
-                                       $partData = array(
-                                               'open' => $curChar,
-                                               'close' => $rule['end'],
-                                               'count' => $count,
-                                               'lineStart' => ($i == 0 || $text[$i-1] === "\n"),
-                                       );
-
-                                       $stack->push( $partData );
-                                       $accum = $stack->getAccum();
-                                       $stackFlags = $stack->getFlags();
-                               } else {
-                                       # Add literal brace(s)
-                                       $accum->addLiteral( str_repeat( $curChar, $count ) );
-                               }
-                               $i += $count;
-                       } elseif ( $found === 'close' ) {
-                               $piece = $stack->getTop();
-                               # lets check if there are enough characters for closing brace
-                               $maxCount = intval( $piece->count );
-                               $count = intval( strspn( $text, $curChar, $i, $maxCount ) );
-
-                               # check for maximum matching characters (if there are 5 closing
-                               # characters, we will probably need only 3 - depending on the rules)
-                               $rule = $rules[$piece->open];
-                               if ( $count > $rule['max'] ) {
-                                       # The specified maximum exists in the callback array, unless the caller
-                                       # has made an error
-                                       $matchingCount = intval( $rule['max'] );
-                               } else {
-                                       # Count is less than the maximum
-                                       # Skip any gaps in the callback array to find the true largest match
-                                       # Need to use array_key_exists not isset because the callback can be null
-                                       $matchingCount = $count;
-                                       while ( $matchingCount > 0 && !array_key_exists( $matchingCount, $rule['names'] ) ) {
-                                               --$matchingCount;
-                                       }
-                               }
-
-                               if ($matchingCount <= 0) {
-                                       # No matching element found in callback array
-                                       # Output a literal closing brace and continue
-                                       $accum->addLiteral( str_repeat( $curChar, $count ) );
-                                       $i += $count;
-                                       continue;
-                               }
-                               $name = strval( $rule['names'][$matchingCount] );
-                               $isTreeNode = false;
-                               if ( $name === 'LITERAL' ) {
-                                       // No element, just literal text
-                                       $resultAccum = $piece->breakSyntax( $matchingCount );
-                                       $resultAccum->addLiteral( str_repeat( $rule['end'], $matchingCount ) );
-                               } else {
-                                       # Create XML element
-                                       # Note: $parts is already XML, does not need to be encoded further
-                                       $isTreeNode = true;
-                                       $parts = $piece->parts;
-                                       $titleAccum = PPDAccum_HipHop::cast( $parts[0]->out );
-                                       unset( $parts[0] );
-
-                                       $tree = new PPNode_HipHop_Tree( $name );
-
-                                       # The invocation is at the start of the line if lineStart is set in
-                                       # the stack, and all opening brackets are used up.
-                                       if ( $maxCount == $matchingCount && !empty( $piece->lineStart ) ) {
-                                               $tree->addChild( new PPNode_HipHop_Attr( 'lineStart', 1 ) );
-                                       }
-                                       $titleNode = new PPNode_HipHop_Tree( 'title' );
-                                       $titleNode->firstChild = $titleAccum->firstNode;
-                                       $titleNode->lastChild = $titleAccum->lastNode;
-                                       $tree->addChild( $titleNode );
-                                       $argIndex = 1;
-                                       foreach ( $parts as $variantPart ) {
-                                               $part = PPDPart_HipHop::cast( $variantPart );
-                                               if ( isset( $part->eqpos ) ) {
-                                                       // Find equals
-                                                       $lastNode = false;
-                                                       for ( $node = $part->out->firstNode; $node; $node = $node->nextSibling ) {
-                                                               if ( $node === $part->eqpos ) {
-                                                                       break;
-                                                               }
-                                                               $lastNode = $node;
-                                                       }
-                                                       if ( !$node ) {
-                                                               throw new MWException( __METHOD__. ': eqpos not found' );
-                                                       }
-                                                       if ( $node->name !== 'equals' ) {
-                                                               throw new MWException( __METHOD__ .': eqpos is not equals' );
-                                                       }
-                                                       $equalsNode = $node;
-
-                                                       // Construct name node
-                                                       $nameNode = new PPNode_HipHop_Tree( 'name' );
-                                                       if ( $lastNode !== false ) {
-                                                               $lastNode->nextSibling = false;
-                                                               $nameNode->firstChild = $part->out->firstNode;
-                                                               $nameNode->lastChild = $lastNode;
-                                                       }
-
-                                                       // Construct value node
-                                                       $valueNode = new PPNode_HipHop_Tree( 'value' );
-                                                       if ( $equalsNode->nextSibling !== false ) {
-                                                               $valueNode->firstChild = $equalsNode->nextSibling;
-                                                               $valueNode->lastChild = $part->out->lastNode;
-                                                       }
-                                                       $partNode = new PPNode_HipHop_Tree( 'part' );
-                                                       $partNode->addChild( $nameNode );
-                                                       $partNode->addChild( $equalsNode->firstChild );
-                                                       $partNode->addChild( $valueNode );
-                                                       $tree->addChild( $partNode );
-                                               } else {
-                                                       $partNode = new PPNode_HipHop_Tree( 'part' );
-                                                       $nameNode = new PPNode_HipHop_Tree( 'name' );
-                                                       $nameNode->addChild( new PPNode_HipHop_Attr( 'index', $argIndex++ ) );
-                                                       $valueNode = new PPNode_HipHop_Tree( 'value' );
-                                                       $valueNode->firstChild = $part->out->firstNode;
-                                                       $valueNode->lastChild = $part->out->lastNode;
-                                                       $partNode->addChild( $nameNode );
-                                                       $partNode->addChild( $valueNode );
-                                                       $tree->addChild( $partNode );
-                                               }
-                                       }
-                               }
-
-                               # Advance input pointer
-                               $i += $matchingCount;
-
-                               # Unwind the stack
-                               $stack->pop();
-                               $accum = $stack->getAccum();
-
-                               # Re-add the old stack element if it still has unmatched opening characters remaining
-                               if ($matchingCount < $piece->count) {
-                                       $piece->parts = array( new PPDPart_HipHop );
-                                       $piece->count -= $matchingCount;
-                                       # do we still qualify for any callback with remaining count?
-                                       $names = $rules[$piece->open]['names'];
-                                       $skippedBraces = 0;
-                                       $enclosingAccum = $accum;
-                                       while ( $piece->count ) {
-                                               if ( array_key_exists( $piece->count, $names ) ) {
-                                                       $stack->push( $piece );
-                                                       $accum = $stack->getAccum();
-                                                       break;
-                                               }
-                                               --$piece->count;
-                                               $skippedBraces ++;
-                                       }
-                                       $enclosingAccum->addLiteral( str_repeat( $piece->open, $skippedBraces ) );
-                               }
-
-                               $stackFlags = $stack->getFlags();
-
-                               # Add XML element to the enclosing accumulator
-                               if ( $isTreeNode ) {
-                                       $accum->addNode( $tree );
-                               } else {
-                                       $accum->addAccum( $resultAccum );
-                               }
-                       } elseif ( $found === 'pipe' ) {
-                               $stackFlags['findEquals'] = true; // shortcut for getFlags()
-                               $stack->addPart();
-                               $accum = $stack->getAccum();
-                               ++$i;
-                       } elseif ( $found === 'equals' ) {
-                               $stackFlags['findEquals'] = false; // shortcut for getFlags()
-                               $accum->addNodeWithText( 'equals', '=' );
-                               $stack->getCurrentPart()->eqpos = $accum->lastNode;
-                               ++$i;
-                       }
-               }
-
-               # Output any remaining unclosed brackets
-               foreach ( $stack->stack as $variantPiece ) {
-                       $piece = PPDStackElement_HipHop::cast( $variantPiece );
-                       $stack->rootAccum->addAccum( $piece->breakSyntax() );
-               }
-
-               # Enable top-level headings
-               for ( $node = $stack->rootAccum->firstNode; $node; $node = $node->nextSibling ) {
-                       if ( isset( $node->name ) && $node->name === 'possible-h' ) {
-                               $node->name = 'h';
-                       }
-               }
-
-               $rootNode = new PPNode_HipHop_Tree( 'root' );
-               $rootNode->firstChild = $stack->rootAccum->firstNode;
-               $rootNode->lastChild = $stack->rootAccum->lastNode;
-
-               // Cache
-               if ($cacheable) {
-                       $cacheValue = sprintf( "%08d", self::CACHE_VERSION ) . serialize( $rootNode );
-                       $wgMemc->set( $cacheKey, $cacheValue, 86400 );
-                       wfProfileOut( __METHOD__.'-cache-miss' );
-                       wfProfileOut( __METHOD__.'-cacheable' );
-                       wfDebugLog( "Preprocessor", "Saved preprocessor Hash to memcached (key $cacheKey)" );
-               }
-
-               wfProfileOut( __METHOD__ );
-               return $rootNode;
-       }
-}
-
-
-
-/**
- * Stack class to help Preprocessor::preprocessToObj()
- * @ingroup Parser
- */
-class PPDStack_HipHop {
-       var $stack, $rootAccum;
-
-       /**
-        * @var PPDStack
-        */
-       var $top;
-       var $out;
-
-       static $false = false;
-
-       function __construct() {
-               $this->stack = array();
-               $this->top = false;
-               $this->rootAccum = new PPDAccum_HipHop;
-               $this->accum = $this->rootAccum;
-       }
-
-       /**
-        * @return int
-        */
-       function count() {
-               return count( $this->stack );
-       }
-
-       function getAccum() {
-               return PPDAccum_HipHop::cast( $this->accum );
-       }
-
-       function getCurrentPart() {
-               return $this->getTop()->getCurrentPart();
-       }
-
-       function getTop() {
-               return PPDStackElement_HipHop::cast( $this->top );
-       }
-
-       function push( $data ) {
-               if ( $data instanceof PPDStackElement_HipHop ) {
-                       $this->stack[] = $data;
-               } else {
-                       $this->stack[] = new PPDStackElement_HipHop( $data );
-               }
-               $this->top = $this->stack[ count( $this->stack ) - 1 ];
-               $this->accum = $this->top->getAccum();
-       }
-
-       function pop() {
-               if ( !count( $this->stack ) ) {
-                       throw new MWException( __METHOD__.': no elements remaining' );
-               }
-               $temp = array_pop( $this->stack );
-
-               if ( count( $this->stack ) ) {
-                       $this->top = $this->stack[ count( $this->stack ) - 1 ];
-                       $this->accum = $this->top->getAccum();
-               } else {
-                       $this->top = self::$false;
-                       $this->accum = $this->rootAccum;
-               }
-               return $temp;
-       }
-
-       function addPart( $s = '' ) {
-               $this->top->addPart( $s );
-               $this->accum = $this->top->getAccum();
-       }
-
-       /**
-        * @return array
-        */
-       function getFlags() {
-               if ( !count( $this->stack ) ) {
-                       return array(
-                               'findEquals' => false,
-                               'findPipe' => false,
-                               'inHeading' => false,
-                       );
-               } else {
-                       return $this->top->getFlags();
-               }
-       }
-}
-
-/**
- * @ingroup Parser
- */
-class PPDStackElement_HipHop {
-       var $open,              // Opening character (\n for heading)
-               $close,             // Matching closing character
-               $count,             // Number of opening characters found (number of "=" for heading)
-               $parts,             // Array of PPDPart objects describing pipe-separated parts.
-               $lineStart;         // True if the open char appeared at the start of the input line. Not set for headings.
-
-       /**
-        * @param $obj PPDStackElement_HipHop
-        * @return PPDStackElement_HipHop
-        */
-       static function cast( PPDStackElement_HipHop $obj ) {
-               return $obj;
-       }
-
-       /**
-        * @param $data array
-        */
-       function __construct( $data = array() ) {
-               $this->parts = array( new PPDPart_HipHop );
-
-               foreach ( $data as $name => $value ) {
-                       $this->$name = $value;
-               }
-       }
-
-       /**
-        * @return PPDAccum_HipHop
-        */
-       function getAccum() {
-               return PPDAccum_HipHop::cast( $this->parts[count($this->parts) - 1]->out );
-       }
-
-       /**
-        * @param $s string
-        */
-       function addPart( $s = '' ) {
-               $this->parts[] = new PPDPart_HipHop( $s );
-       }
-
-       /**
-        * @return PPDPart_HipHop
-        */
-       function getCurrentPart() {
-               return PPDPart_HipHop::cast( $this->parts[count($this->parts) - 1] );
-       }
-
-       /**
-        * @return array
-        */
-       function getFlags() {
-               $partCount = count( $this->parts );
-               $findPipe = $this->open !== "\n" && $this->open !== '[';
-               return array(
-                       'findPipe' => $findPipe,
-                       'findEquals' => $findPipe && $partCount > 1 && !isset( $this->parts[$partCount - 1]->eqpos ),
-                       'inHeading' => $this->open === "\n",
-               );
-       }
-
-       /**
-        * Get the accumulator that would result if the close is not found.
-        *
-        * @param $openingCount bool
-        * @return PPDAccum_HipHop
-        */
-       function breakSyntax( $openingCount = false ) {
-               if ( $this->open === "\n" ) {
-                       $accum = PPDAccum_HipHop::cast( $this->parts[0]->out );
-               } else {
-                       if ( $openingCount === false ) {
-                               $openingCount = $this->count;
-                       }
-                       $accum = new PPDAccum_HipHop;
-                       $accum->addLiteral( str_repeat( $this->open, $openingCount ) );
-                       $first = true;
-                       foreach ( $this->parts as $part ) {
-                               if ( $first ) {
-                                       $first = false;
-                               } else {
-                                       $accum->addLiteral( '|' );
-                               }
-                               $accum->addAccum( $part->out );
-                       }
-               }
-               return $accum;
-       }
-}
-
-/**
- * @ingroup Parser
- */
-class PPDPart_HipHop {
-       var $out; // Output accumulator object
-
-       // Optional member variables:
-       //   eqpos        Position of equals sign in output accumulator
-       //   commentEnd   Past-the-end input pointer for the last comment encountered
-       //   visualEnd    Past-the-end input pointer for the end of the accumulator minus comments
-
-       function __construct( $out = '' ) {
-               $this->out = new PPDAccum_HipHop;
-               if ( $out !== '' ) {
-                       $this->out->addLiteral( $out );
-               }
-       }
-
-       static function cast( PPDPart_HipHop $obj ) {
-               return $obj;
-       }
-}
-
-/**
- * @ingroup Parser
- */
-class PPDAccum_HipHop {
-       var $firstNode, $lastNode;
-
-       function __construct() {
-               $this->firstNode = $this->lastNode = false;
-       }
-
-       static function cast( PPDAccum_HipHop $obj ) {
-               return $obj;
-       }
-
-       /**
-        * Append a string literal
-        */
-       function addLiteral( string $s ) {
-               if ( $this->lastNode === false ) {
-                       $this->firstNode = $this->lastNode = new PPNode_HipHop_Text( $s );
-               } elseif ( $this->lastNode instanceof PPNode_HipHop_Text ) {
-                       $this->lastNode->value .= $s;
-               } else {
-                       $this->lastNode->nextSibling = new PPNode_HipHop_Text( $s );
-                       $this->lastNode = $this->lastNode->nextSibling;
-               }
-       }
-
-       /**
-        * Append a PPNode
-        */
-       function addNode( PPNode $node ) {
-               if ( $this->lastNode === false ) {
-                       $this->firstNode = $this->lastNode = $node;
-               } else {
-                       $this->lastNode->nextSibling = $node;
-                       $this->lastNode = $node;
-               }
-       }
-
-       /**
-        * Append a tree node with text contents
-        */
-       function addNodeWithText( string $name, string $value ) {
-               $node = PPNode_HipHop_Tree::newWithText( $name, $value );
-               $this->addNode( $node );
-       }
-
-       /**
-        * Append a PPDAccum_HipHop
-        * Takes over ownership of the nodes in the source argument. These nodes may
-        * subsequently be modified, especially nextSibling.
-        */
-       function addAccum( PPDAccum_HipHop $accum ) {
-               if ( $accum->lastNode === false ) {
-                       // nothing to add
-               } elseif ( $this->lastNode === false ) {
-                       $this->firstNode = $accum->firstNode;
-                       $this->lastNode = $accum->lastNode;
-               } else {
-                       $this->lastNode->nextSibling = $accum->firstNode;
-                       $this->lastNode = $accum->lastNode;
-               }
-       }
-}
-
-/**
- * An expansion frame, used as a context to expand the result of preprocessToObj()
- * @ingroup Parser
- */
-class PPFrame_HipHop implements PPFrame {
-
-       /**
-        * @var Parser
-        */
-       var $parser;
-
-       /**
-        * @var Preprocessor
-        */
-       var $preprocessor;
-
-       /**
-        * @var Title
-        */
-       var $title;
-       var $titleCache;
-
-       /**
-        * Hashtable listing templates which are disallowed for expansion in this frame,
-        * having been encountered previously in parent frames.
-        */
-       var $loopCheckHash;
-
-       /**
-        * Recursion depth of this frame, top = 0
-        * Note that this is NOT the same as expansion depth in expand()
-        */
-       var $depth;
-
-       /**
-        * Construct a new preprocessor frame.
-        * @param $preprocessor Preprocessor: the parent preprocessor
-        */
-       function __construct( $preprocessor ) {
-               $this->preprocessor = $preprocessor;
-               $this->parser = $preprocessor->parser;
-               $this->title = $this->parser->mTitle;
-               $this->titleCache = array( $this->title ? $this->title->getPrefixedDBkey() : false );
-               $this->loopCheckHash = array();
-               $this->depth = 0;
-       }
-
-       /**
-        * Create a new child frame
-        * $args is optionally a multi-root PPNode or array containing the template arguments
-        *
-        * @param $args PPNode_HipHop_Array|array|bool
-        * @param $title Title|bool
-        * @param $indexOffset A number subtracted from the index attributes of the arguments
-        *
-        * @throws MWException
-        * @return PPTemplateFrame_HipHop
-        */
-       function newChild( $args = false, $title = false, $indexOffset = 0 ) {
-               $namedArgs = array();
-               $numberedArgs = array();
-               if ( $title === false ) {
-                       $title = $this->title;
-               }
-               if ( $args !== false ) {
-                       if ( $args instanceof PPNode_HipHop_Array ) {
-                               $args = $args->value;
-                       } elseif ( !is_array( $args ) ) {
-                               throw new MWException( __METHOD__ . ': $args must be array or PPNode_HipHop_Array' );
-                       }
-                       foreach ( $args as $arg ) {
-                               $bits = $arg->splitArg();
-                               if ( $bits['index'] !== '' ) {
-                                       // Numbered parameter
-                                       $numberedArgs[$bits['index']] = $bits['value'];
-                                       unset( $namedArgs[$bits['index']] );
-                               } else {
-                                       // Named parameter
-                                       $name = trim( $this->expand( $bits['name'], PPFrame::STRIP_COMMENTS ) );
-                                       $namedArgs[$name] = $bits['value'];
-                                       unset( $numberedArgs[$name] );
-                               }
-                       }
-               }
-               return new PPTemplateFrame_HipHop( $this->preprocessor, $this, $numberedArgs, $namedArgs, $title );
-       }
-
-       /**
-        * @throws MWException
-        * @param $root
-        * @param $flags int
-        * @return string
-        */
-       function expand( $root, $flags = 0 ) {
-               static $expansionDepth = 0;
-               if ( is_string( $root ) ) {
-                       return $root;
-               }
-
-               if ( ++$this->parser->mPPNodeCount > $this->parser->mOptions->getMaxPPNodeCount() ) {
-                       $this->parser->limitationWarn( 'node-count-exceeded',
-                                       $this->parser->mPPNodeCount,
-                                       $this->parser->mOptions->getMaxPPNodeCount()
-                       );
-                       return '<span class="error">Node-count limit exceeded</span>';
-               }
-               if ( $expansionDepth > $this->parser->mOptions->getMaxPPExpandDepth() ) {
-                       $this->parser->limitationWarn( 'expansion-depth-exceeded',
-                                       $expansionDepth,
-                                       $this->parser->mOptions->getMaxPPExpandDepth()
-                       );
-                       return '<span class="error">Expansion depth limit exceeded</span>';
-               }
-               ++$expansionDepth;
-               if ( $expansionDepth > $this->parser->mHighestExpansionDepth ) {
-                       $this->parser->mHighestExpansionDepth = $expansionDepth;
-               }
-
-               $outStack = array( '', '' );
-               $iteratorStack = array( false, $root );
-               $indexStack = array( 0, 0 );
-
-               while ( count( $iteratorStack ) > 1 ) {
-                       $level = count( $outStack ) - 1;
-                       $iteratorNode =& $iteratorStack[ $level ];
-                       $out =& $outStack[$level];
-                       $index =& $indexStack[$level];
-
-                       if ( is_array( $iteratorNode ) ) {
-                               if ( $index >= count( $iteratorNode ) ) {
-                                       // All done with this iterator
-                                       $iteratorStack[$level] = false;
-                                       $contextNode = false;
-                               } else {
-                                       $contextNode = $iteratorNode[$index];
-                                       $index++;
-                               }
-                       } elseif ( $iteratorNode instanceof PPNode_HipHop_Array ) {
-                               if ( $index >= $iteratorNode->getLength() ) {
-                                       // All done with this iterator
-                                       $iteratorStack[$level] = false;
-                                       $contextNode = false;
-                               } else {
-                                       $contextNode = $iteratorNode->item( $index );
-                                       $index++;
-                               }
-                       } else {
-                               // Copy to $contextNode and then delete from iterator stack,
-                               // because this is not an iterator but we do have to execute it once
-                               $contextNode = $iteratorStack[$level];
-                               $iteratorStack[$level] = false;
-                       }
-
-                       $newIterator = false;
-
-                       if ( $contextNode === false ) {
-                               // nothing to do
-                       } elseif ( is_string( $contextNode ) ) {
-                               $out .= $contextNode;
-                       } elseif ( is_array( $contextNode ) || $contextNode instanceof PPNode_HipHop_Array ) {
-                               $newIterator = $contextNode;
-                       } elseif ( $contextNode instanceof PPNode_HipHop_Attr ) {
-                               // No output
-                       } elseif ( $contextNode instanceof PPNode_HipHop_Text ) {
-                               $out .= $contextNode->value;
-                       } elseif ( $contextNode instanceof PPNode_HipHop_Tree ) {
-                               if ( $contextNode->name === 'template' ) {
-                                       # Double-brace expansion
-                                       $bits = $contextNode->splitTemplate();
-                                       if ( $flags & PPFrame::NO_TEMPLATES ) {
-                                               $newIterator = $this->virtualBracketedImplode( '{{', '|', '}}', $bits['title'], $bits['parts'] );
-                                       } else {
-                                               $ret = $this->parser->braceSubstitution( $bits, $this );
-                                               if ( isset( $ret['object'] ) ) {
-                                                       $newIterator = $ret['object'];
-                                               } else {
-                                                       $out .= $ret['text'];
-                                               }
-                                       }
-                               } elseif ( $contextNode->name === 'tplarg' ) {
-                                       # Triple-brace expansion
-                                       $bits = $contextNode->splitTemplate();
-                                       if ( $flags & PPFrame::NO_ARGS ) {
-                                               $newIterator = $this->virtualBracketedImplode( '{{{', '|', '}}}', $bits['title'], $bits['parts'] );
-                                       } else {
-                                               $ret = $this->parser->argSubstitution( $bits, $this );
-                                               if ( isset( $ret['object'] ) ) {
-                                                       $newIterator = $ret['object'];
-                                               } else {
-                                                       $out .= $ret['text'];
-                                               }
-                                       }
-                               } elseif ( $contextNode->name === 'comment' ) {
-                                       # HTML-style comment
-                                       # Remove it in HTML, pre+remove and STRIP_COMMENTS modes
-                                       if ( $this->parser->ot['html']
-                                               || ( $this->parser->ot['pre'] && $this->parser->mOptions->getRemoveComments() )
-                                               || ( $flags & PPFrame::STRIP_COMMENTS ) )
-                                       {
-                                               $out .= '';
-                                       }
-                                       # Add a strip marker in PST mode so that pstPass2() can run some old-fashioned regexes on the result
-                                       # Not in RECOVER_COMMENTS mode (extractSections) though
-                                       elseif ( $this->parser->ot['wiki'] && ! ( $flags & PPFrame::RECOVER_COMMENTS ) ) {
-                                               $out .= $this->parser->insertStripItem( $contextNode->firstChild->value );
-                                       }
-                                       # Recover the literal comment in RECOVER_COMMENTS and pre+no-remove
-                                       else {
-                                               $out .= $contextNode->firstChild->value;
-                                       }
-                               } elseif ( $contextNode->name === 'ignore' ) {
-                                       # Output suppression used by <includeonly> etc.
-                                       # OT_WIKI will only respect <ignore> in substed templates.
-                                       # The other output types respect it unless NO_IGNORE is set.
-                                       # extractSections() sets NO_IGNORE and so never respects it.
-                                       if ( ( !isset( $this->parent ) && $this->parser->ot['wiki'] ) || ( $flags & PPFrame::NO_IGNORE ) ) {
-                                               $out .= $contextNode->firstChild->value;
-                                       } else {
-                                               //$out .= '';
-                                       }
-                               } elseif ( $contextNode->name === 'ext' ) {
-                                       # Extension tag
-                                       $bits = $contextNode->splitExt() + array( 'attr' => null, 'inner' => null, 'close' => null );
-                                       $out .= $this->parser->extensionSubstitution( $bits, $this );
-                               } elseif ( $contextNode->name === 'h' ) {
-                                       # Heading
-                                       if ( $this->parser->ot['html'] ) {
-                                               # Expand immediately and insert heading index marker
-                                               $s = '';
-                                               for ( $node = $contextNode->firstChild; $node; $node = $node->nextSibling ) {
-                                                       $s .= $this->expand( $node, $flags );
-                                               }
-
-                                               $bits = $contextNode->splitHeading();
-                                               $titleText = $this->title->getPrefixedDBkey();
-                                               $this->parser->mHeadings[] = array( $titleText, $bits['i'] );
-                                               $serial = count( $this->parser->mHeadings ) - 1;
-                                               $marker = "{$this->parser->mUniqPrefix}-h-$serial-" . Parser::MARKER_SUFFIX;
-                                               $s = substr( $s, 0, $bits['level'] ) . $marker . substr( $s, $bits['level'] );
-                                               $this->parser->mStripState->addGeneral( $marker, '' );
-                                               $out .= $s;
-                                       } else {
-                                               # Expand in virtual stack
-                                               $newIterator = $contextNode->getChildren();
-                                       }
-                               } else {
-                                       # Generic recursive expansion
-                                       $newIterator = $contextNode->getChildren();
-                               }
-                       } else {
-                               throw new MWException( __METHOD__.': Invalid parameter type' );
-                       }
-
-                       if ( $newIterator !== false ) {
-                               $outStack[] = '';
-                               $iteratorStack[] = $newIterator;
-                               $indexStack[] = 0;
-                       } elseif ( $iteratorStack[$level] === false ) {
-                               // Return accumulated value to parent
-                               // With tail recursion
-                               while ( $iteratorStack[$level] === false && $level > 0 ) {
-                                       $outStack[$level - 1] .= $out;
-                                       array_pop( $outStack );
-                                       array_pop( $iteratorStack );
-                                       array_pop( $indexStack );
-                                       $level--;
-                               }
-                       }
-               }
-               --$expansionDepth;
-               return $outStack[0];
-       }
-
-       /**
-        * @param $sep
-        * @param $flags
-        * @return string
-        */
-       function implodeWithFlags( $sep, $flags /*, ... */ ) {
-               $args = array_slice( func_get_args(), 2 );
-
-               $first = true;
-               $s = '';
-               foreach ( $args as $root ) {
-                       if ( $root instanceof PPNode_HipHop_Array ) {
-                               $root = $root->value;
-                       }
-                       if ( !is_array( $root ) ) {
-                               $root = array( $root );
-                       }
-                       foreach ( $root as $node ) {
-                               if ( $first ) {
-                                       $first = false;
-                               } else {
-                                       $s .= $sep;
-                               }
-                               $s .= $this->expand( $node, $flags );
-                       }
-               }
-               return $s;
-       }
-
-       /**
-        * Implode with no flags specified
-        * This previously called implodeWithFlags but has now been inlined to reduce stack depth
-        * @param $sep
-        * @return string
-        */
-       function implode( $sep /*, ... */ ) {
-               $args = array_slice( func_get_args(), 1 );
-
-               $first = true;
-               $s = '';
-               foreach ( $args as $root ) {
-                       if ( $root instanceof PPNode_HipHop_Array ) {
-                               $root = $root->value;
-                       }
-                       if ( !is_array( $root ) ) {
-                               $root = array( $root );
-                       }
-                       foreach ( $root as $node ) {
-                               if ( $first ) {
-                                       $first = false;
-                               } else {
-                                       $s .= $sep;
-                               }
-                               $s .= $this->expand( $node );
-                       }
-               }
-               return $s;
-       }
-
-       /**
-        * Makes an object that, when expand()ed, will be the same as one obtained
-        * with implode()
-        *
-        * @param $sep
-        * @return PPNode_HipHop_Array
-        */
-       function virtualImplode( $sep /*, ... */ ) {
-               $args = array_slice( func_get_args(), 1 );
-               $out = array();
-               $first = true;
-
-               foreach ( $args as $root ) {
-                       if ( $root instanceof PPNode_HipHop_Array ) {
-                               $root = $root->value;
-                       }
-                       if ( !is_array( $root ) ) {
-                               $root = array( $root );
-                       }
-                       foreach ( $root as $node ) {
-                               if ( $first ) {
-                                       $first = false;
-                               } else {
-                                       $out[] = $sep;
-                               }
-                               $out[] = $node;
-                       }
-               }
-               return new PPNode_HipHop_Array( $out );
-       }
-
-       /**
-        * Virtual implode with brackets
-        *
-        * @param $start
-        * @param $sep
-        * @param $end
-        * @return PPNode_HipHop_Array
-        */
-       function virtualBracketedImplode( $start, $sep, $end /*, ... */ ) {
-               $args = array_slice( func_get_args(), 3 );
-               $out = array( $start );
-               $first = true;
-
-               foreach ( $args as $root ) {
-                       if ( $root instanceof PPNode_HipHop_Array ) {
-                               $root = $root->value;
-                       }
-                       if ( !is_array( $root ) ) {
-                               $root = array( $root );
-                       }
-                       foreach ( $root as $node ) {
-                               if ( $first ) {
-                                       $first = false;
-                               } else {
-                                       $out[] = $sep;
-                               }
-                               $out[] = $node;
-                       }
-               }
-               $out[] = $end;
-               return new PPNode_HipHop_Array( $out );
-       }
-
-       function __toString() {
-               return 'frame{}';
-       }
-
-       /**
-        * @param $level bool
-        * @return array|bool|String
-        */
-       function getPDBK( $level = false ) {
-               if ( $level === false ) {
-                       return $this->title->getPrefixedDBkey();
-               } else {
-                       return isset( $this->titleCache[$level] ) ? $this->titleCache[$level] : false;
-               }
-       }
-
-       /**
-        * @return array
-        */
-       function getArguments() {
-               return array();
-       }
-
-       /**
-        * @return array
-        */
-       function getNumberedArguments() {
-               return array();
-       }
-
-       /**
-        * @return array
-        */
-       function getNamedArguments() {
-               return array();
-       }
-
-       /**
-        * Returns true if there are no arguments in this frame
-        *
-        * @return bool
-        */
-       function isEmpty() {
-               return true;
-       }
-
-       /**
-        * @param $name
-        * @return bool
-        */
-       function getArgument( $name ) {
-               return false;
-       }
-
-       /**
-        * Returns true if the infinite loop check is OK, false if a loop is detected
-        *
-        * @param $title Title
-        *
-        * @return bool
-        */
-       function loopCheck( $title ) {
-               return !isset( $this->loopCheckHash[$title->getPrefixedDBkey()] );
-       }
-
-       /**
-        * Return true if the frame is a template frame
-        *
-        * @return bool
-        */
-       function isTemplate() {
-               return false;
-       }
-
-       /**
-        * Get a title of frame
-        *
-        * @return Title
-        */
-       function getTitle() {
-               return $this->title;
-       }
-}
-
-/**
- * Expansion frame with template arguments
- * @ingroup Parser
- */
-class PPTemplateFrame_HipHop extends PPFrame_HipHop {
-       var $numberedArgs, $namedArgs, $parent;
-       var $numberedExpansionCache, $namedExpansionCache;
-
-       /**
-        * @param $preprocessor Preprocessor_HipHop
-        * @param $parent bool
-        * @param $numberedArgs array
-        * @param $namedArgs array
-        * @param $title Title|bool
-        */
-       function __construct( $preprocessor, $parent = false, $numberedArgs = array(), $namedArgs = array(), $title = false ) {
-               parent::__construct( $preprocessor );
-
-               $this->parent = $parent;
-               $this->numberedArgs = $numberedArgs;
-               $this->namedArgs = $namedArgs;
-               $this->title = $title;
-               $pdbk = $title ? $title->getPrefixedDBkey() : false;
-               $this->titleCache = $parent->titleCache;
-               $this->titleCache[] = $pdbk;
-               $this->loopCheckHash = /*clone*/ $parent->loopCheckHash;
-               if ( $pdbk !== false ) {
-                       $this->loopCheckHash[$pdbk] = true;
-               }
-               $this->depth = $parent->depth + 1;
-               $this->numberedExpansionCache = $this->namedExpansionCache = array();
-       }
-
-       function __toString() {
-               $s = 'tplframe{';
-               $first = true;
-               $args = $this->numberedArgs + $this->namedArgs;
-               foreach ( $args as $name => $value ) {
-                       if ( $first ) {
-                               $first = false;
-                       } else {
-                               $s .= ', ';
-                       }
-                       $s .= "\"$name\":\"" .
-                               str_replace( '"', '\\"', $value->__toString() ) . '"';
-               }
-               $s .= '}';
-               return $s;
-       }
-       /**
-        * Returns true if there are no arguments in this frame
-        *
-        * @return bool
-        */
-       function isEmpty() {
-               return !count( $this->numberedArgs ) && !count( $this->namedArgs );
-       }
-
-       /**
-        * @return array
-        */
-       function getArguments() {
-               $arguments = array();
-               foreach ( array_merge(
-                               array_keys($this->numberedArgs),
-                               array_keys($this->namedArgs)) as $key ) {
-                       $arguments[$key] = $this->getArgument($key);
-               }
-               return $arguments;
-       }
-
-       /**
-        * @return array
-        */
-       function getNumberedArguments() {
-               $arguments = array();
-               foreach ( array_keys($this->numberedArgs) as $key ) {
-                       $arguments[$key] = $this->getArgument($key);
-               }
-               return $arguments;
-       }
-
-       /**
-        * @return array
-        */
-       function getNamedArguments() {
-               $arguments = array();
-               foreach ( array_keys($this->namedArgs) as $key ) {
-                       $arguments[$key] = $this->getArgument($key);
-               }
-               return $arguments;
-       }
-
-       /**
-        * @param $index
-        * @return array|bool
-        */
-       function getNumberedArgument( $index ) {
-               if ( !isset( $this->numberedArgs[$index] ) ) {
-                       return false;
-               }
-               if ( !isset( $this->numberedExpansionCache[$index] ) ) {
-                       # No trimming for unnamed arguments
-                       $this->numberedExpansionCache[$index] = $this->parent->expand( $this->numberedArgs[$index], PPFrame::STRIP_COMMENTS );
-               }
-               return $this->numberedExpansionCache[$index];
-       }
-
-       /**
-        * @param $name
-        * @return bool
-        */
-       function getNamedArgument( $name ) {
-               if ( !isset( $this->namedArgs[$name] ) ) {
-                       return false;
-               }
-               if ( !isset( $this->namedExpansionCache[$name] ) ) {
-                       # Trim named arguments post-expand, for backwards compatibility
-                       $this->namedExpansionCache[$name] = trim(
-                               $this->parent->expand( $this->namedArgs[$name], PPFrame::STRIP_COMMENTS ) );
-               }
-               return $this->namedExpansionCache[$name];
-       }
-
-       /**
-        * @param $name
-        * @return array|bool
-        */
-       function getArgument( $name ) {
-               $text = $this->getNumberedArgument( $name );
-               if ( $text === false ) {
-                       $text = $this->getNamedArgument( $name );
-               }
-               return $text;
-       }
-
-       /**
-        * Return true if the frame is a template frame
-        *
-        * @return bool
-        */
-       function isTemplate() {
-               return true;
-       }
-}
-
-/**
- * Expansion frame with custom arguments
- * @ingroup Parser
- */
-class PPCustomFrame_HipHop extends PPFrame_HipHop {
-       var $args;
-
-       function __construct( $preprocessor, $args ) {
-               parent::__construct( $preprocessor );
-               $this->args = $args;
-       }
-
-       function __toString() {
-               $s = 'cstmframe{';
-               $first = true;
-               foreach ( $this->args as $name => $value ) {
-                       if ( $first ) {
-                               $first = false;
-                       } else {
-                               $s .= ', ';
-                       }
-                       $s .= "\"$name\":\"" .
-                               str_replace( '"', '\\"', $value->__toString() ) . '"';
-               }
-               $s .= '}';
-               return $s;
-       }
-
-       /**
-        * @return bool
-        */
-       function isEmpty() {
-               return !count( $this->args );
-       }
-
-       /**
-        * @param $index
-        * @return bool
-        */
-       function getArgument( $index ) {
-               if ( !isset( $this->args[$index] ) ) {
-                       return false;
-               }
-               return $this->args[$index];
-       }
-}
-
-/**
- * @ingroup Parser
- */
-class PPNode_HipHop_Tree implements PPNode {
-       var $name, $firstChild, $lastChild, $nextSibling;
-
-       function __construct( $name ) {
-               $this->name = $name;
-               $this->firstChild = $this->lastChild = $this->nextSibling = false;
-       }
-
-       function __toString() {
-               $inner = '';
-               $attribs = '';
-               for ( $node = $this->firstChild; $node; $node = $node->nextSibling ) {
-                       if ( $node instanceof PPNode_HipHop_Attr ) {
-                               $attribs .= ' ' . $node->name . '="' . htmlspecialchars( $node->value ) . '"';
-                       } else {
-                               $inner .= $node->__toString();
-                       }
-               }
-               if ( $inner === '' ) {
-                       return "<{$this->name}$attribs/>";
-               } else {
-                       return "<{$this->name}$attribs>$inner</{$this->name}>";
-               }
-       }
-
-       /**
-        * @param $name
-        * @param $text
-        * @return PPNode_HipHop_Tree
-        */
-       static function newWithText( $name, $text ) {
-               $obj = new self( $name );
-               $obj->addChild( new PPNode_HipHop_Text( $text ) );
-               return $obj;
-       }
-
-       function addChild( $node ) {
-               if ( $this->lastChild === false ) {
-                       $this->firstChild = $this->lastChild = $node;
-               } else {
-                       $this->lastChild->nextSibling = $node;
-                       $this->lastChild = $node;
-               }
-       }
-
-       /**
-        * @return PPNode_HipHop_Array
-        */
-       function getChildren() {
-               $children = array();
-               for ( $child = $this->firstChild; $child; $child = $child->nextSibling ) {
-                       $children[] = $child;
-               }
-               return new PPNode_HipHop_Array( $children );
-       }
-
-       function getFirstChild() {
-               return $this->firstChild;
-       }
-
-       function getNextSibling() {
-               return $this->nextSibling;
-       }
-
-       /**
-        * @param $name string
-        * @return array
-        */
-       function getChildrenOfType( $name ) {
-               $children = array();
-               for ( $child = $this->firstChild; $child; $child = $child->nextSibling ) {
-                       if ( isset( $child->name ) && $child->name === $name ) {
-                               $children[] = $child;
-                       }
-               }
-               return $children;
-       }
-
-       /**
-        * @return bool
-        */
-       function getLength() {
-               return false;
-       }
-
-       /**
-        * @param  $i
-        * @return bool
-        */
-       function item( $i ) {
-               return false;
-       }
-
-       /**
-        * @return string
-        */
-       function getName() {
-               return $this->name;
-       }
-
-       /**
-        * Split a <part> node into an associative array containing:
-        *    name          PPNode name
-        *    index         String index
-        *    value         PPNode value
-        *
-        * @throws MWException
-        * @return array
-        */
-       function splitArg() {
-               $bits = array();
-               for ( $child = $this->firstChild; $child; $child = $child->nextSibling ) {
-                       if ( !isset( $child->name ) ) {
-                               continue;
-                       }
-                       if ( $child->name === 'name' ) {
-                               $bits['name'] = $child;
-                               if ( $child->firstChild instanceof PPNode_HipHop_Attr
-                                       && $child->firstChild->name === 'index' )
-                               {
-                                       $bits['index'] = $child->firstChild->value;
-                               }
-                       } elseif ( $child->name === 'value' ) {
-                               $bits['value'] = $child;
-                       }
-               }
-
-               if ( !isset( $bits['name'] ) ) {
-                       throw new MWException( 'Invalid brace node passed to ' . __METHOD__ );
-               }
-               if ( !isset( $bits['index'] ) ) {
-                       $bits['index'] = '';
-               }
-               return $bits;
-       }
-
-       /**
-        * Split an <ext> node into an associative array containing name, attr, inner and close
-        * All values in the resulting array are PPNodes. Inner and close are optional.
-        *
-        * @throws MWException
-        * @return array
-        */
-       function splitExt() {
-               $bits = array();
-               for ( $child = $this->firstChild; $child; $child = $child->nextSibling ) {
-                       if ( !isset( $child->name ) ) {
-                               continue;
-                       }
-                       if ( $child->name === 'name' ) {
-                               $bits['name'] = $child;
-                       } elseif ( $child->name === 'attr' ) {
-                               $bits['attr'] = $child;
-                       } elseif ( $child->name === 'inner' ) {
-                               $bits['inner'] = $child;
-                       } elseif ( $child->name === 'close' ) {
-                               $bits['close'] = $child;
-                       }
-               }
-               if ( !isset( $bits['name'] ) ) {
-                       throw new MWException( 'Invalid ext node passed to ' . __METHOD__ );
-               }
-               return $bits;
-       }
-
-       /**
-        * Split an <h> node
-        *
-        * @throws MWException
-        * @return array
-        */
-       function splitHeading() {
-               if ( $this->name !== 'h' ) {
-                       throw new MWException( 'Invalid h node passed to ' . __METHOD__ );
-               }
-               $bits = array();
-               for ( $child = $this->firstChild; $child; $child = $child->nextSibling ) {
-                       if ( !isset( $child->name ) ) {
-                               continue;
-                       }
-                       if ( $child->name === 'i' ) {
-                               $bits['i'] = $child->value;
-                       } elseif ( $child->name === 'level' ) {
-                               $bits['level'] = $child->value;
-                       }
-               }
-               if ( !isset( $bits['i'] ) ) {
-                       throw new MWException( 'Invalid h node passed to ' . __METHOD__ );
-               }
-               return $bits;
-       }
-
-       /**
-        * Split a <template> or <tplarg> node
-        *
-        * @throws MWException
-        * @return array
-        */
-       function splitTemplate() {
-               $parts = array();
-               $bits = array( 'lineStart' => '' );
-               for ( $child = $this->firstChild; $child; $child = $child->nextSibling ) {
-                       if ( !isset( $child->name ) ) {
-                               continue;
-                       }
-                       if ( $child->name === 'title' ) {
-                               $bits['title'] = $child;
-                       }
-                       if ( $child->name === 'part' ) {
-                               $parts[] = $child;
-                       }
-                       if ( $child->name === 'lineStart' ) {
-                               $bits['lineStart'] = '1';
-                       }
-               }
-               if ( !isset( $bits['title'] ) ) {
-                       throw new MWException( 'Invalid node passed to ' . __METHOD__ );
-               }
-               $bits['parts'] = new PPNode_HipHop_Array( $parts );
-               return $bits;
-       }
-}
-
-/**
- * @ingroup Parser
- */
-class PPNode_HipHop_Text implements PPNode {
-       var $value, $nextSibling;
-
-       function __construct( $value ) {
-               if ( is_object( $value ) ) {
-                       throw new MWException( __CLASS__ . ' given object instead of string' );
-               }
-               $this->value = $value;
-       }
-
-       function __toString() {
-               return htmlspecialchars( $this->value );
-       }
-
-       function getNextSibling() {
-               return $this->nextSibling;
-       }
-
-       function getChildren() { return false; }
-       function getFirstChild() { return false; }
-       function getChildrenOfType( $name ) { return false; }
-       function getLength() { return false; }
-       function item( $i ) { return false; }
-       function getName() { return '#text'; }
-       function splitArg() { throw new MWException( __METHOD__ . ': not supported' ); }
-       function splitExt() { throw new MWException( __METHOD__ . ': not supported' ); }
-       function splitHeading() { throw new MWException( __METHOD__ . ': not supported' ); }
-}
-
-/**
- * @ingroup Parser
- */
-class PPNode_HipHop_Array implements PPNode {
-       var $value, $nextSibling;
-
-       function __construct( $value ) {
-               $this->value = $value;
-       }
-
-       function __toString() {
-               return var_export( $this, true );
-       }
-
-       function getLength() {
-               return count( $this->value );
-       }
-
-       function item( $i ) {
-               return $this->value[$i];
-       }
-
-       function getName() { return '#nodelist'; }
-
-       function getNextSibling() {
-               return $this->nextSibling;
-       }
-
-       function getChildren() { return false; }
-       function getFirstChild() { return false; }
-       function getChildrenOfType( $name ) { return false; }
-       function splitArg() { throw new MWException( __METHOD__ . ': not supported' ); }
-       function splitExt() { throw new MWException( __METHOD__ . ': not supported' ); }
-       function splitHeading() { throw new MWException( __METHOD__ . ': not supported' ); }
-}
-
-/**
- * @ingroup Parser
- */
-class PPNode_HipHop_Attr implements PPNode {
-       var $name, $value, $nextSibling;
-
-       function __construct( $name, $value ) {
-               $this->name = $name;
-               $this->value = $value;
-       }
-
-       function __toString() {
-               return "<@{$this->name}>" . htmlspecialchars( $this->value ) . "</@{$this->name}>";
-       }
-
-       function getName() {
-               return $this->name;
-       }
-
-       function getNextSibling() {
-               return $this->nextSibling;
-       }
-
-       function getChildren() { return false; }
-       function getFirstChild() { return false; }
-       function getChildrenOfType( $name ) { return false; }
-       function getLength() { return false; }
-       function item( $i ) { return false; }
-       function splitArg() { throw new MWException( __METHOD__ . ': not supported' ); }
-       function splitExt() { throw new MWException( __METHOD__ . ': not supported' ); }
-       function splitHeading() { throw new MWException( __METHOD__ . ': not supported' ); }
-}
index 57f623d..5f3f18e 100644 (file)
@@ -233,4 +233,3 @@ class StripState {
                return preg_replace( $this->regex, '', $text );
        }
 }
-
index dd7e965..4994d3e 100644 (file)
@@ -68,9 +68,9 @@ class MWTidyWrapper {
                $wrappedtext = preg_replace( '!<(link|meta)([^>]*?)(/{0,1}>)!', '<html-$1$2$3', $wrappedtext );
 
                // Wrap the whole thing in a doctype and body for Tidy.
-               $wrappedtext = '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"'.
-                       ' "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html>'.
-                       '<head><title>test</title></head><body>'.$wrappedtext.'</body></html>';
+               $wrappedtext = '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"' .
+                       ' "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html>' .
+                       '<head><title>test</title></head><body>' . $wrappedtext . '</body></html>';
 
                return $wrappedtext;
        }
index b30b031..1ead836 100644 (file)
@@ -178,10 +178,10 @@ class Profiler {
                        $this->debug( str_repeat( ' ', count( $this->mWorkStack ) - 1 ) . 'Exiting ' . $functionname . "\n" );
                }
 
-               $bit = array_pop($this->mWorkStack);
+               $bit = array_pop( $this->mWorkStack );
 
-               if (!$bit) {
-                       $this->debug("Profiling error, !\$bit: $functionname\n");
+               if ( !$bit ) {
+                       $this->debug( "Profiling error, !\$bit: $functionname\n" );
                } else {
                        //if( $wgDebugProfiling ) {
                                if( $functionname == 'close' ) {
@@ -293,9 +293,9 @@ class Profiler {
         * @return string
         */
        function getCallTreeLine( $entry ) {
-               list( $fname, $level, $start, /* $x */, $end = $entry;
+               list( $fname, $level, $start, /* $x */, $end ) = $entry;
                $delta = $end - $start;
-               $space = str_repeat(' ', $level);
+               $space = str_repeat( ' ', $level );
                # The ugly double sprintf is to work around a PHP bug,
                # which has been fixed in recent releases.
                return sprintf( "%10s %s %s\n", trim( sprintf( "%7.3f", $delta * 1000.0 ) ), $space, $fname );
@@ -386,7 +386,7 @@ class Profiler {
                $this->mMemory = array();
 
                # Estimate profiling overhead
-               $profileCount = count($this->mStack);
+               $profileCount = count( $this->mStack );
                self::calculateOverhead( $profileCount );
 
                # First, subtract the overhead!
@@ -441,8 +441,8 @@ class Profiler {
                        $this->mCollated[$fname] += $elapsed;
                        $this->mCalls[$fname]++;
                        $this->mMemory[$fname] += $memory;
-                       $this->mMin[$fname] = min($this->mMin[$fname], $elapsed);
-                       $this->mMax[$fname] = max($this->mMax[$fname], $elapsed);
+                       $this->mMin[$fname] = min( $this->mMin[$fname], $elapsed );
+                       $this->mMax[$fname] = max( $this->mMax[$fname], $elapsed );
                        $this->mOverhead[$fname] += $subcalls;
                }
 
@@ -499,10 +499,10 @@ class Profiler {
         * @return Integer
         * @private
         */
-       function calltreeCount($stack, $start) {
+       function calltreeCount( $stack, $start ) {
                $level = $stack[$start][1];
                $count = 0;
-               for ($i = $start -1; $i >= 0 && $stack[$i][1] > $level; $i --) {
+               for ( $i = $start -1; $i >= 0 && $stack[$i][1] > $level; $i-- ) {
                        $count ++;
                }
                return $count;
@@ -557,9 +557,9 @@ class Profiler {
 
                                $rc = $dbw->affectedRows();
                                if ( $rc == 0 ) {
-                                       $dbw->insert('profiling', array ('pf_name' => $name, 'pf_count' => $eventCount,
+                                       $dbw->insert( 'profiling', array ( 'pf_name' => $name, 'pf_count' => $eventCount,
                                                'pf_time' => $timeSum, 'pf_memory' => $memorySum, 'pf_server' => $pfhost ),
-                                               __METHOD__, array ('IGNORE'));
+                                               __METHOD__, array ( 'IGNORE' ) );
                                }
                                // When we upgrade to mysql 4.1, the insert+update
                                // can be merged into just a insert with this construct added:
index d1d1c5d..1322e47 100644 (file)
@@ -29,7 +29,7 @@
 class ProfilerSimple extends Profiler {
        var $mMinimumTime = 0;
 
-       var $zeroEntry = array('cpu'=> 0.0, 'cpu_sq' => 0.0, 'real' => 0.0, 'real_sq' => 0.0, 'count' => 0);
+       var $zeroEntry = array( 'cpu'=> 0.0, 'cpu_sq' => 0.0, 'real' => 0.0, 'real_sq' => 0.0, 'count' => 0 );
        var $errorEntry;
 
        public function isPersistent() {
@@ -57,33 +57,33 @@ class ProfilerSimple extends Profiler {
                $this->mMinimumTime = $min;
        }
 
-       function profileIn($functionname) {
+       function profileIn( $functionname ) {
                global $wgDebugFunctionEntry;
-               if ($wgDebugFunctionEntry) {
-                       $this->debug(str_repeat(' ', count($this->mWorkStack)).'Entering '.$functionname."\n");
+               if ( $wgDebugFunctionEntry ) {
+                       $this->debug( str_repeat( ' ', count( $this->mWorkStack ) ) . 'Entering ' . $functionname . "\n" );
                }
                $this->mWorkStack[] = array( $functionname, count( $this->mWorkStack ), $this->getTime(), $this->getTime( 'cpu' ) );
        }
 
-       function profileOut($functionname) {
+       function profileOut( $functionname ) {
                global $wgDebugFunctionEntry;
 
-               if ($wgDebugFunctionEntry) {
-                       $this->debug(str_repeat(' ', count($this->mWorkStack) - 1).'Exiting '.$functionname."\n");
+               if ( $wgDebugFunctionEntry ) {
+                       $this->debug( str_repeat( ' ', count( $this->mWorkStack ) - 1 ) . 'Exiting ' . $functionname . "\n" );
                }
 
-               list($ofname, /* $ocount */ ,$ortime,$octime) = array_pop($this->mWorkStack);
+               list( $ofname, /* $ocount */, $ortime, $octime ) = array_pop( $this->mWorkStack );
 
-               if (!$ofname) {
-                       $this->debug("Profiling error: $functionname\n");
+               if ( !$ofname ) {
+                       $this->debug( "Profiling error: $functionname\n" );
                } else {
-                       if ($functionname == 'close') {
+                       if ( $functionname == 'close' ) {
                                $message = "Profile section ended by close(): {$ofname}";
                                $functionname = $ofname;
                                $this->debug( "$message\n" );
                                $this->mCollated[$message] = $this->errorEntry;
                        }
-                       elseif ($ofname != $functionname) {
+                       elseif ( $ofname != $functionname ) {
                                $message = "Profiling error: in({$ofname}), out($functionname)";
                                $this->debug( "$message\n" );
                                $this->mCollated[$message] = $this->errorEntry;
@@ -91,7 +91,7 @@ class ProfilerSimple extends Profiler {
                        $entry =& $this->mCollated[$functionname];
                        $elapsedcpu = $this->getTime( 'cpu' ) - $octime;
                        $elapsedreal = $this->getTime() - $ortime;
-                       if (!is_array($entry)) {
+                       if ( !is_array( $entry ) ) {
                                $entry = $this->zeroEntry;
                                $this->mCollated[$functionname] =& $entry;
                        }
index e62622f..37350bf 100644 (file)
@@ -48,9 +48,9 @@ class ProfilerSimpleText extends ProfilerSimple {
                        $totalReal = isset( $this->mCollated['-total'] )
                                ? $this->mCollated['-total']['real']
                                : 0; // profiling mismatch error?
-                       uasort( $this->mCollated, array('self','sort') );
-                       array_walk( $this->mCollated, array('self','format'), $totalReal );
-                       if ( php_sapi_name() === 'cli' ) {
+                       uasort( $this->mCollated, array( 'self', 'sort' ) );
+                       array_walk( $this->mCollated, array( 'self', 'format' ), $totalReal );
+                       if ( PHP_SAPI === 'cli' ) {
                                print "<!--\n".self::$out."\n-->\n";
                        } elseif ( $this->getContentType() === 'text/html' ) {
                                if ( $this->visible ) {
index 017e135..d44dfe1 100644 (file)
@@ -32,18 +32,18 @@ class ProfilerSimpleTrace extends ProfilerSimple {
 
        function profileIn( $functionname ) {
                parent::profileIn( $functionname );
-               $this->trace .= "         " . sprintf("%6.1f",$this->memoryDiff()) .
-                               str_repeat( " ", count($this->mWorkStack)) . " > " . $functionname . "\n";
+               $this->trace .= "         " . sprintf( "%6.1f", $this->memoryDiff() ) .
+                               str_repeat( " ", count( $this->mWorkStack ) ) . " > " . $functionname . "\n";
        }
 
-       function profileOut($functionname) {
+       function profileOut( $functionname ) {
                global $wgDebugFunctionEntry;
 
                if ( $wgDebugFunctionEntry ) {
-                       $this->debug(str_repeat(' ', count($this->mWorkStack) - 1).'Exiting '.$functionname."\n");
+                       $this->debug( str_repeat( ' ', count( $this->mWorkStack ) - 1 ) . 'Exiting ' . $functionname . "\n" );
                }
 
-               list( $ofname, /* $ocount */ , $ortime ) = array_pop( $this->mWorkStack );
+               list( $ofname, /* $ocount */, $ortime ) = array_pop( $this->mWorkStack );
 
                if ( !$ofname ) {
                        $this->trace .= "Profiling error: $functionname\n";
@@ -58,7 +58,7 @@ class ProfilerSimpleTrace extends ProfilerSimple {
                        }
                        $elapsedreal = $this->getTime() - $ortime;
                        $this->trace .= sprintf( "%03.6f %6.1f", $elapsedreal, $this->memoryDiff() ) .
-                                       str_repeat(" ", count( $this->mWorkStack ) + 1 ) . " < " . $functionname . "\n";
+                                       str_repeat( " ", count( $this->mWorkStack ) + 1 ) . " < " . $functionname . "\n";
                }
        }
 
@@ -69,7 +69,7 @@ class ProfilerSimpleTrace extends ProfilerSimple {
        }
 
        function logData() {
-               if ( php_sapi_name() === 'cli' ) {
+               if ( PHP_SAPI === 'cli' ) {
                        print "<!-- \n {$this->trace} \n -->";
                } elseif ( $this->getContentType() === 'text/html' ) {
                        print "<!-- \n {$this->trace} \n -->";
index a95ccb0..abefa81 100644 (file)
@@ -50,7 +50,7 @@ class ProfilerSimpleUDP extends ProfilerSimple {
                $plength = 0;
                $packet = "";
                foreach ( $this->mCollated as $entry => $pfdata ) {
-                       if( !isset($pfdata['count'])
+                       if( !isset( $pfdata['count'] )
                                || !isset( $pfdata['cpu'] )
                                || !isset( $pfdata['cpu_sq'] )
                                || !isset( $pfdata['real'] )
index fad0027..9904107 100644 (file)
@@ -441,9 +441,9 @@ class ResourceLoaderFileModule extends ResourceLoaderModule {
                        return $this->modifiedTime[$context->getHash()] = 1;
                }
 
-               wfProfileIn( __METHOD__.'-filemtime' );
+               wfProfileIn( __METHOD__ . '-filemtime' );
                $filesMtime = max( array_map( array( __CLASS__, 'safeFilemtime' ), $files ) );
-               wfProfileOut( __METHOD__.'-filemtime' );
+               wfProfileOut( __METHOD__ . '-filemtime' );
                $this->modifiedTime[$context->getHash()] = max(
                        $filesMtime,
                        $this->getMsgBlobMtime( $context->getLanguage() ) );
@@ -571,7 +571,7 @@ class ResourceLoaderFileModule extends ResourceLoaderModule {
                foreach ( array_unique( $scripts ) as $fileName ) {
                        $localPath = $this->getLocalPath( $fileName );
                        if ( !file_exists( $localPath ) ) {
-                               throw new MWException( __METHOD__.": script file not found: \"$localPath\"" );
+                               throw new MWException( __METHOD__ . ": script file not found: \"$localPath\"" );
                        }
                        $contents = file_get_contents( $localPath );
                        if ( $wgResourceLoaderValidateStaticJS ) {
@@ -628,7 +628,7 @@ class ResourceLoaderFileModule extends ResourceLoaderModule {
        protected function readStyleFile( $path, $flip ) {
                $localPath = $this->getLocalPath( $path );
                if ( !file_exists( $localPath ) ) {
-                       $msg = __METHOD__.": style file not found: \"$localPath\"";
+                       $msg = __METHOD__ . ": style file not found: \"$localPath\"";
                        wfDebugLog( 'resourceloader', $msg );
                        throw new MWException( $msg );
                }
index b85da16..4ea9f4e 100644 (file)
@@ -147,7 +147,7 @@ abstract class ResourceLoaderWikiModule extends ResourceLoaderModule {
                                continue;
                        }
                        $title = Title::newFromText( $titleText );
-                       if ( !$title || $title->isRedirect()  ) {
+                       if ( !$title || $title->isRedirect() ) {
                                continue;
                        }
                        $media = isset( $options['media'] ) ? $options['media'] : 'all';
index 6ceadff..d64201c 100644 (file)
@@ -424,7 +424,7 @@ class RevDel_ArchivedRevisionItem extends RevDel_ArchiveItem {
                $dbw->update( 'archive',
                        array( 'ar_deleted' => $bits ),
                        array( 'ar_rev_id' => $this->row->ar_rev_id,
-                                  'ar_deleted' => $this->getBits()
+                               'ar_deleted' => $this->getBits()
                        ),
                        __METHOD__ );
                return (bool)$dbw->affectedRows();
@@ -454,7 +454,9 @@ class RevDel_FileList extends RevDel_List {
                foreach( $this->ids as $timestamp ) {
                        $archiveNames[] = $timestamp . '!' . $this->title->getDBkey();
                }
-               return $db->select( 'oldimage', '*',
+               return $db->select(
+                       'oldimage',
+                       OldLocalFile::selectFields(),
                        array(
                                'oi_name'         => $this->title->getDBkey(),
                                'oi_archive_name' => $archiveNames
@@ -695,7 +697,9 @@ class RevDel_ArchivedFileList extends RevDel_FileList {
         */
        public function doQuery( $db ) {
                $ids = array_map( 'intval', $this->ids );
-               return $db->select( 'filearchive', '*',
+               return $db->select(
+                       'filearchive',
+                       ArchivedFile::selectFields(),
                        array(
                                'fa_name' => $this->title->getDBkey(),
                                'fa_id'   => $ids
@@ -899,7 +903,7 @@ class RevDel_LogItem extends RevDel_Item {
                $action = $formatter->getActionText();
                // Comment
                $comment = $this->list->getLanguage()->getDirMark() . Linker::commentBlock( $this->row->log_comment );
-               if( LogEventsList::isDeleted($this->row,LogPage::DELETED_COMMENT) ) {
+               if( LogEventsList::isDeleted( $this->row, LogPage::DELETED_COMMENT ) ) {
                        $comment = '<span class="history-deleted">' . $comment . '</span>';
                }
 
index e10b642..5e5755c 100644 (file)
@@ -45,7 +45,7 @@ class SearchEngine {
         */
        protected $db;
 
-       function __construct($db = null) {
+       function __construct( $db = null ) {
                if ( $db ) {
                        $this->db = $db;
                } else {
@@ -1142,8 +1142,8 @@ class SearchHighlighter {
                                // add more lines
                                $add = $index + 1;
                                while ( $len < $targetchars - 20
-                                          && array_key_exists( $add, $all )
-                                          && !array_key_exists( $add, $snippets ) ) {
+                                               && array_key_exists( $add, $all )
+                                               && !array_key_exists( $add, $snippets ) ) {
                                        $offsets[$add] = 0;
                                        $tt = "\n" . $this->extract( $all[$add], 0, $targetchars - $len, $offsets[$add] );
                                        $extended[$add] = $tt;
@@ -1153,7 +1153,7 @@ class SearchHighlighter {
                        }
                }
 
-               // $snippets = array_map('htmlspecialchars', $extended);
+               // $snippets = array_map( 'htmlspecialchars', $extended );
                $snippets = $extended;
                $last = - 1;
                $extract = '';
@@ -1332,12 +1332,12 @@ class SearchHighlighter {
                $fname = __METHOD__;
                wfProfileIn( $fname );
 
-               // $text = preg_replace("/'{2,5}/", "", $text);
-               // $text = preg_replace("/\[[a-z]+:\/\/[^ ]+ ([^]]+)\]/", "\\2", $text);
-               // $text = preg_replace("/\[\[([^]|]+)\]\]/", "\\1", $text);
-               // $text = preg_replace("/\[\[([^]]+\|)?([^|]]+)\]\]/", "\\2", $text);
-               // $text = preg_replace("/\\{\\|(.*?)\\|\\}/", "", $text);
-               // $text = preg_replace("/\\[\\[[A-Za-z_-]+:([^|]+?)\\]\\]/", "", $text);
+               // $text = preg_replace( "/'{2,5}/", "", $text );
+               // $text = preg_replace( "/\[[a-z]+:\/\/[^ ]+ ([^]]+)\]/", "\\2", $text );
+               // $text = preg_replace( "/\[\[([^]|]+)\]\]/", "\\1", $text );
+               // $text = preg_replace( "/\[\[([^]]+\|)?([^|]]+)\]\]/", "\\2", $text );
+               // $text = preg_replace( "/\\{\\|(.*?)\\|\\}/", "", $text );
+               // $text = preg_replace( "/\\[\\[[A-Za-z_-]+:([^|]+?)\\]\\]/", "", $text );
                $text = preg_replace( "/\\{\\{([^|]+?)\\}\\}/", "", $text );
                $text = preg_replace( "/\\{\\{([^|]+\\|)(.*?)\\}\\}/", "\\2", $text );
                $text = preg_replace( "/\\[\\[([^|]+?)\\]\\]/", "\\1", $text );
index 368d900..ebc9d5a 100644 (file)
@@ -34,7 +34,7 @@ class SearchIBM_DB2 extends SearchEngine {
         * Creates an instance of this class
         * @param $db DatabaseIbm_db2: database object
         */
-       function __construct($db) {
+       function __construct( $db ) {
                parent::__construct( $db );
        }
 
@@ -45,8 +45,8 @@ class SearchIBM_DB2 extends SearchEngine {
         * @return SqlSearchResultSet
         */
        function searchText( $term ) {
-               $resultSet = $this->db->resultObject($this->db->query($this->getQuery($this->filter($term), true)));
-               return new SqlSearchResultSet($resultSet, $this->searchTerms);
+               $resultSet = $this->db->resultObject( $this->db->query( $this->getQuery( $this->filter( $term ), true ) ) );
+               return new SqlSearchResultSet( $resultSet, $this->searchTerms );
        }
 
        /**
@@ -55,9 +55,9 @@ class SearchIBM_DB2 extends SearchEngine {
         * @param $term String: taw search term
         * @return SqlSearchResultSet
         */
-       function searchTitle($term) {
-               $resultSet = $this->db->resultObject($this->db->query($this->getQuery($this->filter($term), false)));
-               return new SqlSearchResultSet($resultSet, $this->searchTerms);
+       function searchTitle( $term ) {
+               $resultSet = $this->db->resultObject( $this->db->query( $this->getQuery( $this->filter( $term ), false ) ) );
+               return new SqlSearchResultSet( $resultSet, $this->searchTerms );
        }
 
 
@@ -66,7 +66,7 @@ class SearchIBM_DB2 extends SearchEngine {
         * @return String
         */
        function queryRedirect() {
-               if ($this->showRedirects) {
+               if ( $this->showRedirects ) {
                        return '';
                } else {
                        return 'AND page_is_redirect=0';
@@ -78,10 +78,10 @@ class SearchIBM_DB2 extends SearchEngine {
         * @return String
         */
        function queryNamespaces() {
-               if( is_null($this->namespaces) )
+               if( is_null( $this->namespaces ) )
                        return '';
-               $namespaces = implode(',', $this->namespaces);
-               if ($namespaces == '') {
+               $namespaces = implode( ',', $this->namespaces );
+               if ( $namespaces == '' ) {
                        $namespaces = '0';
                }
                return 'AND page_namespace IN (' . $namespaces . ')';
@@ -92,7 +92,7 @@ class SearchIBM_DB2 extends SearchEngine {
         * @return String
         */
        function queryLimit( $sql ) {
-               return $this->db->limitResult($sql, $this->limit, $this->offset);
+               return $this->db->limitResult( $sql, $this->limit, $this->offset );
        }
 
        /**
@@ -100,7 +100,7 @@ class SearchIBM_DB2 extends SearchEngine {
         * subclasses may define this though
         * @return String
         */
-       function queryRanking($filteredTerm, $fulltext) {
+       function queryRanking( $filteredTerm, $fulltext ) {
                // requires Net Search Extender or equivalent
                // return ' ORDER BY score(1)';
                return '';
@@ -114,10 +114,10 @@ class SearchIBM_DB2 extends SearchEngine {
         * @return String
         */
        function getQuery( $filteredTerm, $fulltext ) {
-               return $this->queryLimit($this->queryMain($filteredTerm, $fulltext) . ' ' .
+               return $this->queryLimit( $this->queryMain( $filteredTerm, $fulltext ) . ' ' .
                        $this->queryRedirect() . ' ' .
                        $this->queryNamespaces() . ' ' .
-                       $this->queryRanking( $filteredTerm, $fulltext ) . ' ');
+                       $this->queryRanking( $filteredTerm, $fulltext ) . ' ' );
        }
 
 
@@ -126,7 +126,7 @@ class SearchIBM_DB2 extends SearchEngine {
         * @param $fulltext Boolean
         * @return String
         */
-       function getIndexField($fulltext) {
+       function getIndexField( $fulltext ) {
                return $fulltext ? 'si_text' : 'si_title';
        }
 
@@ -138,9 +138,9 @@ class SearchIBM_DB2 extends SearchEngine {
         * @return String
         */
        function queryMain( $filteredTerm, $fulltext ) {
-               $match = $this->parseQuery($filteredTerm, $fulltext);
-               $page        = $this->db->tableName('page');
-               $searchindex = $this->db->tableName('searchindex');
+               $match = $this->parseQuery( $filteredTerm, $fulltext );
+               $page = $this->db->tableName( 'page' );
+               $searchindex = $this->db->tableName( 'searchindex' );
                return 'SELECT page_id, page_namespace, page_title ' .
                        "FROM $page,$searchindex " .
                        'WHERE page_id=si_page AND ' . $match;
@@ -149,7 +149,7 @@ class SearchIBM_DB2 extends SearchEngine {
        /** @todo document
         * @return string
         */
-       function parseQuery($filteredText, $fulltext) {
+       function parseQuery( $filteredText, $fulltext ) {
                global $wgContLang;
                $lc = SearchEngine::legalSearchChars();
                $this->searchTerms = array();
@@ -158,9 +158,9 @@ class SearchIBM_DB2 extends SearchEngine {
                $m = array();
                $q = array();
 
-               if (preg_match_all('/([-+<>~]?)(([' . $lc . ']+)(\*?)|"[^"]*")/',
-                         $filteredText, $m, PREG_SET_ORDER)) {
-                       foreach($m as $terms) {
+               if ( preg_match_all( '/([-+<>~]?)(([' . $lc . ']+)(\*?)|"[^"]*")/',
+                               $filteredText, $m, PREG_SET_ORDER ) ) {
+                       foreach( $m as $terms ) {
 
                                // Search terms in all variant forms, only
                                // apply on wiki with LanguageConverter
@@ -173,19 +173,19 @@ class SearchIBM_DB2 extends SearchEngine {
                                else
                                        $q[] = $terms[1] . $wgContLang->normalizeForSearch( $terms[2] );
 
-                               if (!empty($terms[3])) {
+                               if ( !empty( $terms[3] ) ) {
                                        $regexp = preg_quote( $terms[3], '/' );
-                                       if ($terms[4])
+                                       if ( $terms[4] )
                                                $regexp .= "[0-9A-Za-z_]+";
                                } else {
-                                       $regexp = preg_quote(str_replace('"', '', $terms[2]), '/');
+                                       $regexp = preg_quote(str_replace( '"', '', $terms[2]), '/' );
                                }
                                $this->searchTerms[] = $regexp;
                        }
                }
 
-               $searchon = $this->db->strencode(join(',', $q));
-               $field = $this->getIndexField($fulltext);
+               $searchon = $this->db->strencode( join( ',', $q ) );
+               $field = $this->getIndexField( $fulltext );
 
                // requires Net Search Extender or equivalent
                //return " CONTAINS($field, '$searchon') > 0 ";
@@ -201,18 +201,18 @@ class SearchIBM_DB2 extends SearchEngine {
         * @param $title String
         * @param $text String
         */
-       function update($id, $title, $text) {
-               $dbw = wfGetDB(DB_MASTER);
-               $dbw->replace('searchindex',
-                       array('si_page'),
+       function update( $id, $title, $text ) {
+               $dbw = wfGetDB( DB_MASTER );
+               $dbw->replace( 'searchindex',
+                       array( 'si_page' ),
                        array(
                                'si_page' => $id,
                                'si_title' => $title,
                                'si_text' => $text
                        ), 'SearchIBM_DB2::update' );
                // ?
-               //$dbw->query("CALL ctx_ddl.sync_index('si_text_idx')");
-               //$dbw->query("CALL ctx_ddl.sync_index('si_title_idx')");
+               //$dbw->query( "CALL ctx_ddl.sync_index('si_text_idx')" );
+               //$dbw->query( "CALL ctx_ddl.sync_index('si_title_idx')" );
        }
 
        /**
@@ -222,13 +222,13 @@ class SearchIBM_DB2 extends SearchEngine {
         * @param $id Integer
         * @param $title String
         */
-       function updateTitle($id, $title) {
-               $dbw = wfGetDB(DB_MASTER);
+       function updateTitle( $id, $title ) {
+               $dbw = wfGetDB( DB_MASTER );
 
-               $dbw->update('searchindex',
-                       array('si_title' => $title),
-                       array('si_page'  => $id),
+               $dbw->update( 'searchindex',
+                       array( 'si_title' => $title ),
+                       array( 'si_page'  => $id ),
                        'SearchIBM_DB2::updateTitle',
-                       array());
+                       array() );
        }
 }
index 23dd479..85fe148 100644 (file)
@@ -253,5 +253,3 @@ class MssqlSearchResultSet extends SearchResultSet {
                return new SearchResult( $row );
        }
 }
-
-
index 5cee03e..a76662b 100644 (file)
@@ -58,7 +58,7 @@ class SearchMySQL extends SearchEngine {
                # @todo FIXME: This doesn't handle parenthetical expressions.
                $m = array();
                if( preg_match_all( '/([-+<>~]?)(([' . $lc . ']+)(\*?)|"[^"]*")/',
-                         $filteredText, $m, PREG_SET_ORDER ) ) {
+                               $filteredText, $m, PREG_SET_ORDER ) ) {
                        foreach( $m as $bits ) {
                                @list( /* all */, $modifier, $term, $nonQuoted, $wildcard ) = $bits;
 
@@ -221,7 +221,7 @@ class SearchMySQL extends SearchEngine {
         */
        protected function queryFeatures( &$query ) {
                foreach ( $this->features as $feature => $value ) {
-                       if ( $feature ===  'list-redirects' && !$value ) {
+                       if ( $feature === 'list-redirects' && !$value ) {
                                $query['conds']['page_is_redirect'] = 0;
                        } elseif( $feature === 'title-suffix-filter' && $value ) {
                                $query['conds'][] = 'page_title' . $this->db->buildLike( $this->db->anyString(), $value );
index 29070e1..009502b 100644 (file)
@@ -61,7 +61,7 @@ class SearchOracle extends SearchEngine {
         * Creates an instance of this class
         * @param $db DatabasePostgres: database object
         */
-       function __construct($db) {
+       function __construct( $db ) {
                parent::__construct( $db );
        }
 
@@ -72,11 +72,11 @@ class SearchOracle extends SearchEngine {
         * @return SqlSearchResultSet
         */
        function searchText( $term ) {
-               if ($term == '')
-                       return new SqlSearchResultSet(false, '');
+               if ( $term == '' )
+                       return new SqlSearchResultSet( false, '' );
 
-               $resultSet = $this->db->resultObject($this->db->query($this->getQuery($this->filter($term), true)));
-               return new SqlSearchResultSet($resultSet, $this->searchTerms);
+               $resultSet = $this->db->resultObject( $this->db->query( $this->getQuery( $this->filter( $term ), true ) ) );
+               return new SqlSearchResultSet( $resultSet, $this->searchTerms );
        }
 
        /**
@@ -85,12 +85,12 @@ class SearchOracle extends SearchEngine {
         * @param $term String: raw search term
         * @return SqlSearchResultSet
         */
-       function searchTitle($term) {
-               if ($term == '')
-                       return new SqlSearchResultSet(false, '');
+       function searchTitle( $term ) {
+               if ( $term == '' )
+                       return new SqlSearchResultSet( false, '' );
 
-               $resultSet = $this->db->resultObject($this->db->query($this->getQuery($this->filter($term), false)));
-               return new MySQLSearchResultSet($resultSet, $this->searchTerms);
+               $resultSet = $this->db->resultObject( $this->db->query( $this->getQuery( $this->filter( $term ), false ) ) );
+               return new MySQLSearchResultSet( $resultSet, $this->searchTerms );
        }
 
 
@@ -99,7 +99,7 @@ class SearchOracle extends SearchEngine {
         * @return String
         */
        function queryRedirect() {
-               if ($this->showRedirects) {
+               if ( $this->showRedirects ) {
                        return '';
                } else {
                        return 'AND page_is_redirect=0';
@@ -111,7 +111,7 @@ class SearchOracle extends SearchEngine {
         * @return String
         */
        function queryNamespaces() {
-               if( is_null($this->namespaces) )
+               if( is_null( $this->namespaces ) )
                        return '';
                if ( !count( $this->namespaces ) ) {
                        $namespaces = '0';
@@ -129,7 +129,7 @@ class SearchOracle extends SearchEngine {
         * @return String
         */
        function queryLimit( $sql ) {
-               return $this->db->limitResult($sql, $this->limit, $this->offset);
+               return $this->db->limitResult( $sql, $this->limit, $this->offset );
        }
 
        /**
@@ -150,10 +150,10 @@ class SearchOracle extends SearchEngine {
         * @return String
         */
        function getQuery( $filteredTerm, $fulltext ) {
-               return $this->queryLimit($this->queryMain($filteredTerm, $fulltext) . ' ' .
+               return $this->queryLimit( $this->queryMain( $filteredTerm, $fulltext ) . ' ' .
                        $this->queryRedirect() . ' ' .
                        $this->queryNamespaces() . ' ' .
-                       $this->queryRanking( $filteredTerm, $fulltext ) . ' ');
+                       $this->queryRanking( $filteredTerm, $fulltext ) . ' ' );
        }
 
 
@@ -162,7 +162,7 @@ class SearchOracle extends SearchEngine {
         * @param $fulltext Boolean
         * @return String
         */
-       function getIndexField($fulltext) {
+       function getIndexField( $fulltext ) {
                return $fulltext ? 'si_text' : 'si_title';
        }
 
@@ -174,9 +174,9 @@ class SearchOracle extends SearchEngine {
         * @return String
         */
        function queryMain( $filteredTerm, $fulltext ) {
-               $match = $this->parseQuery($filteredTerm, $fulltext);
-               $page        = $this->db->tableName('page');
-               $searchindex = $this->db->tableName('searchindex');
+               $match = $this->parseQuery( $filteredTerm, $fulltext );
+               $page = $this->db->tableName( 'page' );
+               $searchindex = $this->db->tableName( 'searchindex' );
                return 'SELECT page_id, page_namespace, page_title ' .
                        "FROM $page,$searchindex " .
                        'WHERE page_id=si_page AND ' . $match;
@@ -187,7 +187,7 @@ class SearchOracle extends SearchEngine {
         * as part of a WHERE clause
         * @return string
         */
-       function parseQuery($filteredText, $fulltext) {
+       function parseQuery( $filteredText, $fulltext ) {
                global $wgContLang;
                $lc = SearchEngine::legalSearchChars();
                $this->searchTerms = array();
@@ -195,9 +195,9 @@ class SearchOracle extends SearchEngine {
                # @todo FIXME: This doesn't handle parenthetical expressions.
                $m = array();
                $searchon = '';
-               if (preg_match_all('/([-+<>~]?)(([' . $lc . ']+)(\*?)|"[^"]*")/',
-                         $filteredText, $m, PREG_SET_ORDER)) {
-                       foreach($m as $terms) {
+               if ( preg_match_all( '/([-+<>~]?)(([' . $lc . ']+)(\*?)|"[^"]*")/',
+                               $filteredText, $m, PREG_SET_ORDER ) ) {
+                       foreach( $m as $terms ) {
                                // Search terms in all variant forms, only
                                // apply on wiki with LanguageConverter
                                $temp_terms = $wgContLang->autoConvertToAllVariants( $terms[2] );
@@ -210,27 +210,27 @@ class SearchOracle extends SearchEngine {
                                else {
                                        $searchon .= ($terms[1] == '-' ? ' ~' : ' & ') . $this->escapeTerm( $terms[2] );
                                }
-                               if (!empty($terms[3])) {
+                               if ( !empty( $terms[3] ) ) {
                                        $regexp = preg_quote( $terms[3], '/' );
-                                       if ($terms[4])
+                                       if ( $terms[4] )
                                                $regexp .= "[0-9A-Za-z_]+";
                                } else {
-                                       $regexp = preg_quote(str_replace('"', '', $terms[2]), '/');
+                                       $regexp = preg_quote( str_replace( '"', '', $terms[2] ), '/' );
                                }
                                $this->searchTerms[] = $regexp;
                        }
                }
 
 
-               $searchon = $this->db->addQuotes(ltrim($searchon, ' &'));
-               $field = $this->getIndexField($fulltext);
+               $searchon = $this->db->addQuotes( ltrim( $searchon, ' &' ) );
+               $field = $this->getIndexField( $fulltext );
                return " CONTAINS($field, $searchon, 1) > 0 ";
        }
 
-       private function escapeTerm($t) {
+       private function escapeTerm( $t ) {
                global $wgContLang;
-               $t = $wgContLang->normalizeForSearch($t);
-               $t = isset($this->reservedWords[strtoupper($t)]) ? '{'.$t.'}' : $t;
+               $t = $wgContLang->normalizeForSearch( $t );
+               $t = isset( $this->reservedWords[strtoupper( $t )] ) ? '{'.$t.'}' : $t;
                $t = preg_replace('/^"(.*)"$/', '($1)', $t);
                $t = preg_replace('/([-&|])/', '\\\\$1', $t);
                return $t;
@@ -243,10 +243,10 @@ class SearchOracle extends SearchEngine {
         * @param $title String
         * @param $text String
         */
-       function update($id, $title, $text) {
-               $dbw = wfGetDB(DB_MASTER);
-               $dbw->replace('searchindex',
-                       array('si_page'),
+       function update( $id, $title, $text ) {
+               $dbw = wfGetDB( DB_MASTER );
+               $dbw->replace( 'searchindex',
+                       array( 'si_page' ),
                        array(
                                'si_page' => $id,
                                'si_title' => $title,
@@ -271,14 +271,14 @@ class SearchOracle extends SearchEngine {
         * @param $id Integer
         * @param $title String
         */
-       function updateTitle($id, $title) {
-               $dbw = wfGetDB(DB_MASTER);
+       function updateTitle( $id, $title ) {
+               $dbw = wfGetDB( DB_MASTER );
 
-               $dbw->update('searchindex',
-                       array('si_title' => $title),
-                       array('si_page'  => $id),
+               $dbw->update( 'searchindex',
+                       array( 'si_title' => $title ),
+                       array( 'si_page'  => $id ),
                        'SearchOracle::updateTitle',
-                       array());
+                       array() );
        }
 
 
index 9c89c3d..727cc16 100644 (file)
@@ -66,8 +66,8 @@ class SearchPostgres extends SearchEngine {
                $q = $this->searchQuery( $term, 'textvector', 'old_text' );
                $olderror = error_reporting(E_ERROR);
                $resultSet = $this->db->resultObject( $this->db->query( $q, 'SearchPostgres', true ) );
-               error_reporting($olderror);
-               if (!$resultSet) {
+               error_reporting( $olderror );
+               if ( !$resultSet ) {
                        return new SearchResultTooMany();
                }
                return new PostgresSearchResultSet( $resultSet, $this->searchTerms );
@@ -99,16 +99,16 @@ class SearchPostgres extends SearchEngine {
                $m = array();
                if( preg_match_all('/([-!]?)(\S+)\s*/', $term, $m, PREG_SET_ORDER ) ) {
                        foreach( $m as $terms ) {
-                               if (strlen($terms[1])) {
+                               if ( strlen( $terms[1] ) ) {
                                        $searchstring .= ' & !';
                                }
-                               if (strtolower($terms[2]) === 'and') {
+                               if ( strtolower( $terms[2] ) === 'and' ) {
                                        $searchstring .= ' & ';
                                }
-                               elseif (strtolower($terms[2]) === 'or' or $terms[2] === '|') {
+                               elseif ( strtolower( $terms[2] ) === 'or' or $terms[2] === '|' ) {
                                        $searchstring .= ' | ';
                                }
-                               elseif (strtolower($terms[2]) === 'not') {
+                               elseif ( strtolower( $terms[2] ) === 'not' ) {
                                        $searchstring .= ' & !';
                                }
                                else {
@@ -133,7 +133,7 @@ class SearchPostgres extends SearchEngine {
                $searchstring = preg_replace('/^[\'"](.*)[\'"]$/', "$1", $searchstring);
 
                ## Quote the whole thing
-               $searchstring = $this->db->addQuotes($searchstring);
+               $searchstring = $this->db->addQuotes( $searchstring );
 
                wfDebug( "parseQuery returned: $searchstring \n" );
 
@@ -154,15 +154,15 @@ class SearchPostgres extends SearchEngine {
 
                ## We need a separate query here so gin does not complain about empty searches
                $SQL = "SELECT to_tsquery($searchstring)";
-               $res = $this->db->query($SQL);
-               if (!$res) {
+               $res = $this->db->query( $SQL );
+               if ( !$res ) {
                        ## TODO: Better output (example to catch: one 'two)
-                       die ("Sorry, that was not a valid search string. Please go back and try again");
+                       die( "Sorry, that was not a valid search string. Please go back and try again" );
                }
                $top = $res->fetchRow();
                $top = $top[0];
 
-               if ($top === "") { ## e.g. if only stopwords are used XXX return something better
+               if ( $top === "" ) { ## e.g. if only stopwords are used XXX return something better
                        $query = "SELECT page_id, page_namespace, page_title, 0 AS score ".
                                "FROM page p, revision r, pagecontent c WHERE p.page_latest = r.rev_id " .
                                "AND r.rev_text_id = c.old_id AND 1=0";
@@ -182,7 +182,7 @@ class SearchPostgres extends SearchEngine {
                }
 
                ## Redirects
-               if (! $this->showRedirects)
+               if ( !$this->showRedirects )
                        $query .= ' AND page_is_redirect = 0';
 
                ## Namespaces - defaults to 0
@@ -226,7 +226,7 @@ class SearchPostgres extends SearchEngine {
  */
 class PostgresSearchResult extends SearchResult {
        function __construct( $row ) {
-               parent::__construct($row);
+               parent::__construct( $row );
                $this->score = $row->score;
        }
        function getScore() {
index e52e4fe..f91399a 100644 (file)
@@ -62,7 +62,7 @@ class SearchSqlite extends SearchEngine {
 
                $m = array();
                if( preg_match_all( '/([-+<>~]?)(([' . $lc . ']+)(\*?)|"[^"]*")/',
-                         $filteredText, $m, PREG_SET_ORDER ) ) {
+                               $filteredText, $m, PREG_SET_ORDER ) ) {
                        foreach( $m as $bits ) {
                                @list( /* all */, $modifier, $term, $nonQuoted, $wildcard ) = $bits;
 
@@ -214,7 +214,7 @@ class SearchSqlite extends SearchEngine {
         * @return String
         */
        function queryNamespaces() {
-               if( is_null($this->namespaces) )
+               if( is_null( $this->namespaces ) )
                        return '';  # search all
                if ( !count( $this->namespaces ) ) {
                        $namespaces = '0';
@@ -266,7 +266,7 @@ class SearchSqlite extends SearchEngine {
         */
        function queryMain( $filteredTerm, $fulltext ) {
                $match = $this->parseQuery( $filteredTerm, $fulltext );
-               $page        = $this->db->tableName( 'page' );
+               $page = $this->db->tableName( 'page' );
                $searchindex = $this->db->tableName( 'searchindex' );
                return "SELECT $searchindex.rowid, page_namespace, page_title " .
                        "FROM $page,$searchindex " .
@@ -317,7 +317,7 @@ class SearchSqlite extends SearchEngine {
         * @param $id Integer
         * @param $title String
         */
-    function updateTitle( $id, $title ) {
+       function updateTitle( $id, $title ) {
                if ( !$this->fulltextSearchSupported() ) {
                        return;
                }
index 389c317..eabcda3 100644 (file)
@@ -79,7 +79,7 @@ class SearchUpdate implements DeferrableUpdate {
                $text = preg_replace( "/<\\/?\\s*[A-Za-z][^>]*?>/",
                        ' ', $wgContLang->lc( " " . $text . " " ) ); # Strip HTML markup
                $text = preg_replace( "/(^|\\n)==\\s*([^\\n]+)\\s*==(\\s)/sD",
-                 "\\1\\2 \\2 \\2\\3", $text ); # Emphasize headings
+                       "\\1\\2 \\2 \\2\\3", $text ); # Emphasize headings
 
                # Strip external URLs
                $uc = "A-Za-z0-9_\\/:.,~%\\-+&;#?!=()@\\x80-\\xFF";
@@ -97,7 +97,7 @@ class SearchUpdate implements DeferrableUpdate {
                $text = preg_replace( $pat2, " \\1 \\3", $text );
 
                $text = preg_replace( "/([^{$lc}])([{$lc}]+)]]([a-z]+)/",
-                 "\\1\\2 \\2\\3", $text ); # Handle [[game]]s
+                       "\\1\\2 \\2\\3", $text ); # Handle [[game]]s
 
                # Strip all remaining non-search characters
                $text = preg_replace( "/[^{$lc}]+/", " ", $text );
@@ -127,7 +127,7 @@ class SearchUpdate implements DeferrableUpdate {
                wfRunHooks( 'SearchUpdate', array( $this->mId, $this->mNamespace, $this->mTitle, &$text ) );
 
                # Perform the actual update
-               $search->update($this->mId, $search->normalizeText( Title::indexTitle( $this->mNamespace, $this->mTitle ) ),
+               $search->update( $this->mId, $search->normalizeText( Title::indexTitle( $this->mNamespace, $this->mTitle ) ),
                                $search->normalizeText( $text ) );
 
                wfProfileOut( __METHOD__ );
index d4613aa..68161b9 100644 (file)
@@ -323,7 +323,7 @@ class MediaWikiSite extends Site {
 
                if ( $pageName !== false ) {
                        $pageName = $this->toDBKey( trim( $pageName ) );
-                       $url = str_replace( '$1', wfUrlencode( $pageName ), $url ) ;
+                       $url = str_replace( '$1', wfUrlencode( $pageName ), $url );
                }
 
                return $url;
index 5394860..525c375 100644 (file)
@@ -378,7 +378,7 @@ class Site implements Serializable {
                }
 
                if ( $pageName !== false ) {
-                       $url = str_replace( '$1', rawurlencode( $pageName ), $url ) ;
+                       $url = str_replace( '$1', rawurlencode( $pageName ), $url );
                }
 
                return $url;
index 97848b5..b0d1f95 100644 (file)
@@ -240,7 +240,7 @@ class SiteList extends GenericArrayObject {
         * @var string A string uniquely identifying the version of the serialization structure,
         *             not including any sub-structures.
         */
-       const SERIAL_VERSION_ID = '2013-01-23';
+       const SERIAL_VERSION_ID = '2013-02-07';
 
        /**
         * Returns the version ID that identifies the serialization structure used by
@@ -297,4 +297,4 @@ class SiteList extends GenericArrayObject {
 /**
  * @deprecated
  */
-class SiteArray extends SiteList {}
\ No newline at end of file
+class SiteArray extends SiteList {}
index a79c8c5..4123805 100644 (file)
@@ -47,6 +47,11 @@ class SiteSQLStore implements SiteStore {
         */
        private $cacheKey = null;
 
+       /**
+        * @var int
+        */
+       private $cacheTimeout = 3600;
+
        /**
         * @since 1.21
         *
@@ -218,7 +223,7 @@ class SiteSQLStore implements SiteStore {
                }
 
                $cache = wfGetMainCache();
-               $cache->set( $this->getCacheKey(), $this->sites );
+               $cache->set( $this->getCacheKey(), $this->sites, $this->cacheTimeout );
 
                wfProfileOut( __METHOD__ );
        }
@@ -466,7 +471,13 @@ class Sites extends SiteSQLStore {
         * @return SiteStore
         */
        public static function singleton() {
-               return new static();
+               static $singleton;
+
+               if ( $singleton === null ) {
+                       $singleton = new static();
+               }
+
+               return $singleton;
        }
 
        /**
index abfb719..eeda739 100644 (file)
@@ -180,7 +180,7 @@ class SpecialAllpages extends IncludableSpecialPage {
                $where = array( 'page_namespace' => $namespace );
 
                if ( $hideredirects ) {
-                       $where[ 'page_is_redirect' ] = 0;
+                       $where['page_is_redirect'] = 0;
                }
 
                $from = Title::makeTitleSafe( $namespace, $from );
@@ -188,13 +188,13 @@ class SpecialAllpages extends IncludableSpecialPage {
                $from = ( $from && $from->isLocal() ) ? $from->getDBkey() : null;
                $to = ( $to && $to->isLocal() ) ? $to->getDBkey() : null;
 
-               if( isset($from) )
-                       $where[] = 'page_title >= '.$dbr->addQuotes( $from );
-               if( isset($to) )
-                       $where[] = 'page_title <= '.$dbr->addQuotes( $to );
+               if( isset( $from ) )
+                       $where[] = 'page_title >= ' . $dbr->addQuotes( $from );
+               if( isset( $to ) )
+                       $where[] = 'page_title <= ' . $dbr->addQuotes( $to );
 
                global $wgMemc;
-               $key = wfMemcKey( 'allpages', 'ns', $namespace, $from, $to );
+               $key = wfMemcKey( 'allpages', 'ns', $namespace, sha1( $from ), sha1( $to ) );
                $lines = $wgMemc->get( $key );
 
                $count = $dbr->estimateRowCount( 'page', '*', $where, __METHOD__ );
@@ -217,9 +217,9 @@ class SpecialAllpages extends IncludableSpecialPage {
                                        : array( 'page_title >= ' . $dbr->addQuotes( $lastTitle ) );
                                $res = $dbr->select( 'page', /* FROM */
                                        'page_title', /* WHAT */
-                                       array_merge($where,$chunk),
+                                       array_merge( $where, $chunk ),
                                        __METHOD__,
-                                       array ('LIMIT' => 2, 'OFFSET' => $maxPerSubpage - 1, 'ORDER BY' => 'page_title ASC')
+                                       array( 'LIMIT' => 2, 'OFFSET' => $maxPerSubpage - 1, 'ORDER BY' => 'page_title ASC' )
                                );
 
                                $s = $dbr->fetchObject( $res );
@@ -228,7 +228,7 @@ class SpecialAllpages extends IncludableSpecialPage {
                                } else {
                                        // Final chunk, but ended prematurely. Go back and find the end.
                                        $endTitle = $dbr->selectField( 'page', 'MAX(page_title)',
-                                               array_merge($where,$chunk),
+                                               array_merge( $where, $chunk ),
                                                __METHOD__ );
                                        array_push( $lines, $endTitle );
                                        $done = true;
@@ -250,7 +250,7 @@ class SpecialAllpages extends IncludableSpecialPage {
                // If there are only two or less sections, don't even display them.
                // Instead, display the first section directly.
                if( count( $lines ) <= 2 ) {
-                       if( !empty($lines) ) {
+                       if( !empty( $lines ) ) {
                                $this->showChunk( $namespace, $from, $to, $hideredirects );
                        } else {
                                $output->addHTML( $this->namespaceForm( $namespace, $from, $to, $hideredirects ) );
@@ -272,7 +272,7 @@ class SpecialAllpages extends IncludableSpecialPage {
                if( $this->including() ) {
                        $out2 = '';
                } else {
-                       if( isset($from) || isset($to) ) {
+                       if( isset( $from ) || isset( $to ) ) {
                                $out2 = Xml::openElement( 'table', array( 'class' => 'mw-allpages-table-form' ) ).
                                                '<tr>
                                                        <td>' .
@@ -311,12 +311,12 @@ class SpecialAllpages extends IncludableSpecialPage {
                $queryparams = $namespace ? "namespace=$namespace&" : '';
 
                $queryhideredirects = array();
-               if ($hideredirects) {
-                       $queryhideredirects[ 'hideredirects' ] = 1;
+               if ( $hideredirects ) {
+                       $queryhideredirects['hideredirects'] = 1;
                }
 
                $special = $this->getTitle();
-               $link = htmlspecialchars( $special->getLocalUrl( $queryparams . 'from=' . urlencode($inpoint) . '&to=' . urlencode($outpoint), $queryhideredirects ) );
+               $link = htmlspecialchars( $special->getLocalUrl( $queryparams . 'from=' . urlencode( $inpoint ) . '&to=' . urlencode( $outpoint ), $queryhideredirects ) );
 
                $out = $this->msg( 'alphaindexline' )->rawParams(
                        "<a href=\"$link\">$inpointf</a></td><td>",
@@ -335,7 +335,7 @@ class SpecialAllpages extends IncludableSpecialPage {
                global $wgContLang;
                $output = $this->getOutput();
 
-               $fromList = $this->getNamespaceKeyAndText($namespace, $from);
+               $fromList = $this->getNamespaceKeyAndText( $namespace, $from );
                $toList = $this->getNamespaceKeyAndText( $namespace, $to );
                $namespaces = $wgContLang->getNamespaces();
                $n = 0;
@@ -357,7 +357,7 @@ class SpecialAllpages extends IncludableSpecialPage {
                        );
 
                        if ( $hideredirects ) {
-                               $conds[ 'page_is_redirect' ] = 0;
+                               $conds['page_is_redirect'] = 0;
                        }
 
                        if( $toKey !== "" ) {
@@ -416,10 +416,10 @@ class SpecialAllpages extends IncludableSpecialPage {
                                $res_prev = $dbr->select(
                                        'page',
                                        'page_title',
-                                       array( 'page_namespace' => $namespace, 'page_title < '.$dbr->addQuotes($from) ),
+                                       array( 'page_namespace' => $namespace, 'page_title < ' . $dbr->addQuotes( $from ) ),
                                        __METHOD__,
                                        array( 'ORDER BY' => 'page_title DESC',
-                                               'LIMIT' => $this->maxPerPage, 'OFFSET' => ($this->maxPerPage - 1 )
+                                               'LIMIT' => $this->maxPerPage, 'OFFSET' => ( $this->maxPerPage - 1 )
                                        )
                                );
 
@@ -438,7 +438,7 @@ class SpecialAllpages extends IncludableSpecialPage {
                                                array( 'page_namespace' => $namespace ), __METHOD__, $options );
                                        # Show the previous link if it s not the current requested chunk
                                        if( $from != $reallyFirstPage_title ) {
-                                               $prevTitle =  Title::makeTitle( $namespace, $reallyFirstPage_title );
+                                               $prevTitle = Title::makeTitle( $namespace, $reallyFirstPage_title );
                                        } else {
                                                $prevTitle = null;
                                        }
@@ -477,7 +477,7 @@ class SpecialAllpages extends IncludableSpecialPage {
 
                        if( $n == $this->maxPerPage && $s = $res->fetchObject() ) {
                                # $s is the first link of the next chunk
-                               $t = Title::makeTitle($namespace, $s->page_title);
+                               $t = Title::makeTitle( $namespace, $s->page_title );
                                $query = array( 'from' => $t->getText() );
 
                                if( $namespace )
@@ -518,11 +518,11 @@ class SpecialAllpages extends IncludableSpecialPage {
         * @param $text String: the name of the article
         * @return array( int namespace, string dbkey, string pagename ) or NULL on error
         */
-       protected function getNamespaceKeyAndText($ns, $text) {
+       protected function getNamespaceKeyAndText( $ns, $text ) {
                if ( $text == '' )
                        return array( $ns, '', '' ); # shortcut for common case
 
-               $t = Title::makeTitleSafe($ns, $text);
+               $t = Title::makeTitleSafe( $ns, $text );
                if ( $t && $t->isLocal() ) {
                        return array( $t->getNamespace(), $t->getDBkey(), $t->getText() );
                } elseif ( $t ) {
@@ -530,8 +530,8 @@ class SpecialAllpages extends IncludableSpecialPage {
                }
 
                # try again, in case the problem was an empty pagename
-               $text = preg_replace('/(#|$)/', 'X$1', $text);
-               $t = Title::makeTitleSafe($ns, $text);
+               $text = preg_replace( '/(#|$)/', 'X$1', $text );
+               $t = Title::makeTitleSafe( $ns, $text );
                if ( $t && $t->isLocal() ) {
                        return array( $t->getNamespace(), '', '' );
                } else {
index 42d3377..bfa2f95 100644 (file)
@@ -33,6 +33,6 @@ class SpecialBlankpage extends UnlistedSpecialPage {
        }
        public function execute( $par ) {
                $this->setHeaders();
-               $this->getOutput()->addWikiMsg('intentionallyblankpage');
+               $this->getOutput()->addWikiMsg( 'intentionallyblankpage' );
        }
 }
index ec026e8..ac05f67 100644 (file)
@@ -62,7 +62,7 @@ class SpecialBlock extends FormSpecialPage {
         * @throws ErrorPageError
         */
        protected function checkExecutePermissions( User $user ) {
-                parent::checkExecutePermissions( $user );
+               parent::checkExecutePermissions( $user );
 
                # bug 15810: blocked admins should have limited access here
                $status = self::checkUnblockSelf( $this->target, $user );
@@ -134,6 +134,7 @@ class SpecialBlock extends FormSpecialPage {
                                'tabindex' => '1',
                                'id' => 'mw-bi-target',
                                'size' => '45',
+                               'autofocus' => true,
                                'required' => true,
                                'validation-callback' => array( __CLASS__, 'validateTargetField' ),
                        ),
@@ -239,7 +240,7 @@ class SpecialBlock extends FormSpecialPage {
 
                if ( $block instanceof Block && !$block->mAuto # The block exists and isn't an autoblock
                        && ( $this->type != Block::TYPE_RANGE # The block isn't a rangeblock
-                         || $block->getTarget() == $this->target ) # or if it is, the range is what we're about to block
+                               || $block->getTarget() == $this->target ) # or if it is, the range is what we're about to block
                        )
                {
                        $fields['HardBlock']['default'] = $block->isHardblock();
@@ -386,7 +387,7 @@ class SpecialBlock extends FormSpecialPage {
                        );
                }
 
-               $text =  Html::rawElement(
+               $text = Html::rawElement(
                        'p',
                        array( 'class' => 'mw-ipb-conveniencelinks' ),
                        $this->getLanguage()->pipeList( $links )
@@ -650,7 +651,7 @@ class SpecialBlock extends FormSpecialPage {
                }
 
                if ( $data['HideUser'] ) {
-                       if ( !$performer->isAllowed('hideuser') ) {
+                       if ( !$performer->isAllowed( 'hideuser' ) ) {
                                # this codepath is unreachable except by a malicious user spoofing forms,
                                # or by race conditions (user has oversight and sysop, loads block form,
                                # and is de-oversighted before submission); so need to fail completely
@@ -769,7 +770,7 @@ class SpecialBlock extends FormSpecialPage {
                        $logParams
                );
                # Relate log ID to block IDs (bug 25763)
-               $blockIds = array_merge( array( $status['id'] ), $status['autoIds']  );
+               $blockIds = array_merge( array( $status['id'] ), $status['autoIds'] );
                $log->addRelations( 'ipb_id', $blockIds, $log_id );
 
                # Report to the user
index d1afe58..56b9b00 100644 (file)
@@ -472,7 +472,7 @@ class HTMLBlockedUsersItemSelect extends HTMLSelectField {
                        // This adds the explicitly requested limit value to the drop-down,
                        // then makes sure it's sorted correctly so when we output the list
                        // later, the custom option doesn't just show up last.
-                       $this->mParams['options'][ $this->mParent->getLanguage()->formatNum( $value ) ] = intval($value);
+                       $this->mParams['options'][$this->mParent->getLanguage()->formatNum( $value )] = intval( $value );
                        asort( $this->mParams['options'] );
                }
 
index 6d27c1b..255b1b6 100644 (file)
@@ -62,7 +62,7 @@ class SpecialBookSources extends SpecialPage {
        }
 
        /**
-        * Returns whether a given ISBN (10 or 13) is valid.  True indicates validity.
+        * Returns whether a given ISBN (10 or 13) is valid. True indicates validity.
         * @param $isbn string ISBN passed for check
         * @return bool
         */
@@ -71,7 +71,7 @@ class SpecialBookSources extends SpecialPage {
                $sum = 0;
                if( strlen( $isbn ) == 13 ) {
                        for( $i = 0; $i < 12; $i++ ) {
-                               if($i % 2 == 0) {
+                               if( $i % 2 == 0 ) {
                                        $sum += $isbn[$i];
                                } else {
                                        $sum += 3 * $isbn[$i];
@@ -79,19 +79,19 @@ class SpecialBookSources extends SpecialPage {
                        }
 
                        $check = (10 - ($sum % 10)) % 10;
-                       if ($check == $isbn[12]) {
+                       if ( $check == $isbn[12] ) {
                                return true;
                        }
                } elseif( strlen( $isbn ) == 10 ) {
-                       for($i = 0; $i < 9; $i++) {
+                       for( $i = 0; $i < 9; $i++ ) {
                                $sum += $isbn[$i] * ($i + 1);
                        }
 
                        $check = $sum % 11;
-                       if($check == 10) {
+                       if( $check == 10 ) {
                                $check = "X";
                        }
-                       if($check == $isbn[9]) {
+                       if( $check == $isbn[9] ) {
                                return true;
                        }
                }
index 97de72a..77b69e8 100644 (file)
@@ -50,6 +50,7 @@ class BrokenRedirectsPage extends QueryPage {
        }
 
        function getQueryInfo() {
+               $dbr = wfGetDB( DB_SLAVE );
                return array(
                        'tables' => array(
                                'redirect',
@@ -68,7 +69,7 @@ class BrokenRedirectsPage extends QueryPage {
                                // but aren't "broken" either.
                                // Special pages and interwiki links
                                'rd_namespace >= 0',
-                               '(rd_interwiki IS NULL OR rd_interwiki = "")',
+                               'rd_interwiki IS NULL OR rd_interwiki = ' . $dbr->addQuotes( '' ),
                                'p2.page_namespace IS NULL',
                        ),
                        'join_conds' => array(
index 1232e3f..44388c4 100644 (file)
@@ -72,7 +72,7 @@ class CategoryPager extends AlphabeticPager {
        function getQueryInfo() {
                return array(
                        'tables' => array( 'category' ),
-                       'fields' => array( 'cat_title','cat_pages' ),
+                       'fields' => array( 'cat_title', 'cat_pages' ),
                        'conds' => array( 'cat_pages > 0' ),
                        'options' => array( 'USE INDEX' => 'cat_title' ),
                );
@@ -112,7 +112,7 @@ class CategoryPager extends AlphabeticPager {
                return parent::getBody();
        }
 
-       function formatRow($result) {
+       function formatRow( $result ) {
                $title = Title::makeTitle( NS_CATEGORY, $result->cat_title );
                $titleText = Linker::link( $title, htmlspecialchars( $title->getText() ) );
                $count = $this->msg( 'nmembers' )->numParams( $result->cat_pages )->escaped();
index eae8e3a..53faba7 100644 (file)
@@ -195,7 +195,7 @@ class SpecialChangeEmail extends UnlistedSpecialPage {
                        if ( $type != 'text' ) {
                                $out .= Xml::label( $this->msg( $label )->text(), $name );
                        } else {
-                               $out .=  $this->msg( $label )->escaped();
+                               $out .= $this->msg( $label )->escaped();
                        }
                        $out .= "</td>\n";
                        $out .= "\t<td class='mw-input'>";
index 54a2771..fba2bf0 100644 (file)
@@ -73,8 +73,10 @@ class SpecialChangePassword extends UnlistedSpecialPage {
                                }
 
                                $this->attemptReset( $this->mNewpass, $this->mRetype );
-                               $this->getOutput()->addWikiMsg( 'resetpass_success' );
-                               if( !$user->isLoggedIn() ) {
+
+                               if( $user->isLoggedIn() ) {
+                                       $this->doReturnTo();
+                               } else {
                                        LoginForm::setLoginToken();
                                        $token = LoginForm::getLoginToken();
                                        $data = array(
@@ -82,7 +84,7 @@ class SpecialChangePassword extends UnlistedSpecialPage {
                                                'wpName'       => $this->mUserName,
                                                'wpDomain'     => $this->mDomain,
                                                'wpLoginToken' => $token,
-                                               'wpPassword'   => $this->mNewpass,
+                                               'wpPassword'   => $request->getVal( 'wpNewPassword' ),
                                                'returnto'     => $request->getVal( 'returnto' ),
                                        );
                                        if( $request->getCheck( 'wpRemember' ) ) {
@@ -92,7 +94,7 @@ class SpecialChangePassword extends UnlistedSpecialPage {
                                        $login->setContext( $this->getContext() );
                                        $login->execute( null );
                                }
-                               $this->doReturnTo();
+                               return;
                        } catch( PasswordError $e ) {
                                $this->error( $e->getMessage() );
                        }
@@ -112,7 +114,7 @@ class SpecialChangePassword extends UnlistedSpecialPage {
         * @param $msg string
         */
        function error( $msg ) {
-               $this->getOutput()->addHTML( Xml::element('p', array( 'class' => 'error' ), $msg ) );
+               $this->getOutput()->addHTML( Xml::element( 'p', array( 'class' => 'error' ), $msg ) );
        }
 
        function showForm() {
@@ -202,7 +204,7 @@ class SpecialChangePassword extends UnlistedSpecialPage {
                        if ( $type != 'text' )
                                $out .= Xml::label( $this->msg( $label )->text(), $name );
                        else
-                               $out .=  $this->msg( $label )->escaped();
+                               $out .= $this->msg( $label )->escaped();
                        $out .= "</td>\n";
                        $out .= "\t<td class='mw-input'>";
                        $out .= $field;
@@ -216,7 +218,13 @@ class SpecialChangePassword extends UnlistedSpecialPage {
         * @throws PasswordError when cannot set the new password because requirements not met.
         */
        protected function attemptReset( $newpass, $retype ) {
-               $user = User::newFromName( $this->mUserName );
+               $isSelf = ( $this->mUserName === $this->getUser()->getName() );
+               if ( $isSelf ) {
+                       $user = $this->getUser();
+               } else {
+                       $user = User::newFromName( $this->mUserName );
+               }
+
                if( !$user || $user->isAnon() ) {
                        throw new PasswordError( $this->msg( 'nosuchusershort', $this->mUserName )->text() );
                }
@@ -231,7 +239,7 @@ class SpecialChangePassword extends UnlistedSpecialPage {
                        throw new PasswordError( $this->msg( 'login-throttled' )->text() );
                }
 
-               if( !$user->checkTemporaryPassword($this->mOldpass) && !$user->checkPassword($this->mOldpass) ) {
+               if( !$user->checkTemporaryPassword( $this->mOldpass ) && !$user->checkPassword( $this->mOldpass ) ) {
                        wfRunHooks( 'PrefsPasswordAudit', array( $user, $newpass, 'wrongpassword' ) );
                        throw new PasswordError( $this->msg( 'resetpass-wrong-oldpass' )->text() );
                }
@@ -250,7 +258,12 @@ class SpecialChangePassword extends UnlistedSpecialPage {
                        throw new PasswordError( $e->getMessage() );
                }
 
-               $user->setCookies();
+               if ( $isSelf ) {
+                       // This is needed to keep the user connected since
+                       // changing the password also modifies the user's token.
+                       $user->setCookies();
+               }
+
                $user->saveSettings();
        }
 }
index 54ec07d..d156d20 100644 (file)
@@ -360,7 +360,7 @@ class SpecialContributions extends SpecialPage {
                if ( !isset( $this->opts['target'] ) ) {
                        $this->opts['target'] = '';
                } else {
-                       $this->opts['target'] = str_replace( '_' , ' ' , $this->opts['target'] );
+                       $this->opts['target'] = str_replace( '_', ' ', $this->opts['target'] );
                }
 
                if ( !isset( $this->opts['namespace'] ) ) {
@@ -424,7 +424,7 @@ class SpecialContributions extends SpecialPage {
                        Xml::radioLabel(
                                $this->msg( 'sp-contributions-newbies' )->text(),
                                'contribs',
-                               'newbie' ,
+                               'newbie',
                                'newbie',
                                $this->opts['contribs'] == 'newbie',
                                array( 'class' => 'mw-input' )
@@ -445,7 +445,7 @@ class SpecialContributions extends SpecialPage {
                                        ( $this->opts['target'] ? array() : array( 'autofocus' )
                                )
                        ) . ' '
-               ) ;
+               );
 
                $namespaceSelection =
                        Xml::tags( 'td', array( 'class' => 'mw-label' ),
@@ -483,7 +483,7 @@ class SpecialContributions extends SpecialPage {
                                                array( 'title' => $this->msg( 'tooltip-namespace_association' )->text(), 'class' => 'mw-input' )
                                        ) . '&#160;'
                                )
-                       ) ;
+                       );
 
                if ( $this->getUser()->isAllowed( 'deletedhistory' ) ) {
                        $deletedOnlyCheck = Html::rawElement( 'span', array( 'style' => 'white-space: nowrap' ),
@@ -521,7 +521,7 @@ class SpecialContributions extends SpecialPage {
                                $this->msg( 'sp-contributions-submit' )->text(),
                                array( 'class' => 'mw-submit' )
                        )
-               ) ;
+               );
 
                $form .=
                        Xml::fieldset( $this->msg( 'sp-contributions-search' )->text() ) .
index bdeb7fe..0c934a4 100644 (file)
@@ -168,7 +168,7 @@ class DeletedContribsPager extends IndexPager {
 
                $user = $this->getUser();
 
-               if( $user->isAllowed('deletedtext') ) {
+               if( $user->isAllowed( 'deletedtext' ) ) {
                        $last = Linker::linkKnown(
                                $undelete,
                                $this->messages['diff'],
@@ -475,7 +475,7 @@ class DeletedContributionsPage extends SpecialPage {
                if ( !isset( $options['target'] ) ) {
                        $options['target'] = '';
                } else {
-                       $options['target'] = str_replace( '_' , ' ' , $options['target'] );
+                       $options['target'] = str_replace( '_', ' ', $options['target'] );
                }
 
                if ( !isset( $options['namespace'] ) ) {
@@ -499,7 +499,7 @@ class DeletedContributionsPage extends SpecialPage {
                        $f .= "\t" . Html::hidden( $name, $value ) . "\n";
                }
 
-               $f .=  Xml::openElement( 'fieldset' ) .
+               $f .= Xml::openElement( 'fieldset' ) .
                        Xml::element( 'legend', array(), $this->msg( 'sp-contributions-search' )->text() ) .
                        Xml::tags( 'label', array( 'for' => 'target' ), $this->msg( 'sp-contributions-username' )->parse() ) . ' ' .
                        Html::input( 'target', $options['target'], 'text', array(
index 48180a7..a9c554a 100644 (file)
@@ -59,20 +59,20 @@ class DisambiguationsPage extends QueryPage {
                        if( $dp->getNamespace() != NS_TEMPLATE ) {
                                # @todo FIXME: We assume the disambiguation message is a template but
                                # the page can potentially be from another namespace :/
-                               wfDebug("Mediawiki:disambiguationspage message does not refer to a template!\n");
+                               wfDebug( "Mediawiki:disambiguationspage message does not refer to a template!\n" );
                        }
                        $linkBatch->addObj( $dp );
                } else {
                                # Get all the templates linked from the Mediawiki:Disambiguationspage
                                $disPageObj = Title::makeTitleSafe( NS_MEDIAWIKI, 'disambiguationspage' );
                                $res = $dbr->select(
-                                       array('pagelinks', 'page'),
+                                       array( 'pagelinks', 'page' ),
                                        'pl_title',
-                                       array('page_id = pl_from',
+                                       array( 'page_id = pl_from',
                                                'pl_namespace' => NS_TEMPLATE,
                                                'page_namespace' => $disPageObj->getNamespace(),
-                                               'page_title' => $disPageObj->getDBkey()),
-                                       __METHOD__ );
+                                               'page_title' => $disPageObj->getDBkey()
+                                       ), __METHOD__ );
 
                                foreach ( $res as $row ) {
                                        $linkBatch->addObj( Title::makeTitle( NS_TEMPLATE, $row->pl_title ));
index ee07323..512fd85 100644 (file)
@@ -51,6 +51,7 @@ class DoubleRedirectsPage extends QueryPage {
 
        function reallyGetQueryInfo( $namespace = null, $title = null ) {
                $limitToTitle = !( $namespace === null && $title === null );
+               $dbr = wfGetDB( DB_SLAVE );
                $retval = array (
                        'tables' => array (
                                'ra' => 'redirect',
@@ -82,7 +83,7 @@ class DoubleRedirectsPage extends QueryPage {
 
                                // Need to check both NULL and "" for some reason,
                                // apparently either can be stored for non-iw entries.
-                               '(ra.rd_interwiki IS NULL OR ra.rd_interwiki = "")',
+                               'ra.rd_interwiki IS NULL OR ra.rd_interwiki = ' . $dbr->addQuotes( '' ),
 
                                'pb.page_namespace = ra.rd_namespace',
                                'pb.page_title = ra.rd_title',
@@ -117,7 +118,7 @@ class DoubleRedirectsPage extends QueryPage {
                        $dbr = wfGetDB( DB_SLAVE );
                        $qi = $this->reallyGetQueryInfo( $result->namespace,
                                        $result->title );
-                       $res = $dbr->select($qi['tables'], $qi['fields'],
+                       $res = $dbr->select( $qi['tables'], $qi['fields'],
                                        $qi['conds'], __METHOD__ );
                        if ( $res ) {
                                $result = $dbr->fetchObject( $res );
@@ -128,7 +129,7 @@ class DoubleRedirectsPage extends QueryPage {
                }
 
                $titleB = Title::makeTitle( $result->nsb, $result->tb );
-               $titleC = Title::makeTitle( $result->nsc, $result->tc, '',  $result->iwc );
+               $titleC = Title::makeTitle( $result->nsc, $result->tc, '', $result->iwc );
 
                $linkA = Linker::linkKnown(
                        $titleA,
index 6d5205a..7e1b44a 100644 (file)
@@ -77,6 +77,7 @@ class SpecialEditWatchlist extends UnlistedSpecialPage {
                }
 
                $this->checkPermissions();
+               $this->checkReadOnly();
 
                $this->outputHeader();
 
@@ -289,7 +290,7 @@ class SpecialEditWatchlist extends UnlistedSpecialPage {
 
                $res = $dbr->select(
                        array( 'watchlist' ),
-                       array( 'wl_namespace',  'wl_title' ),
+                       array( 'wl_namespace', 'wl_title' ),
                        array( 'wl_user' => $this->getUser()->getId() ),
                        __METHOD__,
                        array( 'ORDER BY' => array( 'wl_namespace', 'wl_title' ) )
@@ -478,7 +479,7 @@ class SpecialEditWatchlist extends UnlistedSpecialPage {
 
                foreach( $this->getWatchlistInfo() as $namespace => $pages ) {
                        if ( $namespace >= 0 ) {
-                               $fields['TitlesNs'.$namespace] = array(
+                               $fields['TitlesNs' . $namespace] = array(
                                        'class' => 'EditWatchlistCheckboxSeriesField',
                                        'options' => array(),
                                        'section' => "ns$namespace",
@@ -489,7 +490,7 @@ class SpecialEditWatchlist extends UnlistedSpecialPage {
                                $title = Title::makeTitleSafe( $namespace, $dbkey );
                                if ( $this->checkTitle( $title, $namespace, $dbkey ) ) {
                                        $text = $this->buildRemoveLine( $title );
-                                       $fields['TitlesNs'.$namespace]['options'][$text] = $title->getPrefixedText();
+                                       $fields['TitlesNs' . $namespace]['options'][$text] = $title->getPrefixedText();
                                        $count++;
                                }
                        }
@@ -519,7 +520,7 @@ class SpecialEditWatchlist extends UnlistedSpecialPage {
                $form->setTitle( $this->getTitle() );
                $form->setSubmitTextMsg( 'watchlistedit-normal-submit' );
                # Used message keys: 'accesskey-watchlistedit-normal-submit', 'tooltip-watchlistedit-normal-submit'
-               $form->setSubmitTooltip('watchlistedit-normal-submit');
+               $form->setSubmitTooltip( 'watchlistedit-normal-submit' );
                $form->setWrapperLegendMsg( 'watchlistedit-normal-legend' );
                $form->addHeaderText( $this->msg( 'watchlistedit-normal-explain' )->parse() );
                $form->setSubmitCallback( array( $this, 'submitNormal' ) );
@@ -577,7 +578,7 @@ class SpecialEditWatchlist extends UnlistedSpecialPage {
                $form->setTitle( $this->getTitle( 'raw' ) );
                $form->setSubmitTextMsg( 'watchlistedit-raw-submit' );
                # Used message keys: 'accesskey-watchlistedit-raw-submit', 'tooltip-watchlistedit-raw-submit'
-               $form->setSubmitTooltip('watchlistedit-raw-submit');
+               $form->setSubmitTooltip( 'watchlistedit-raw-submit' );
                $form->setWrapperLegendMsg( 'watchlistedit-raw-legend' );
                $form->addHeaderText( $this->msg( 'watchlistedit-raw-explain' )->parse() );
                $form->setSubmitCallback( array( $this, 'submitRaw' ) );
index 18dde20..9d1ec10 100644 (file)
@@ -80,7 +80,7 @@ class SpecialExport extends SpecialPage {
                        $page = $request->getText( 'pages' );
                        $nsindex = $request->getText( 'nsindex', '' );
 
-                       if ( strval( $nsindex ) !== ''  ) {
+                       if ( strval( $nsindex ) !== '' ) {
                                /**
                                 * Same implementation as above, so same @todo
                                 */
@@ -124,7 +124,7 @@ class SpecialExport extends SpecialPage {
                        if ( $this->curonly ) {
                                $history = WikiExporter::CURRENT;
                        } elseif ( !$historyCheck ) {
-                               if ( $limit > 0 && ($wgExportMaxHistory == 0 || $limit < $wgExportMaxHistory ) ) {
+                               if ( $limit > 0 && ( $wgExportMaxHistory == 0 || $limit < $wgExportMaxHistory ) ) {
                                        $history['limit'] = $limit;
                                }
                                if ( !is_null( $offset ) ) {
@@ -161,7 +161,7 @@ class SpecialExport extends SpecialPage {
 
                $list_authors = $request->getCheck( 'listauthors' );
                if ( !$this->curonly || !$wgExportAllowListContributors ) {
-                       $list_authors = false ;
+                       $list_authors = false;
                }
 
                if ( $this->doExport ) {
@@ -339,7 +339,7 @@ class SpecialExport extends SpecialPage {
 
                        // This might take a while... :D
                        wfSuppressWarnings();
-                       set_time_limit(0);
+                       set_time_limit( 0 );
                        wfRestoreWarnings();
                }
 
@@ -405,7 +405,7 @@ class SpecialExport extends SpecialPage {
 
                foreach ( $res as $row ) {
                        $n = $row->page_title;
-                       if ($row->page_namespace) {
+                       if ( $row->page_namespace ) {
                                $ns = $wgContLang->getNsText( $row->page_namespace );
                                $n = $ns . ':' . $n;
                        }
index 96739ea..366aa81 100644 (file)
@@ -101,7 +101,7 @@ class FileDuplicateSearchPage extends QueryPage {
                $this->setHeaders();
                $this->outputHeader();
 
-               $this->filename =  isset( $par ) ?  $par : $this->getRequest()->getText( 'filename' );
+               $this->filename = isset( $par ) ?  $par : $this->getRequest()->getText( 'filename' );
                $this->file = null;
                $this->hash = '';
                $title = Title::newFromText( $this->filename, NS_FILE );
index 7247470..16772ec 100644 (file)
@@ -353,7 +353,7 @@ class ImportReporter extends ContextSource {
        private $mOriginalPageOutCallback = null;
        private $mLogItemCount = 0;
 
-       function __construct( $importer, $upload, $interwiki , $reason=false ) {
+       function __construct( $importer, $upload, $interwiki, $reason = false ) {
                $this->mOriginalPageOutCallback =
                                $importer->setPageOutCallback( array( $this, 'reportPage' ) );
                $this->mOriginalLogCallback =
@@ -410,7 +410,7 @@ class ImportReporter extends ContextSource {
                                $detail = $this->msg( 'import-logentry-upload-detail' )->numParams(
                                        $successCount )->inContentLanguage()->text();
                                if ( $this->reason ) {
-                                       $detail .=  $this->msg( 'colon-separator' )->inContentLanguage()->text() . $this->reason;
+                                       $detail .= $this->msg( 'colon-separator' )->inContentLanguage()->text() . $this->reason;
                                }
                                $log->addEntry( 'upload', $title, $detail );
                        } else {
@@ -419,7 +419,7 @@ class ImportReporter extends ContextSource {
                                $detail = $this->msg( 'import-logentry-interwiki-detail' )->numParams(
                                        $successCount )->params( $interwiki )->inContentLanguage()->text();
                                if ( $this->reason ) {
-                                       $detail .=  $this->msg( 'colon-separator' )->inContentLanguage()->text() . $this->reason;
+                                       $detail .= $this->msg( 'colon-separator' )->inContentLanguage()->text() . $this->reason;
                                }
                                $log->addEntry( 'interwiki', $title, $detail );
                        }
@@ -428,7 +428,7 @@ class ImportReporter extends ContextSource {
                        $dbw = wfGetDB( DB_MASTER );
                        $latest = $title->getLatestRevID();
                        $nullRevision = Revision::newNullRevision( $dbw, $title->getArticleID(), $comment, true );
-                       if (!is_null($nullRevision)) {
+                       if ( !is_null( $nullRevision ) ) {
                                $nullRevision->insertOn( $dbw );
                                $page = WikiPage::factory( $title );
                                # Update page record
index 9a224b6..f5fa697 100644 (file)
@@ -64,15 +64,15 @@ class LinkSearchPage extends QueryPage {
 
                $target2 = $target;
                $protocol = '';
-               $pr_sl = strpos($target2, '//' );
-               $pr_cl = strpos($target2, ':' );
+               $pr_sl = strpos( $target2, '//' );
+               $pr_cl = strpos( $target2, ':' );
                if ( $pr_sl ) {
                        // For protocols with '//'
-                       $protocol = substr( $target2, 0 , $pr_sl+2 );
-                       $target2 = substr( $target2, $pr_sl+2 );
+                       $protocol = substr( $target2, 0, $pr_sl + 2 );
+                       $target2 = substr( $target2, $pr_sl + 2 );
                } elseif ( !$pr_sl && $pr_cl ) {
                        // For protocols without '//' like 'mailto:'
-                       $protocol = substr( $target2, 0 , $pr_cl+1 );
+                       $protocol = substr( $target2, 0, $pr_cl + 1 );
                        $target2 = substr( $target2, $pr_cl+1 );
                } elseif ( $protocol == '' && $target2 != '' ) {
                        // default
@@ -138,10 +138,10 @@ class LinkSearchPage extends QueryPage {
         */
        static function mungeQuery( $query, $prot ) {
                $field = 'el_index';
-               $rv = LinkFilter::makeLikeArray( $query , $prot );
+               $rv = LinkFilter::makeLikeArray( $query, $prot );
                if ( $rv === false ) {
                        // LinkFilter doesn't handle wildcard in IP, so we'll have to munge here.
-                       if (preg_match('/^(:?[0-9]{1,3}\.)+\*\s*$|^(:?[0-9]{1,3}\.){3}[0-9]{1,3}:[0-9]*\*\s*$/', $query)) {
+                       if ( preg_match( '/^(:?[0-9]{1,3}\.)+\*\s*$|^(:?[0-9]{1,3}\.){3}[0-9]{1,3}:[0-9]*\*\s*$/', $query ) ) {
                                $dbr = wfGetDB( DB_SLAVE );
                                $rv = array( $prot . rtrim( $query, " \t*" ), $dbr->anyString() );
                                $field = 'el_to';
@@ -201,7 +201,7 @@ class LinkSearchPage extends QueryPage {
         * Override to check query validity.
         */
        function doQuery( $offset = false, $limit = false ) {
-               list( $this->mMungedQuery,  ) = LinkSearchPage::mungeQuery( $this->mQuery, $this->mProt );
+               list( $this->mMungedQuery, ) = LinkSearchPage::mungeQuery( $this->mQuery, $this->mProt );
                if( $this->mMungedQuery === false ) {
                        $this->getOutput()->addWikiMsg( 'linksearch-error' );
                } else {
index ef68302..661db7b 100644 (file)
@@ -137,7 +137,7 @@ class ImageListPager extends TablePager {
                $tables = array( 'image' );
                $fields = array_keys( $this->getFieldNames() );
                $fields[] = 'img_user';
-               $fields[array_search('thumb', $fields)] = 'img_name AS thumb';
+               $fields[array_search( 'thumb', $fields )] = 'img_name AS thumb';
                $options = $join_conds = array();
 
                # Depends on $wgMiserMode
index ea598c3..3265d1a 100644 (file)
@@ -116,7 +116,7 @@ class UsersPager extends AlphabeticPager {
                $options['GROUP BY'] = $this->creationSort ? 'user_id' : 'user_name';
 
                $query = array(
-                       'tables' => array( 'user', 'user_groups', 'ipblocks'),
+                       'tables' => array( 'user', 'user_groups', 'ipblocks' ),
                        'fields' => array(
                                'user_name' => $this->creationSort ? 'MAX(user_name)' : 'user_name',
                                'user_id' => $this->creationSort ? 'user_id' : 'MAX(user_id)',
@@ -212,17 +212,26 @@ class UsersPager extends AlphabeticPager {
                list( $self ) = explode( '/', $this->getTitle()->getPrefixedDBkey() );
 
                # Form tag
-               $out  = Xml::openElement( 'form', array( 'method' => 'get', 'action' => $wgScript, 'id' => 'mw-listusers-form' ) ) .
+               $out = Xml::openElement( 'form', array( 'method' => 'get', 'action' => $wgScript, 'id' => 'mw-listusers-form' ) ) .
                        Xml::fieldset( $this->msg( 'listusers' )->text() ) .
                        Html::hidden( 'title', $self );
 
                # Username field
                $out .= Xml::label( $this->msg( 'listusersfrom' )->text(), 'offset' ) . ' ' .
-                       Xml::input( 'username', 20, $this->requestedUser, array( 'id' => 'offset' ) ) . ' ';
+                       Html::input(
+                               'username',
+                               $this->requestedUser,
+                               'text',
+                               array(
+                                       'id' => 'offset',
+                                       'size' => 20,
+                                       'autofocus' => $this->requestedUser === ''
+                               )
+                       ) . ' ';
 
                # Group drop-down list
                $out .= Xml::label( $this->msg( 'group' )->text(), 'group' ) . ' ' .
-                       Xml::openElement('select',  array( 'name' => 'group', 'id' => 'group' ) ) .
+                       Xml::openElement( 'select', array( 'name' => 'group', 'id' => 'group' ) ) .
                        Xml::option( $this->msg( 'group-all' )->text(), '' );
                foreach( $this->getAllGroups() as $group => $groupText )
                        $out .= Xml::option( $groupText, $group, $group == $this->requestedGroup );
index 22932e5..a2d51db 100644 (file)
@@ -125,4 +125,3 @@ class MostlinkedTemplatesPage extends QueryPage {
                return Linker::link( $wlh, $label );
        }
 }
-
index 66fd918..bf93ef2 100644 (file)
@@ -152,7 +152,7 @@ class MovePageForm extends UnlistedSpecialPage {
                                </tr>";
                        $err = array();
                } else {
-                       if ($this->oldTitle->getNamespace() == NS_USER && !$this->oldTitle->isSubpage() ) {
+                       if ( $this->oldTitle->getNamespace() == NS_USER && !$this->oldTitle->isSubpage() ) {
                                $out->wrapWikiMsg( "<div class=\"error mw-moveuserpage-warning\">\n$1\n</div>", 'moveuserpage-warning' );
                        }
                        $out->addWikiMsg( $wgFixDoubleRedirects ? 'movepagetext' :
@@ -189,7 +189,7 @@ class MovePageForm extends UnlistedSpecialPage {
                                array(
                                        'rd_namespace' => $this->oldTitle->getNamespace(),
                                        'rd_title' => $this->oldTitle->getDBkey(),
-                               ) , __METHOD__ );
+                               ), __METHOD__ );
                } else {
                        $hasRedirects = false;
                }
@@ -257,11 +257,11 @@ class MovePageForm extends UnlistedSpecialPage {
                $handler = ContentHandler::getForTitle( $this->oldTitle );
 
                $out->addHTML(
-                        Xml::openElement( 'form', array( 'method' => 'post', 'action' => $this->getTitle()->getLocalURL( 'action=submit' ), 'id' => 'movepage' ) ) .
-                        Xml::openElement( 'fieldset' ) .
-                        Xml::element( 'legend', null, $this->msg( 'move-page-legend' )->text() ) .
-                        Xml::openElement( 'table', array( 'id' => 'mw-movepage-table' ) ) .
-                        "<tr>
+                       Xml::openElement( 'form', array( 'method' => 'post', 'action' => $this->getTitle()->getLocalURL( 'action=submit' ), 'id' => 'movepage' ) ) .
+                       Xml::openElement( 'fieldset' ) .
+                       Xml::element( 'legend', null, $this->msg( 'move-page-legend' )->text() ) .
+                       Xml::openElement( 'table', array( 'id' => 'mw-movepage-table' ) ) .
+                       "<tr>
                                <td class='mw-label'>" .
                                        $this->msg( 'movearticle' )->escaped() .
                                "</td>
@@ -344,7 +344,7 @@ class MovePageForm extends UnlistedSpecialPage {
                                        'wpMovesubpages',
                                        # Don't check the box if we only have talk subpages to
                                        # move and we aren't moving the talk page.
-                                       $this->moveSubpages && ($this->oldTitle->hasSubpages() || $this->moveTalk),
+                                       $this->moveSubpages && ( $this->oldTitle->hasSubpages() || $this->moveTalk ),
                                        array( 'id' => 'wpMovesubpages' )
                                ) . '&#160;' .
                                Xml::tags( 'label', array( 'for' => 'wpMovesubpages' ),
@@ -359,7 +359,7 @@ class MovePageForm extends UnlistedSpecialPage {
                        );
                }
 
-               $watchChecked = $user->isLoggedIn() && ($this->watch || $user->getBoolOption( 'watchmoves' )
+               $watchChecked = $user->isLoggedIn() && ( $this->watch || $user->getBoolOption( 'watchmoves' )
                        || $user->isWatched( $this->oldTitle ) );
                # Don't allow watching if user is not logged in
                if( $user->isLoggedIn() ) {
@@ -538,10 +538,10 @@ class MovePageForm extends UnlistedSpecialPage {
                        );
                        $conds['page_namespace'] = array();
                        if( MWNamespace::hasSubpages( $nt->getNamespace() ) ) {
-                               $conds['page_namespace'] []= $ot->getNamespace();
+                               $conds['page_namespace'][] = $ot->getNamespace();
                        }
                        if( $this->moveTalk && MWNamespace::hasSubpages( $nt->getTalkPage()->getNamespace() ) ) {
-                               $conds['page_namespace'] []= $ot->getTalkPage()->getNamespace();
+                               $conds['page_namespace'][] = $ot->getTalkPage()->getNamespace();
                        }
                } elseif( $this->moveTalk ) {
                        $conds = array(
@@ -587,7 +587,7 @@ class MovePageForm extends UnlistedSpecialPage {
                        $newSubpage = Title::makeTitleSafe( $newNs, $newPageName );
                        if( !$newSubpage ) {
                                $oldLink = Linker::linkKnown( $oldSubpage );
-                               $extraOutput []= $this->msg( 'movepage-page-unmoved' )->rawParams( $oldLink
+                               $extraOutput[] = $this->msg( 'movepage-page-unmoved' )->rawParams( $oldLink
                                        )->params( Title::makeName( $newNs, $newPageName ) )->escaped();
                                continue;
                        }
@@ -595,7 +595,7 @@ class MovePageForm extends UnlistedSpecialPage {
                        # This was copy-pasted from Renameuser, bleh.
                        if ( $newSubpage->exists() && !$oldSubpage->isValidMoveTarget( $newSubpage ) ) {
                                $link = Linker::linkKnown( $newSubpage );
-                               $extraOutput []= $this->msg( 'movepage-page-exists' )->rawParams( $link )->escaped();
+                               $extraOutput[] = $this->msg( 'movepage-page-exists' )->rawParams( $link )->escaped();
                        } else {
                                $success = $oldSubpage->moveTo( $newSubpage, true, $this->reason, $createRedirect );
                                if( $success === true ) {
@@ -609,16 +609,16 @@ class MovePageForm extends UnlistedSpecialPage {
                                                array( 'redirect' => 'no' )
                                        );
                                        $newLink = Linker::linkKnown( $newSubpage );
-                                       $extraOutput []= $this->msg( 'movepage-page-moved' )->rawParams( $oldLink, $newLink )->escaped();
+                                       $extraOutput[] = $this->msg( 'movepage-page-moved' )->rawParams( $oldLink, $newLink )->escaped();
                                        ++$count;
                                        if( $count >= $wgMaximumMovedPages ) {
-                                               $extraOutput []= $this->msg( 'movepage-max-pages' )->numParams( $wgMaximumMovedPages )->escaped();
+                                               $extraOutput[] = $this->msg( 'movepage-max-pages' )->numParams( $wgMaximumMovedPages )->escaped();
                                                break;
                                        }
                                } else {
                                        $oldLink = Linker::linkKnown( $oldSubpage );
                                        $newLink = Linker::link( $newSubpage );
-                                       $extraOutput []= $this->msg( 'movepage-page-unmoved' )->rawParams( $oldLink, $newLink )->escaped();
+                                       $extraOutput[] = $this->msg( 'movepage-page-unmoved' )->rawParams( $oldLink, $newLink )->escaped();
                                }
                        }
 
index d9d6a79..cc301a5 100644 (file)
@@ -105,7 +105,7 @@ class SpecialNewpages extends IncludableSpecialPage {
                        }
                        // PG offsets not just digits!
                        if ( preg_match( '/^offset=([^=]+)$/', $bit, $m ) ) {
-                               $this->opts->setValue( 'offset',  intval( $m[1] ) );
+                               $this->opts->setValue( 'offset', intval( $m[1] ) );
                        }
                        if ( preg_match( '/^username=(.*)$/', $bit, $m ) ) {
                                $this->opts->setValue( 'username', $m[1] );
@@ -113,7 +113,7 @@ class SpecialNewpages extends IncludableSpecialPage {
                        if ( preg_match( '/^namespace=(.*)$/', $bit, $m ) ) {
                                $ns = $this->getLanguage()->getNsIndex( $m[1] );
                                if( $ns !== false ) {
-                                       $this->opts->setValue( 'namespace',  $ns );
+                                       $this->opts->setValue( 'namespace', $ns );
                                }
                        }
                }
@@ -296,11 +296,11 @@ class SpecialNewpages extends IncludableSpecialPage {
 
                # Revision deletion works on revisions, so we should cast one
                $row = array(
-                                         'comment' => $result->rc_comment,
-                                         'deleted' => $result->rc_deleted,
-                                         'user_text' => $result->rc_user_text,
-                                         'user' => $result->rc_user,
-                                       );
+                       'comment' => $result->rc_comment,
+                       'deleted' => $result->rc_deleted,
+                       'user_text' => $result->rc_user_text,
+                       'user' => $result->rc_user,
+               );
                $rev = new Revision( $row );
                $rev->setTitle( $title );
 
index 5a9f3f7..99b586e 100644 (file)
@@ -46,7 +46,7 @@ class PopularPagesPage extends QueryPage {
                        'tables' => array( 'page' ),
                        'fields' => array( 'namespace' => 'page_namespace',
                                        'title' => 'page_title',
-                                       'value' => 'page_counter'),
+                                       'value' => 'page_counter' ),
                        'conds' => array( 'page_is_redirect' => 0,
                                        'page_namespace' => MWNamespace::getContentNamespaces() ) );
        }
index f3895e8..e1e18e4 100644 (file)
@@ -145,8 +145,8 @@ class SpecialPrefixindex extends SpecialAllpages {
                        $from = $prefix;
                }
 
-               $fromList = $this->getNamespaceKeyAndText($namespace, $from);
-               $prefixList = $this->getNamespaceKeyAndText($namespace, $prefix);
+               $fromList = $this->getNamespaceKeyAndText( $namespace, $from );
+               $prefixList = $this->getNamespaceKeyAndText( $namespace, $prefix );
                $namespaces = $wgContLang->getNamespaces();
 
                if ( !$prefixList || !$fromList ) {
@@ -227,7 +227,7 @@ class SpecialPrefixindex extends SpecialAllpages {
                } else {
                        $nsForm = $this->namespacePrefixForm( $namespace, $prefix, $hideredirects );
                        $self = $this->getTitle();
-                       $out2 = Xml::openElement( 'table', array( 'id' => 'mw-prefixindex-nav-table' ) )  .
+                       $out2 = Xml::openElement( 'table', array( 'id' => 'mw-prefixindex-nav-table' ) ) .
                                '<tr>
                                        <td>' .
                                                $nsForm .
@@ -241,7 +241,7 @@ class SpecialPrefixindex extends SpecialAllpages {
                                        'hideredirects' => $hideredirects,
                                );
 
-                               if( $namespace || ($prefix == '')) {
+                               if( $namespace || $prefix == '' ) {
                                        // Keep the namespace even if it's 0 for empty prefixes.
                                        // This tells us we're not just a holdover from old links.
                                        $query['namespace'] = $namespace;
index aceac3f..d580d62 100644 (file)
@@ -51,7 +51,7 @@ class SpecialProtectedpages extends SpecialPage {
                $size = $request->getIntOrNull( 'size' );
                $NS = $request->getIntOrNull( 'namespace' );
                $indefOnly = $request->getBool( 'indefonly' ) ? 1 : 0;
-               $cascadeOnly = $request->getBool('cascadeonly') ? 1 : 0;
+               $cascadeOnly = $request->getBool( 'cascadeonly' ) ? 1 : 0;
 
                $pager = new ProtectedPagesPager( $this, array(), $type, $level, $NS, $sizetype, $size, $indefOnly, $cascadeOnly );
 
@@ -109,7 +109,7 @@ class SpecialProtectedpages extends SpecialPage {
                        )->escaped();
                }
 
-               if(!is_null($size = $row->page_len)) {
+               if( !is_null( $size = $row->page_len ) ) {
                        $stxt = $lang->getDirMark() . ' ' . Linker::formatRevisionSize( $size );
                }
 
@@ -154,7 +154,7 @@ class SpecialProtectedpages extends SpecialPage {
         * @param $cascadeOnly Boolean: only cascading protection
         * @return String: input form
         */
-       protected function showOptions( $namespace, $type='edit', $level, $sizetype, $size, $indefOnly, $cascadeOnly ) {
+       protected function showOptions( $namespace, $type = 'edit', $level, $sizetype, $size, $indefOnly, $cascadeOnly ) {
                global $wgScript;
                $title = $this->getTitle();
                return Xml::openElement( 'form', array( 'method' => 'get', 'action' => $wgScript ) ) .
@@ -272,7 +272,7 @@ class SpecialProtectedpages extends SpecialPage {
                // First pass to load the log names
                foreach( $wgRestrictionLevels as $type ) {
                        // Messages used can be 'restriction-level-sysop' and 'restriction-level-autoconfirmed'
-                       if( $type !='' && $type !='*') {
+                       if( $type != '' && $type != '*' ) {
                                $text = $this->msg( "restriction-level-$type" )->text();
                                $m[$text] = $type;
                        }
@@ -300,7 +300,7 @@ class ProtectedPagesPager extends AlphabeticPager {
        public $mForm, $mConds;
        private $type, $level, $namespace, $sizetype, $size, $indefonly;
 
-       function __construct( $form, $conds = array(), $type, $level, $namespace, $sizetype='', $size=0,
+       function __construct( $form, $conds = array(), $type, $level, $namespace, $sizetype = '', $size = 0,
                $indefonly = false, $cascadeonly = false )
        {
                $this->mForm = $form;
@@ -309,7 +309,7 @@ class ProtectedPagesPager extends AlphabeticPager {
                $this->level = $level;
                $this->namespace = $namespace;
                $this->sizetype = $sizetype;
-               $this->size = intval($size);
+               $this->size = intval( $size );
                $this->indefonly = (bool)$indefonly;
                $this->cascadeonly = (bool)$cascadeonly;
                parent::__construct( $form->getContext() );
@@ -336,9 +336,9 @@ class ProtectedPagesPager extends AlphabeticPager {
                $conds[] = 'page_id=pr_page';
                $conds[] = 'pr_type=' . $this->mDb->addQuotes( $this->type );
 
-               if( $this->sizetype=='min' ) {
+               if( $this->sizetype == 'min' ) {
                        $conds[] = 'page_len>=' . $this->size;
-               } elseif( $this->sizetype=='max' ) {
+               } elseif( $this->sizetype == 'max' ) {
                        $conds[] = 'page_len<=' . $this->size;
                }
 
@@ -351,7 +351,7 @@ class ProtectedPagesPager extends AlphabeticPager {
 
                if( $this->level )
                        $conds[] = 'pr_level=' . $this->mDb->addQuotes( $this->level );
-               if( !is_null($this->namespace) )
+               if( !is_null( $this->namespace ) )
                        $conds[] = 'page_namespace=' . $this->mDb->addQuotes( $this->namespace );
                return array(
                        'tables' => array( 'page_restrictions', 'page' ),
index da0a63c..abb4af3 100644 (file)
@@ -113,7 +113,7 @@ class SpecialProtectedtitles extends SpecialPage {
         * @return string
         * @private
         */
-       function showOptions( $namespace, $type='edit', $level ) {
+       function showOptions( $namespace, $type = 'edit', $level ) {
                global $wgScript;
                $action = htmlspecialchars( $wgScript );
                $title = $this->getTitle();
@@ -161,13 +161,13 @@ class SpecialProtectedtitles extends SpecialPage {
 
                // First pass to load the log names
                foreach( $wgRestrictionLevels as $type ) {
-                       if ( $type !='' && $type !='*') {
+                       if ( $type != '' && $type != '*' ) {
                                $text = $this->msg( "restriction-level-$type" )->text();
                                $m[$text] = $type;
                        }
                }
                // Is there only one level (aside from "all")?
-               if( count($m) <= 2 ) {
+               if( count( $m ) <= 2 ) {
                        return '';
                }
                // Third pass generates sorted XHTML content
@@ -191,7 +191,7 @@ class SpecialProtectedtitles extends SpecialPage {
 class ProtectedTitlesPager extends AlphabeticPager {
        public $mForm, $mConds;
 
-       function __construct( $form, $conds = array(), $type, $level, $namespace, $sizetype='', $size=0 ) {
+       function __construct( $form, $conds = array(), $type, $level, $namespace, $sizetype = '', $size = 0 ) {
                $this->mForm = $form;
                $this->mConds = $conds;
                $this->level = $level;
@@ -234,7 +234,7 @@ class ProtectedTitlesPager extends AlphabeticPager {
                $conds[] = 'pt_expiry>' . $this->mDb->addQuotes( $this->mDb->timestamp() );
                if( $this->level )
                        $conds['pt_create_perm'] = $this->level;
-               if( !is_null($this->namespace) )
+               if( !is_null( $this->namespace ) )
                        $conds[] = 'pt_namespace=' . $this->mDb->addQuotes( $this->namespace );
                return array(
                        'tables' => 'protected_titles',
index 6502c72..7ea3a94 100644 (file)
@@ -42,16 +42,16 @@ class SpecialRecentChanges extends IncludableSpecialPage {
        public function getDefaultOptions() {
                $opts = new FormOptions();
 
-               $opts->add( 'days',  (int)$this->getUser()->getOption( 'rcdays' ) );
+               $opts->add( 'days', (int)$this->getUser()->getOption( 'rcdays' ) );
                $opts->add( 'limit', (int)$this->getUser()->getOption( 'rclimit' ) );
                $opts->add( 'from', '' );
 
-               $opts->add( 'hideminor',     $this->getUser()->getBoolOption( 'hideminor' ) );
-               $opts->add( 'hidebots',      true  );
-               $opts->add( 'hideanons',     false );
-               $opts->add( 'hideliu',       false );
+               $opts->add( 'hideminor', $this->getUser()->getBoolOption( 'hideminor' ) );
+               $opts->add( 'hidebots', true  );
+               $opts->add( 'hideanons', false );
+               $opts->add( 'hideliu', false );
                $opts->add( 'hidepatrolled', $this->getUser()->getBoolOption( 'hidepatrolled' ) );
-               $opts->add( 'hidemyself',    false );
+               $opts->add( 'hidemyself', false );
 
                $opts->add( 'namespace', '', FormOptions::INTNULL );
                $opts->add( 'invert', false );
@@ -232,7 +232,7 @@ class SpecialRecentChanges extends IncludableSpecialPage {
                        }
 
                        if( is_numeric( $bit ) ) {
-                               $opts['limit'] =  $bit;
+                               $opts['limit'] = $bit;
                        }
 
                        $m = array();
@@ -296,7 +296,7 @@ class SpecialRecentChanges extends IncludableSpecialPage {
                $cutoff_unixtime = $cutoff_unixtime - ($cutoff_unixtime % 86400);
                $cutoff = $dbr->timestamp( $cutoff_unixtime );
 
-               $fromValid = preg_match('/^[0-9]{14}$/', $opts['from']);
+               $fromValid = preg_match( '/^[0-9]{14}$/', $opts['from'] );
                if( $fromValid && $opts['from'] > wfTimestamp( TS_MW, $cutoff ) ) {
                        $cutoff = $dbr->timestamp( $opts['from'] );
                } else {
@@ -351,8 +351,8 @@ class SpecialRecentChanges extends IncludableSpecialPage {
                                        MWNamespace::getAssociated( $opts['namespace'] )
                                );
                                $condition = "(rc_namespace $operator $selectedNS "
-                                                  . $boolean
-                                                  . " rc_namespace $operator $associatedNS)";
+                                       . $boolean
+                                       . " rc_namespace $operator $associatedNS)";
                        }
 
                        $conds[] = $condition;
@@ -387,7 +387,7 @@ class SpecialRecentChanges extends IncludableSpecialPage {
                        $tables[] = 'watchlist';
                        $fields[] = 'wl_user';
                        $fields[] = 'wl_notificationtimestamp';
-                       $join_conds['watchlist'] = array('LEFT JOIN', array(
+                       $join_conds['watchlist'] = array( 'LEFT JOIN', array(
                                'wl_user' => $uid,
                                'wl_title=rc_title',
                                'wl_namespace=rc_namespace'
@@ -396,7 +396,7 @@ class SpecialRecentChanges extends IncludableSpecialPage {
                if ( $this->getUser()->isAllowed( 'rollback' ) ) {
                        $tables[] = 'page';
                        $fields[] = 'page_latest';
-                       $join_conds['page'] = array('LEFT JOIN', 'rc_cur_id=page_id');
+                       $join_conds['page'] = array( 'LEFT JOIN', 'rc_cur_id=page_id' );
                }
                // Tag stuff.
                ChangeTags::modifyDisplayQuery(
@@ -545,7 +545,7 @@ class SpecialRecentChanges extends IncludableSpecialPage {
 
        /**
         * Get the query string to append to feed link URLs.
-        * 
+        *
         * @return string
         */
        public function getFeedQuery() {
index 3dae3a7..6d7173b 100644 (file)
@@ -110,7 +110,7 @@ class SpecialRecentchangeslinked extends SpecialRecentChanges {
                }
                if ( $this->getUser()->isAllowed( 'rollback' ) ) {
                        $tables[] = 'page';
-                       $join_conds['page'] = array('LEFT JOIN', 'rc_cur_id=page_id');
+                       $join_conds['page'] = array( 'LEFT JOIN', 'rc_cur_id=page_id' );
                        $select[] = 'page_latest';
                }
                ChangeTags::modifyDisplayQuery(
@@ -204,15 +204,15 @@ class SpecialRecentchangeslinked extends SpecialRecentChanges {
                        $subsql[] = $query;
                }
 
-               if( count($subsql) == 0 ) {
+               if( count( $subsql ) == 0 ) {
                        return false; // should never happen
                }
-               if( count($subsql) == 1 && $dbr->unionSupportsOrderAndLimit() ) {
+               if( count( $subsql ) == 1 && $dbr->unionSupportsOrderAndLimit() ) {
                        $sql = $subsql[0];
                } else {
                        // need to resort and relimit after union
-                       $sql = $dbr->unionQueries($subsql, false).' ORDER BY rc_timestamp DESC';
-                       $sql = $dbr->limitResult($sql, $limit, false);
+                       $sql = $dbr->unionQueries( $subsql, false ) . ' ORDER BY rc_timestamp DESC';
+                       $sql = $dbr->limitResult( $sql, $limit, false );
                }
 
                $res = $dbr->query( $sql, __METHOD__ );
@@ -237,7 +237,7 @@ class SpecialRecentchangeslinked extends SpecialRecentChanges {
                        Xml::check( 'showlinkedto', $opts['showlinkedto'], array( 'id' => 'showlinkedto' ) ) . ' ' .
                        Xml::label( $this->msg( 'recentchangeslinked-to' )->text(), 'showlinkedto' ) );
                $tagFilter = ChangeTags::buildTagFilterSelector( $opts['tagfilter'] );
-               if ($tagFilter) {
+               if ( $tagFilter ) {
                        $extraOpts['tagfilter'] = $tagFilter;
                }
                return $extraOpts;
index eaf0d52..6f75da4 100644 (file)
@@ -133,7 +133,7 @@ class SpecialRevisionDelete extends UnlistedSpecialPage {
                        $this->ids = explode( ',', $ids );
                } else {
                        # Array input
-                       $this->ids = array_keys( $request->getArray('ids',array()) );
+                       $this->ids = array_keys( $request->getArray( 'ids', array() ) );
                }
                // $this->ids = array_map( 'intval', $this->ids );
                $this->ids = array_unique( array_filter( $this->ids ) );
@@ -191,7 +191,7 @@ class SpecialRevisionDelete extends UnlistedSpecialPage {
 
                $this->otherReason = $request->getVal( 'wpReason' );
                # We need a target page!
-               if( is_null($this->targetObj) ) {
+               if( is_null( $this->targetObj ) ) {
                        $output->addWikiMsg( 'undelete-header' );
                        return;
                }
@@ -204,7 +204,7 @@ class SpecialRevisionDelete extends UnlistedSpecialPage {
                        array( 'revdelete-hide-comment', 'wpHideComment', Revision::DELETED_COMMENT ),
                        array( 'revdelete-hide-user', 'wpHideUser', Revision::DELETED_USER )
                );
-               if( $user->isAllowed('suppressrevision') ) {
+               if( $user->isAllowed( 'suppressrevision' ) ) {
                        $this->checks[] = array( 'revdelete-hide-restricted',
                                'wpHideRestricted', Revision::DELETED_RESTRICTED );
                }
@@ -225,7 +225,7 @@ class SpecialRevisionDelete extends UnlistedSpecialPage {
                # Show relevant lines from the suppression log
                if( $user->isAllowed( 'suppressionlog' ) ) {
                        $suppressLogPage = new LogPage( 'suppress' );
-                       $output->addHTML( "<h2>" . $suppressLogPage->getName()->escaped()  . "</h2>\n" );
+                       $output->addHTML( "<h2>" . $suppressLogPage->getName()->escaped() . "</h2>\n" );
                        LogEventsList::showLogExtract( $output, 'suppress',
                                $this->targetObj, '', array( 'lim' => 25, 'conds' => $qc ) );
                }
@@ -253,7 +253,7 @@ class SpecialRevisionDelete extends UnlistedSpecialPage {
                                        array( 'action' => 'history' )
                                );
                                # Link to deleted edits
-                               if( $this->getUser()->isAllowed('undelete') ) {
+                               if( $this->getUser()->isAllowed( 'undelete' ) ) {
                                        $undelete = SpecialPage::getTitleFor( 'Undelete' );
                                        $links[] = Linker::linkKnown(
                                                $undelete,
@@ -356,7 +356,7 @@ class SpecialRevisionDelete extends UnlistedSpecialPage {
                $UserAllowed = true;
 
                if ( $this->typeName == 'logging' ) {
-                       $this->getOutput()->addWikiMsg( 'logdelete-selected', $this->getLanguage()->formatNum( count($this->ids) ) );
+                       $this->getOutput()->addWikiMsg( 'logdelete-selected', $this->getLanguage()->formatNum( count( $this->ids ) ) );
                } else {
                        $this->getOutput()->addWikiMsg( 'revdelete-selected',
                                $this->targetObj->getPrefixedText(), count( $this->ids ) );
@@ -522,7 +522,7 @@ class SpecialRevisionDelete extends UnlistedSpecialPage {
         */
        protected function submit() {
                # Check edit token on submission
-               $token = $this->getRequest()->getVal('wpEditToken');
+               $token = $this->getRequest()->getVal( 'wpEditToken' );
                if( $this->submitClicked && !$this->getUser()->matchEditToken( $token ) ) {
                        $this->getOutput()->addWikiMsg( 'sessionfailure' );
                        return false;
@@ -537,7 +537,7 @@ class SpecialRevisionDelete extends UnlistedSpecialPage {
                        $comment = $this->otherReason;
                }
                # Can the user set this field?
-               if( $bitParams[Revision::DELETED_RESTRICTED]==1 && !$this->getUser()->isAllowed('suppressrevision') ) {
+               if( $bitParams[Revision::DELETED_RESTRICTED] == 1 && !$this->getUser()->isAllowed( 'suppressrevision' ) ) {
                        throw new PermissionsError( 'suppressrevision' );
                }
                # If the save went through, go to success message...
@@ -579,14 +579,14 @@ class SpecialRevisionDelete extends UnlistedSpecialPage {
        protected function extractBitParams() {
                $bitfield = array();
                foreach( $this->checks as $item ) {
-                       list( /* message */ , $name, $field ) = $item;
+                       list( /* message */, $name, $field ) = $item;
                        $val = $this->getRequest()->getInt( $name, 0 /* unchecked */ );
                        if( $val < -1 || $val > 1) {
                                $val = -1; // -1 for existing value
                        }
                        $bitfield[$field] = $val;
                }
-               if( !isset($bitfield[Revision::DELETED_RESTRICTED]) ) {
+               if( !isset( $bitfield[Revision::DELETED_RESTRICTED] ) ) {
                        $bitfield[Revision::DELETED_RESTRICTED] = 0;
                }
                return $bitfield;
@@ -624,4 +624,3 @@ class SpecialRevisionDelete extends UnlistedSpecialPage {
                );
        }
 }
-
index 397a24f..77f0ddb 100644 (file)
@@ -138,7 +138,7 @@ class SpecialSearch extends SpecialPage {
                        // BC with old request format
                        $profile = 'advanced';
                        foreach( $profiles as $key => $data ) {
-                               if ( $nslist === $data['namespaces'] && $key !== 'advanced') {
+                               if ( $nslist === $data['namespaces'] && $key !== 'advanced' ) {
                                        $profile = $key;
                                }
                        }
@@ -159,7 +159,7 @@ class SpecialSearch extends SpecialPage {
                $default = $request->getBool( 'profile' ) ? 0 : 1;
                $this->searchRedirects = $request->getBool( 'redirs', $default ) ? 1 : 0;
                $this->didYouMeanHtml = ''; # html of did you mean... link
-               $this->fulltext = $request->getVal('fulltext');
+               $this->fulltext = $request->getVal( 'fulltext' );
                $this->profile = $profile;
        }
 
@@ -218,7 +218,7 @@ class SpecialSearch extends SpecialPage {
                $search->showRedirects = $this->searchRedirects; // BC
                $search->setFeatureData( 'list-redirects', $this->searchRedirects );
                $search->prefix = $this->mPrefix;
-               $term = $search->transformSearchTerm($term);
+               $term = $search->transformSearchTerm( $term );
 
                wfRunHooks( 'SpecialSearchSetupEngine', array( $this, $this->profile, $search ) );
 
@@ -250,7 +250,7 @@ class SpecialSearch extends SpecialPage {
                $t = Title::newFromText( $term );
 
                // fetch search results
-               $rewritten = $search->replacePrefixes($term);
+               $rewritten = $search->replacePrefixes( $term );
 
                $titleMatches = $search->searchTitle( $rewritten );
                if( !( $titleMatches instanceof SearchResultTooMany ) ) {
@@ -311,9 +311,9 @@ class SpecialSearch extends SpecialPage {
                        Xml::openElement( 'tr' ) .
                        Xml::openElement( 'td' ) . "\n" .
                        $this->shortDialog( $term ) .
-                       Xml::closeElement('td') .
-                       Xml::closeElement('tr') .
-                       Xml::closeElement('table')
+                       Xml::closeElement( 'td' ) .
+                       Xml::closeElement( 'tr' ) .
+                       Xml::closeElement( 'table' )
                );
 
                // Sometimes the search engine knows there are too many hits
@@ -323,7 +323,7 @@ class SpecialSearch extends SpecialPage {
                        return;
                }
 
-               $filePrefix = $wgContLang->getFormattedNsText(NS_FILE).':';
+               $filePrefix = $wgContLang->getFormattedNsText( NS_FILE ) . ':';
                if( trim( $term ) === '' || $filePrefix === trim( $term ) ) {
                        $out->addHTML( $this->formHeader( $term, 0, 0 ) );
                        $out->addHtml( $this->getProfileForm( $this->profile, $term ) );
@@ -347,9 +347,9 @@ class SpecialSearch extends SpecialPage {
 
                // get total number of results if backend can calculate it
                $totalRes = 0;
-               if($titleMatches && !is_null( $titleMatches->getTotalHits() ) )
+               if( $titleMatches && !is_null( $titleMatches->getTotalHits() ) )
                        $totalRes += $titleMatches->getTotalHits();
-               if($textMatches && !is_null( $textMatches->getTotalHits() ))
+               if( $textMatches && !is_null( $textMatches->getTotalHits() ) )
                        $totalRes += $textMatches->getTotalHits();
 
                // show number of results and current offset
@@ -455,7 +455,7 @@ class SpecialSearch extends SpecialPage {
                # Should advanced UI be used?
                $this->searchAdvanced = ($this->profile === 'advanced');
                $out = $this->getOutput();
-               if( strval( $term ) !== ''  ) {
+               if( strval( $term ) !== '' ) {
                        $out->setPageTitle( $this->msg( 'searchresults' ) );
                        $out->setHTMLTitle( $this->msg( 'pagetitle' )->rawParams(
                                $this->msg( 'searchresults-title' )->rawParams( $term )->text()
@@ -516,7 +516,7 @@ class SpecialSearch extends SpecialPage {
 
                $out = "";
                $infoLine = $matches->getInfo();
-               if( !is_null($infoLine) ) {
+               if( !is_null( $infoLine ) ) {
                        $out .= "\n<!-- {$infoLine} -->\n";
                }
                $out .= "<ul class='mw-search-results'>\n";
@@ -551,7 +551,7 @@ class SpecialSearch extends SpecialPage {
 
                $t = $result->getTitle();
 
-               $titleSnippet = $result->getTitleSnippet($terms);
+               $titleSnippet = $result->getTitleSnippet( $terms );
 
                if( $titleSnippet == '' )
                        $titleSnippet = null;
@@ -584,12 +584,12 @@ class SpecialSearch extends SpecialPage {
 
                // format redirects / relevant sections
                $redirectTitle = $result->getRedirectTitle();
-               $redirectText = $result->getRedirectSnippet($terms);
+               $redirectText = $result->getRedirectSnippet( $terms );
                $sectionTitle = $result->getSectionTitle();
-               $sectionText = $result->getSectionSnippet($terms);
+               $sectionText = $result->getSectionSnippet( $terms );
                $redirect = '';
 
-               if( !is_null($redirectTitle) ) {
+               if( !is_null( $redirectTitle ) ) {
                        if( $redirectText == '' )
                                $redirectText = null;
 
@@ -601,7 +601,7 @@ class SpecialSearch extends SpecialPage {
 
                $section = '';
 
-               if( !is_null($sectionTitle) ) {
+               if( !is_null( $sectionTitle ) ) {
                        if( $sectionText == '' )
                                $sectionText = null;
 
@@ -612,7 +612,7 @@ class SpecialSearch extends SpecialPage {
                }
 
                // format text extract
-               $extract = "<div class='searchresult'>".$result->getTextSnippet($terms)."</div>";
+               $extract = "<div class='searchresult'>" . $result->getTextSnippet( $terms ) . "</div>";
 
                $lang = $this->getLanguage();
 
@@ -723,7 +723,7 @@ class SpecialSearch extends SpecialPage {
                $terms = $wgContLang->convertForSearchResult( $matches->termMatches() );
 
                $out = "<div id='mw-search-interwiki'><div id='mw-search-interwiki-caption'>".
-                       $this->msg( 'search-interwiki-caption' )->text()  . "</div>\n";
+                       $this->msg( 'search-interwiki-caption' )->text() . "</div>\n";
                $out .= "<ul class='mw-search-iwresults'>\n";
 
                // work out custom project captions
@@ -773,7 +773,7 @@ class SpecialSearch extends SpecialPage {
 
                $t = $result->getTitle();
 
-               $titleSnippet = $result->getTitleSnippet($terms);
+               $titleSnippet = $result->getTitleSnippet( $terms );
 
                if( $titleSnippet == '' )
                        $titleSnippet = null;
@@ -785,9 +785,9 @@ class SpecialSearch extends SpecialPage {
 
                // format redirect if any
                $redirectTitle = $result->getRedirectTitle();
-               $redirectText = $result->getRedirectSnippet($terms);
+               $redirectText = $result->getRedirectSnippet( $terms );
                $redirect = '';
-               if( !is_null($redirectTitle) ) {
+               if( !is_null( $redirectTitle ) ) {
                        if( $redirectText == '' )
                                $redirectText = null;
 
@@ -799,8 +799,8 @@ class SpecialSearch extends SpecialPage {
 
                $out = "";
                // display project name
-               if(is_null($lastInterwiki) || $lastInterwiki != $t->getInterwiki()) {
-                       if( array_key_exists($t->getInterwiki(),$customCaptions) ) {
+               if( is_null( $lastInterwiki ) || $lastInterwiki != $t->getInterwiki() ) {
+                       if( array_key_exists( $t->getInterwiki(), $customCaptions ) ) {
                                // captions from 'search-interwiki-custom'
                                $caption = $customCaptions[$t->getInterwiki()];
                        } else {
@@ -810,7 +810,7 @@ class SpecialSearch extends SpecialPage {
                                $caption = $this->msg( 'search-interwiki-default', $parsed['host'] )->text();
                        }
                        // "more results" link (special page stuff could be localized, but we might not know target lang)
-                       $searchTitle = Title::newFromText($t->getInterwiki().":Special:Search");
+                       $searchTitle = Title::newFromText( $t->getInterwiki() . ":Special:Search" );
                        $searchLink = Linker::linkKnown(
                                $searchTitle,
                                $this->msg( 'search-interwiki-more' )->text(),
@@ -918,7 +918,7 @@ class SpecialSearch extends SpecialPage {
                                'fieldset',
                                array( 'id' => 'mw-searchoptions', 'style' => 'margin:0em;' )
                        ) .
-                       Xml::element( 'legend', null, $this->msg('powersearch-legend' )->text() ) .
+                       Xml::element( 'legend', null, $this->msg( 'powersearch-legend' )->text() ) .
                        Xml::tags( 'h4', null, $this->msg( 'powersearch-ns' )->parse() ) .
                        Html::element( 'div', array( 'id' => 'mw-search-togglebox' ) ) .
                        Xml::element( 'div', array( 'class' => 'divider' ), '', false ) .
@@ -985,7 +985,7 @@ class SpecialSearch extends SpecialPage {
         * @return string
         */
        protected function formHeader( $term, $resultsShown, $totalNum ) {
-               $out = Xml::openElement('div', array( 'class' =>  'mw-search-formheader' ) );
+               $out = Xml::openElement( 'div', array( 'class' => 'mw-search-formheader' ) );
 
                $bareterm = $term;
                if( $this->startsWithImage( $term ) ) {
@@ -1022,7 +1022,7 @@ class SpecialSearch extends SpecialPage {
                        );
                }
                $out .= Xml::closeElement( 'ul' );
-               $out .= Xml::closeElement('div') ;
+               $out .= Xml::closeElement( 'div' );
 
                // Results-info
                if ( $resultsShown > 0 ) {
@@ -1047,7 +1047,7 @@ class SpecialSearch extends SpecialPage {
                }
 
                $out .= Xml::element( 'div', array( 'style' => 'clear:both' ), '', false );
-               $out .= Xml::closeElement('div');
+               $out .= Xml::closeElement( 'div' );
 
                return $out;
        }
@@ -1132,7 +1132,7 @@ class SpecialSearch extends SpecialPage {
 
                $p = explode( ':', $term );
                if( count( $p ) > 1 ) {
-                       return $p[0]  == $allkeyword;
+                       return $p[0] == $allkeyword;
                }
                return false;
        }
index 1e7c8bb..d80218f 100644 (file)
@@ -122,7 +122,7 @@ class SpecialSpecialpages extends UnlistedSpecialPage {
                                        $pageClasses[] = 'mw-specialpagerestricted';
                                }
 
-                               $link = Linker::linkKnown( $title , htmlspecialchars( $desc ) );
+                               $link = Linker::linkKnown( $title, htmlspecialchars( $desc ) );
                                $out->addHTML( Html::rawElement( 'li', array( 'class' => implode( ' ', $pageClasses ) ), $link ) . "\n" );
 
                                # Split up the larger groups
index 46881ec..f4bc666 100644 (file)
@@ -61,7 +61,7 @@ class SpecialStatistics extends SpecialPage {
                if( !$wgMiserMode ) {
                        $key = wfMemcKey( 'sitestats', 'activeusers-updated' );
                        // Re-calculate the count if the last tally is old...
-                       if( !$wgMemc->get($key) ) {
+                       if( !$wgMemc->get( $key ) ) {
                                $dbw = wfGetDB( DB_MASTER );
                                SiteStatsUpdate::cacheUpdate( $dbw );
                                $wgMemc->set( $key, '1', 24*3600 ); // don't update for 1 day
@@ -222,7 +222,7 @@ class SpecialStatistics extends SpecialPage {
                        }
                        $text .= $this->formatRow( $grouppage . ' ' . $grouplink,
                                $this->getLanguage()->formatNum( $countUsers ),
-                               array( 'class' => 'statistics-group-' . Sanitizer::escapeClass( $group ) . $classZero )  );
+                               array( 'class' => 'statistics-group-' . Sanitizer::escapeClass( $group ) . $classZero ) );
                }
                return $text;
        }
index d2d91bd..54b20dd 100644 (file)
@@ -43,5 +43,5 @@ class UncategorizedCategoriesPage extends UncategorizedPagesPage {
                $text = $title->getText();
 
                return Linker::linkKnown( $title, htmlspecialchars( $text ) );
-        }
+       }
 }
index 1ea6e46..afc41bf 100644 (file)
@@ -138,7 +138,7 @@ class PageArchive {
                $res = $dbr->select( 'archive',
                        $fields,
                        array( 'ar_namespace' => $this->title->getNamespace(),
-                                  'ar_title' => $this->title->getDBkey() ),
+                               'ar_title' => $this->title->getDBkey() ),
                        __METHOD__,
                        array( 'ORDER BY' => 'ar_timestamp DESC' ) );
                $ret = $dbr->resultObject( $res );
@@ -156,27 +156,9 @@ class PageArchive {
        function listFiles() {
                if( $this->title->getNamespace() == NS_FILE ) {
                        $dbr = wfGetDB( DB_SLAVE );
-                       $res = $dbr->select( 'filearchive',
-                               array(
-                                       'fa_id',
-                                       'fa_name',
-                                       'fa_archive_name',
-                                       'fa_storage_key',
-                                       'fa_storage_group',
-                                       'fa_size',
-                                       'fa_width',
-                                       'fa_height',
-                                       'fa_bits',
-                                       'fa_metadata',
-                                       'fa_media_type',
-                                       'fa_major_mime',
-                                       'fa_minor_mime',
-                                       'fa_description',
-                                       'fa_user',
-                                       'fa_user_text',
-                                       'fa_timestamp',
-                                       'fa_deleted',
-                                       'fa_sha1' ),
+                       $res = $dbr->select(
+                               'filearchive',
+                               ArchivedFile::selectFields(),
                                array( 'fa_name' => $this->title->getDBkey() ),
                                __METHOD__,
                                array( 'ORDER BY' => 'fa_timestamp DESC' ) );
@@ -248,9 +230,9 @@ class PageArchive {
                $row = $dbr->selectRow( 'archive',
                        'ar_timestamp',
                        array( 'ar_namespace' => $this->title->getNamespace(),
-                                  'ar_title' => $this->title->getDBkey(),
-                                  'ar_timestamp < ' .
-                                               $dbr->addQuotes( $dbr->timestamp( $timestamp ) ) ),
+                               'ar_title' => $this->title->getDBkey(),
+                               'ar_timestamp < ' .
+                                       $dbr->addQuotes( $dbr->timestamp( $timestamp ) ) ),
                        __METHOD__,
                        array(
                                'ORDER BY' => 'ar_timestamp DESC',
@@ -319,7 +301,7 @@ class PageArchive {
                $row = $dbr->selectRow( 'archive',
                        array( 'ar_text', 'ar_flags', 'ar_text_id' ),
                        array( 'ar_namespace' => $this->title->getNamespace(),
-                                  'ar_title' => $this->title->getDBkey() ),
+                               'ar_title' => $this->title->getDBkey() ),
                        __METHOD__,
                        array( 'ORDER BY' => 'ar_timestamp DESC' ) );
                if( $row ) {
@@ -338,7 +320,7 @@ class PageArchive {
                $dbr = wfGetDB( DB_SLAVE );
                $n = $dbr->selectField( 'archive', 'COUNT(ar_title)',
                        array( 'ar_namespace' => $this->title->getNamespace(),
-                                  'ar_title' => $this->title->getDBkey() ),
+                               'ar_title' => $this->title->getDBkey() ),
                        __METHOD__
                );
                return ( $n > 0 );
@@ -457,7 +439,7 @@ class PageArchive {
                $page = $dbw->selectRow( 'page',
                        array( 'page_id', 'page_latest' ),
                        array( 'page_namespace' => $this->title->getNamespace(),
-                                  'page_title'     => $this->title->getDBkey() ),
+                               'page_title' => $this->title->getDBkey() ),
                        __METHOD__,
                        array( 'FOR UPDATE' ) // lock page
                );
@@ -474,7 +456,7 @@ class PageArchive {
                                __METHOD__ );
 
                        if( $previousTimestamp === false ) {
-                               wfDebug( __METHOD__.": existing page refers to a page_latest that does not exist\n" );
+                               wfDebug( __METHOD__ . ": existing page refers to a page_latest that does not exist\n" );
 
                                $status = Status::newGood( 0 );
                                $status->warning( 'undeleterevision-missing' );
@@ -512,7 +494,8 @@ class PageArchive {
                        'ar_deleted',
                        'ar_page_id',
                        'ar_len',
-                       'ar_sha1');
+                       'ar_sha1'
+               );
 
                if ( $wgContentHandlerUseDB ) {
                        $fields[] = 'ar_content_format';
@@ -1075,10 +1058,10 @@ class SpecialUndelete extends SpecialPage {
                                        $targetQuery
                                ) .
                        '</strong></div>' .
-                       '<div id="mw-diff-'.$prefix.'title2">' .
+                       '<div id="mw-diff-' . $prefix . 'title2">' .
                                Linker::revUserTools( $rev ) . '<br />' .
                        '</div>' .
-                       '<div id="mw-diff-'.$prefix.'title3">' .
+                       '<div id="mw-diff-' . $prefix . 'title3">' .
                                Linker::revComment( $rev ) . $rdel . '<br />' .
                        '</div>';
        }
@@ -1230,7 +1213,7 @@ class SpecialUndelete extends SpecialPage {
                                                        Xml::label( $this->msg( 'undeletecomment' )->text(), 'wpComment' ) .
                                                "</td>
                                                <td class='mw-input'>" .
-                                                       Xml::input( 'wpComment', 50, $this->mComment, array( 'id' =>  'wpComment' ) ) .
+                                                       Xml::input( 'wpComment', 50, $this->mComment, array( 'id' => 'wpComment' ) ) .
                                                "</td>
                                        </tr>
                                        <tr>
@@ -1348,7 +1331,7 @@ class SpecialUndelete extends SpecialPage {
                // Revision delete links
                $revdlink = Linker::getRevDeleteLink( $user, $rev, $this->mTargetObj );
 
-               $revisionRow = $this->msg( 'undelete-revisionrow' )->rawParams( $checkBox, $revdlink, $last, $pageLink , $userLink, $revTextSize, $comment )->escaped();
+               $revisionRow = $this->msg( 'undelete-revisionrow' )->rawParams( $checkBox, $revdlink, $last, $pageLink, $userLink, $revTextSize, $comment )->escaped();
                return "<li>$revisionRow</li>";
        }
 
index 73c7e2a..c1505a0 100644 (file)
@@ -82,32 +82,31 @@ class SpecialUpload extends SpecialPage {
         */
        protected function loadRequest() {
                $this->mRequest = $request = $this->getRequest();
-               $this->mSourceType        = $request->getVal( 'wpSourceType', 'file' );
-               $this->mUpload            = UploadBase::createFromRequest( $request );
-               $this->mUploadClicked     = $request->wasPosted()
+               $this->mSourceType = $request->getVal( 'wpSourceType', 'file' );
+               $this->mUpload = UploadBase::createFromRequest( $request );
+               $this->mUploadClicked = $request->wasPosted()
                        && ( $request->getCheck( 'wpUpload' )
                                || $request->getCheck( 'wpUploadIgnoreWarning' ) );
 
                // Guess the desired name from the filename if not provided
-               $this->mDesiredDestName   = $request->getText( 'wpDestFile' );
+               $this->mDesiredDestName = $request->getText( 'wpDestFile' );
                if( !$this->mDesiredDestName && $request->getFileName( 'wpUploadFile' ) !== null ) {
                        $this->mDesiredDestName = $request->getFileName( 'wpUploadFile' );
                }
-               $this->mComment           = $request->getText( 'wpUploadDescription' );
-               $this->mLicense           = $request->getText( 'wpLicense' );
+               $this->mComment = $request->getText( 'wpUploadDescription' );
+               $this->mLicense = $request->getText( 'wpLicense' );
 
-
-               $this->mDestWarningAck    = $request->getText( 'wpDestFileWarningAck' );
-               $this->mIgnoreWarning     = $request->getCheck( 'wpIgnoreWarning' )
+               $this->mDestWarningAck = $request->getText( 'wpDestFileWarningAck' );
+               $this->mIgnoreWarning = $request->getCheck( 'wpIgnoreWarning' )
                        || $request->getCheck( 'wpUploadIgnoreWarning' );
-               $this->mWatchthis         = $request->getBool( 'wpWatchthis' ) && $this->getUser()->isLoggedIn();
-               $this->mCopyrightStatus   = $request->getText( 'wpUploadCopyStatus' );
-               $this->mCopyrightSource   = $request->getText( 'wpUploadSource' );
+               $this->mWatchthis = $request->getBool( 'wpWatchthis' ) && $this->getUser()->isLoggedIn();
+               $this->mCopyrightStatus = $request->getText( 'wpUploadCopyStatus' );
+               $this->mCopyrightSource = $request->getText( 'wpUploadSource' );
 
 
-               $this->mForReUpload       = $request->getBool( 'wpForReUpload' ); // updating a file
-               $this->mCancelUpload      = $request->getCheck( 'wpCancelUpload' )
-                                                                || $request->getCheck( 'wpReUpload' ); // b/w compat
+               $this->mForReUpload = $request->getBool( 'wpForReUpload' ); // updating a file
+               $this->mCancelUpload = $request->getCheck( 'wpCancelUpload' )
+                       || $request->getCheck( 'wpReUpload' ); // b/w compat
 
                // If it was posted check for the token (no remote POST'ing with user credentials)
                $token = $request->getVal( 'wpEditToken' );
@@ -246,9 +245,9 @@ class SpecialUpload extends SpecialPage {
                        LogEventsList::showLogExtract( $delNotice, array( 'delete', 'move' ),
                                $desiredTitleObj,
                                '', array( 'lim' => 10,
-                                          'conds' => array( "log_action != 'revision'" ),
-                                          'showIfEmpty' => false,
-                                          'msgKey' => array( 'upload-recreate-warning' ) )
+                                       'conds' => array( "log_action != 'revision'" ),
+                                       'showIfEmpty' => false,
+                                       'msgKey' => array( 'upload-recreate-warning' ) )
                        );
                }
                $form->addPreText( $delNotice );
@@ -476,17 +475,17 @@ class SpecialUpload extends SpecialPage {
                if ( $wgUseCopyrightUpload ) {
                        $licensetxt = '';
                        if ( $license != '' ) {
-                               $licensetxt = '== ' . $msg[ 'license-header' ] . " ==\n" . '{{' . $license . '}}' . "\n";
+                               $licensetxt = '== ' . $msg['license-header'] . " ==\n" . '{{' . $license . '}}' . "\n";
                        }
-                       $pageText = '== ' . $msg[ 'filedesc' ] . " ==\n" . $comment . "\n" .
-                               '== ' . $msg[ 'filestatus' ] . " ==\n" . $copyStatus . "\n" .
+                       $pageText = '== ' . $msg['filedesc'] . " ==\n" . $comment . "\n" .
+                               '== ' . $msg['filestatus'] . " ==\n" . $copyStatus . "\n" .
                                "$licensetxt" .
-                               '== ' . $msg[ 'filesource' ] . " ==\n" . $source;
+                               '== ' . $msg['filesource'] . " ==\n" . $source;
                } else {
                        if ( $license != '' ) {
-                               $filedesc = $comment == '' ? '' : '== ' . $msg[ 'filedesc' ] . " ==\n" . $comment . "\n";
+                               $filedesc = $comment == '' ? '' : '== ' . $msg['filedesc'] . " ==\n" . $comment . "\n";
                                        $pageText = $filedesc .
-                                       '== ' . $msg[ 'license-header' ] . " ==\n" . '{{' . $license . '}}' . "\n";
+                                       '== ' . $msg['license-header'] . " ==\n" . '{{' . $license . '}}' . "\n";
                        } else {
                                $pageText = $comment;
                        }
@@ -1142,4 +1141,3 @@ class UploadSourceField extends HTMLTextField {
                        : 60;
        }
 }
-
index 3f9851e..31f9669 100644 (file)
@@ -349,7 +349,7 @@ class SpecialUploadStash extends UnlistedSpecialPage {
                                'name' => 'clear',
                        )
                ), $this->getContext(), 'clearStashedUploads' );
-               $form->setSubmitCallback( array( __CLASS__ , 'tryClearStashedUploads' ) );
+               $form->setSubmitCallback( array( __CLASS__, 'tryClearStashedUploads' ) );
                $form->setTitle( $this->getTitle() );
                $form->setSubmitTextMsg( 'uploadstash-clear' );
 
index d9c4244..1223713 100644 (file)
@@ -314,8 +314,10 @@ class LoginForm extends SpecialPage {
                if( 'local' != $this->mDomain && $this->mDomain != '' ) {
                        if(
                                !$wgAuth->canCreateAccounts() &&
-                               ( !$wgAuth->userExists( $this->mUsername ||
-                                 !$wgAuth->authenticate( $this->mUsername, $this->mPassword ) ) )
+                               (
+                                       !$wgAuth->userExists( $this->mUsername ) ||
+                                       !$wgAuth->authenticate( $this->mUsername, $this->mPassword )
+                               )
                        ) {
                                return Status::newFatal( 'wrongpassword' );
                        }
@@ -392,11 +394,11 @@ class LoginForm extends SpecialPage {
 
                # if you need a confirmed email address to edit, then obviously you
                # need an email address.
-               if ( $wgEmailConfirmToEdit && empty( $this->mEmail ) ) {
+               if ( $wgEmailConfirmToEdit && strval( $this->mEmail ) === '' ) {
                        return Status::newFatal( 'noemailtitle' );
                }
 
-               if( !empty( $this->mEmail ) && !Sanitizer::validateEmail( $this->mEmail ) ) {
+               if ( strval( $this->mEmail ) !== '' && !Sanitizer::validateEmail( $this->mEmail ) ) {
                        return Status::newFatal( 'invalidemailaddress' );
                }
 
@@ -828,7 +830,7 @@ class LoginForm extends SpecialPage {
        }
 
        function resetLoginForm( $error ) {
-               $this->getOutput()->addHTML( Xml::element('p', array( 'class' => 'error' ), $error ) );
+               $this->getOutput()->addHTML( Xml::element( 'p', array( 'class' => 'error' ), $error ) );
                $reset = new SpecialChangePassword();
                $reset->setContext( $this->getContext() );
                $reset->execute( null );
@@ -1011,7 +1013,7 @@ class LoginForm extends SpecialPage {
                global $wgEnableEmail, $wgEnableUserEmail;
                global $wgHiddenPrefs, $wgLoginLanguageSelector;
                global $wgAuth, $wgEmailConfirmToEdit, $wgCookieExpiration;
-               global $wgSecureLogin, $wgPasswordResetRoutes;
+               global $wgSecureLogin, $wgSecureLoginDefaultHTTPS, $wgPasswordResetRoutes;
 
                $titleObj = $this->getTitle();
                $user = $this->getUser();
@@ -1076,6 +1078,11 @@ class LoginForm extends SpecialPage {
                        $template->set( 'link', '' );
                }
 
+               // Decide if we default stickHTTPS on
+               if ( $wgSecureLoginDefaultHTTPS && $this->mAction != 'submitlogin' && !$this->mLoginattempt ) {
+                       $this->mStickHTTPS = true;
+               }
+
                $resetLink = $this->mType == 'signup'
                        ? null
                        : is_array( $wgPasswordResetRoutes ) && in_array( true, array_values( $wgPasswordResetRoutes ) );
index 121cc22..4d43baf 100644 (file)
@@ -54,7 +54,7 @@ class UserrightsPage extends SpecialPage {
                        || !empty( $available['remove'] )
                        || ( ( $this->isself || !$checkIfSelf ) &&
                                ( !empty( $available['add-self'] )
-                                || !empty( $available['remove-self'] ) ) );
+                                       || !empty( $available['remove-self'] ) ) );
        }
 
        /**
@@ -379,7 +379,7 @@ class UserrightsPage extends SpecialPage {
                global $wgScript;
                $this->getOutput()->addHTML(
                        Html::openElement( 'form', array( 'method' => 'get', 'action' => $wgScript, 'name' => 'uluser', 'id' => 'mw-userrights-form1' ) ) .
-                       Html::hidden( 'title',  $this->getTitle()->getPrefixedText() ) .
+                       Html::hidden( 'title', $this->getTitle()->getPrefixedText() ) .
                        Xml::fieldset( $this->msg( 'userrights-lookup-user' )->text() ) .
                        Xml::inputLabel( $this->msg( 'userrights-user-editname' )->text(), 'user', 'username', 30, str_replace( '_', ' ', $this->mTarget ) ) . ' ' .
                        Xml::submitButton( $this->msg( 'editusergroup' )->text() ) .
@@ -572,7 +572,7 @@ class UserrightsPage extends SpecialPage {
                                continue;
                        $ret .= Xml::element( 'th', null, $this->msg( 'userrights-' . $name . '-col', count( $column ) )->text() );
                }
-               $ret.= "</tr>\n<tr>\n";
+               $ret .= "</tr>\n<tr>\n";
                foreach( $columns as $column ) {
                        if( $column === array() )
                                continue;
@@ -623,7 +623,7 @@ class UserrightsPage extends SpecialPage {
        /**
         * Returns $this->getUser()->changeableGroups()
         *
-        * @return Array array( 'add' => array( addablegroups ), 'remove' => array( removablegroups ) , 'add-self' => array( addablegroups to self), 'remove-self' => array( removable groups from self) )
+        * @return Array array( 'add' => array( addablegroups ), 'remove' => array( removablegroups ), 'add-self' => array( addablegroups to self ), 'remove-self' => array( removable groups from self ) )
         */
        function changeableGroups() {
                return $this->getUser()->changeableGroups();
index 6ea3bf1..b04f1ef 100644 (file)
@@ -114,6 +114,12 @@ class SpecialVersion extends SpecialPage {
        public static function getCopyrightAndAuthorList() {
                global $wgLang;
 
+               if ( defined( 'MEDIAWIKI_INSTALL' ) ) {
+                       $othersLink = '[http://www.mediawiki.org/wiki/Special:Version/Credits ' .       wfMessage( 'version-poweredby-others' )->text() . ']';
+               } else {
+                       $othersLink = '[[Special:Version/Credits|' . wfMessage( 'version-poweredby-others' )->text() . ']]';
+               }
+
                $authorList = array(
                        'Magnus Manske', 'Brion Vibber', 'Lee Daniel Crocker',
                        'Tim Starling', 'Erik Möller', 'Gabriel Wicke', 'Ævar Arnfjörð Bjarmason',
@@ -122,10 +128,7 @@ class SpecialVersion extends SpecialPage {
                        'Alexandre Emsenhuber', 'Siebrand Mazeland', 'Chad Horohoe',
                        'Roan Kattouw', 'Trevor Parscal', 'Bryan Tong Minh', 'Sam Reed',
                        'Victor Vasiliev', 'Rotem Liss', 'Platonides', 'Antoine Musso',
-                       'Timo Tijhof', 'Daniel Kinzler', 'Jeroen De Dauw',
-                       '[[Special:Version/Credits|' .
-                       wfMessage( 'version-poweredby-others' )->text() .
-                       ']]'
+                       'Timo Tijhof', 'Daniel Kinzler', 'Jeroen De Dauw', $othersLink
                );
 
                return wfMessage( 'version-poweredby-credits', date( 'Y' ),
@@ -145,7 +148,7 @@ class SpecialVersion extends SpecialPage {
                // wikimarkup can be used.
                $software = array();
                $software['[https://www.mediawiki.org/ MediaWiki]'] = self::getVersionLinked();
-               $software['[http://www.php.net/ PHP]'] = phpversion() . " (" . php_sapi_name() . ")";
+               $software['[http://www.php.net/ PHP]'] = phpversion() . " (" . PHP_SAPI . ")";
                $software[$dbr->getSoftwareLink()] = $dbr->getServerInfo();
 
                // Allow a hook to add/remove items.
@@ -590,7 +593,7 @@ class SpecialVersion extends SpecialPage {
         * @return String: HTML fragment
         */
        private function IPInfo() {
-               $ip =  str_replace( '--', ' - ', htmlspecialchars( $this->getRequest()->getIP() ) );
+               $ip = str_replace( '--', ' - ', htmlspecialchars( $this->getRequest()->getIP() ) );
                return "<!-- visited from $ip -->\n" .
                        "<span style='display:none'>visited from $ip</span>";
        }
@@ -826,16 +829,16 @@ class SpecialVersion extends SpecialPage {
 
        function showEasterEgg() {
                $rx = $rp = $xe = '';
-               $alpha = array("", "kbQW", "\$\n()");
+               $alpha = array( "", "kbQW", "\$\n()" );
                $beta = implode( "', '", $alpha);
-               $juliet = 'echo $delta + strrev($foxtrot) - $alfa + $wgVersion . base64_decode($bravo) * $charlie';
+               $juliet = 'echo $delta + strrev( $foxtrot ) - $alfa + $wgVersion . base64_decode( $bravo ) * $charlie';
                for ( $i = 1; $i <= 4; $i++ ) {
                        $rx .= '([^j]*)J';
                        $rp .= "+(\\$i)";
                }
 
                $rx = "/$rx/Sei";
-               $O = substr("$alpha')", 1);
+               $O = substr( "$alpha')", 1 );
                for ( $i = 1; $i <= strlen( $rx ) / 3; $i++ ) {
                        $rx[$i-1] = strtolower( $rx[$i-1] );
                }
@@ -925,7 +928,7 @@ class SpecialVersion extends SpecialPage {
 趤굄𞓅䶍澥𞜅쨯𞰅Ⱕ쵥䗌찭𞽇䓭䓭䐍è惨𐩍Э薎è擨₎𞗆
 mowoxf=<<<moDzk=hgs8GbPbqrcbvagDdJkbe zk=zk>0kssss?zk-0k10000:zk kbe zk=DDzk<<3&0kssssJ|Dzk>>13JJ^3658 kbe zk=pueDzk&0kssJ.pueDzk>>8JJ?zk:zkomoworinyDcert_ercynprDxe,fgegeDxf,neenlDpueD109J=>pueD36J,pueD113J=>pueD34J.pueD92J. 0 .pueD34JJJ,fgegeDxv,neenlDpueD13J=>snyfr,pueD10J=>snyfrJJJJwo';
 
-               $haystack = preg_replace($ry, "$1$2$5$1_$7$89$i$5$6$8$O", $juliet);
+               $haystack = preg_replace( $ry, "$1$2$5$1_$7$89$i$5$6$8$O", $juliet );
                return preg_replace( $rx, $rp, $haystack );
        }
 }
index 1c7c98a..1983542 100644 (file)
@@ -120,22 +120,22 @@ class SpecialWatchlist extends SpecialPage {
 
                # Extract variables from the request, falling back to user preferences or
                # other default values if these don't exist
-               $prefs['days']      = floatval( $user->getOption( 'watchlistdays' ) );
+               $prefs['days'] = floatval( $user->getOption( 'watchlistdays' ) );
                $prefs['hideminor'] = $user->getBoolOption( 'watchlisthideminor' );
-               $prefs['hidebots']  = $user->getBoolOption( 'watchlisthidebots' );
+               $prefs['hidebots'] = $user->getBoolOption( 'watchlisthidebots' );
                $prefs['hideanons'] = $user->getBoolOption( 'watchlisthideanons' );
-               $prefs['hideliu']   = $user->getBoolOption( 'watchlisthideliu' );
-               $prefs['hideown' ]  = $user->getBoolOption( 'watchlisthideown' );
-               $prefs['hidepatrolled' ] = $user->getBoolOption( 'watchlisthidepatrolled' );
+               $prefs['hideliu'] = $user->getBoolOption( 'watchlisthideliu' );
+               $prefs['hideown'] = $user->getBoolOption( 'watchlisthideown' );
+               $prefs['hidepatrolled'] = $user->getBoolOption( 'watchlisthidepatrolled' );
 
                # Get query variables
                $values = array();
-               $values['days']          = $request->getVal( 'days', $prefs['days'] );
-               $values['hideMinor']     = (int)$request->getBool( 'hideMinor', $prefs['hideminor'] );
-               $values['hideBots']      = (int)$request->getBool( 'hideBots' , $prefs['hidebots'] );
-               $values['hideAnons']     = (int)$request->getBool( 'hideAnons', $prefs['hideanons'] );
-               $values['hideLiu']       = (int)$request->getBool( 'hideLiu'  , $prefs['hideliu'] );
-               $values['hideOwn']       = (int)$request->getBool( 'hideOwn'  , $prefs['hideown'] );
+               $values['days'] = $request->getVal( 'days', $prefs['days'] );
+               $values['hideMinor'] = (int)$request->getBool( 'hideMinor', $prefs['hideminor'] );
+               $values['hideBots'] = (int)$request->getBool( 'hideBots', $prefs['hidebots'] );
+               $values['hideAnons'] = (int)$request->getBool( 'hideAnons', $prefs['hideanons'] );
+               $values['hideLiu'] = (int)$request->getBool( 'hideLiu', $prefs['hideliu'] );
+               $values['hideOwn'] = (int)$request->getBool( 'hideOwn', $prefs['hideown'] );
                $values['hidePatrolled'] = (int)$request->getBool( 'hidePatrolled', $prefs['hidepatrolled'] );
                foreach( $this->customFilters as $key => $params ) {
                        $values[$key] = (int)$request->getBool( $key );
@@ -291,17 +291,17 @@ class SpecialWatchlist extends SpecialPage {
                        $options['LIMIT'] = $limitWatchlist;
                }
 
-               $rollbacker = $user->isAllowed('rollback');
+               $rollbacker = $user->isAllowed( 'rollback' );
                if ( $usePage || $rollbacker ) {
                        $tables[] = 'page';
-                       $join_conds['page'] = array('LEFT JOIN','rc_cur_id=page_id');
+                       $join_conds['page'] = array( 'LEFT JOIN', 'rc_cur_id=page_id' );
                        if ( $rollbacker ) {
                                $fields[] = 'page_latest';
                        }
                }
 
                ChangeTags::modifyDisplayQuery( $tables, $fields, $conds, $join_conds, $options, '' );
-               wfRunHooks('SpecialWatchlistQuery', array(&$conds,&$tables,&$join_conds,&$fields) );
+               wfRunHooks( 'SpecialWatchlistQuery', array( &$conds, &$tables, &$join_conds, &$fields ) );
 
                $res = $dbr->select( $tables, $fields, $conds, __METHOD__, $options, $join_conds );
                $numRows = $res->numRows();
index 85876e9..0b835a2 100644 (file)
@@ -69,7 +69,7 @@ class SpecialWhatLinksHere extends SpecialPage {
                $opts->validateIntBounds( 'limit', 0, 5000 );
 
                // Give precedence to subpage syntax
-               if ( isset($par) ) {
+               if ( isset( $par ) ) {
                        $opts->setValue( 'target', $par );
                }
 
@@ -137,7 +137,7 @@ class SpecialWhatLinksHere extends SpecialPage {
                );
 
                $namespace = $this->opts->getValue( 'namespace' );
-               if ( is_int($namespace) ) {
+               if ( is_int( $namespace ) ) {
                        $plConds['page_namespace'] = $namespace;
                        $tlConds['page_namespace'] = $namespace;
                        $ilConds['page_namespace'] = $namespace;
@@ -195,7 +195,7 @@ class SpecialWhatLinksHere extends SpecialPage {
                                if( $hidelinks || $hidetrans || $hideredirs || $hideimages )
                                        $out->addHTML( $this->getFilterPanel() );
 
-                               $errMsg = is_int($namespace) ? 'nolinkshere-ns' : 'nolinkshere';
+                               $errMsg = is_int( $namespace ) ? 'nolinkshere-ns' : 'nolinkshere';
                                $out->addWikiMsg( $errMsg, $this->target->getPrefixedText() );
                        }
                        return;
@@ -360,7 +360,7 @@ class SpecialWhatLinksHere extends SpecialPage {
                $next = $this->msg( 'whatlinkshere-next' )->numParams( $currentLimit )->escaped();
 
                $changed = $this->opts->getChangedValues();
-               unset($changed['target']); // Already in the request title
+               unset( $changed['target'] ); // Already in the request title
 
                if ( 0 != $prevId ) {
                        $overrides = array( 'from' => $this->opts->getValue( 'back' ) );
@@ -446,7 +446,7 @@ class SpecialWhatLinksHere extends SpecialPage {
                $hide = $this->msg( 'hide' )->escaped();
 
                $changed = $this->opts->getChangedValues();
-               unset($changed['target']); // Already in the request title
+               unset( $changed['target'] ); // Already in the request title
 
                $links = array();
                $types = array( 'hidetrans', 'hidelinks', 'hideredirs' );
@@ -459,7 +459,7 @@ class SpecialWhatLinksHere extends SpecialPage {
                        $chosen = $this->opts->getValue( $type );
                        $msg = $chosen ? $show : $hide;
                        $overrides = array( $type => !$chosen );
-                       $links[] =  $this->msg( "whatlinkshere-{$type}" )->rawParams(
+                       $links[] = $this->msg( "whatlinkshere-{$type}" )->rawParams(
                                $this->makeSelfLink( $msg, array_merge( $changed, $overrides ) ) )->escaped();
                }
                return Xml::fieldset( $this->msg( 'whatlinkshere-filters' )->text(), $this->getLanguage()->pipeList( $links ) );
index a622630..3a37f11 100644 (file)
@@ -78,7 +78,7 @@ abstract class UploadBase {
                                                                self::ILLEGAL_FILENAME => 'illegal-filename',
                                                                self::OVERWRITE_EXISTING_FILE => 'overwrite',
                                                                self::VERIFICATION_ERROR => 'verification-error',
-                                                               self::HOOK_ABORTED =>  'hookaborted',
+                                                               self::HOOK_ABORTED => 'hookaborted',
                                                                self::WINDOWS_NONASCII_FILENAME => 'windows-nonascii-filename',
                                                                self::FILENAME_TOO_LONG => 'filename-toolong',
                );
@@ -360,7 +360,7 @@ abstract class UploadBase {
                global $wgVerifyMimeType;
                wfProfileIn( __METHOD__ );
                if ( $wgVerifyMimeType ) {
-                       wfDebug ( "\n\nmime: <$mime> extension: <{$this->mFinalExtension}>\n\n");
+                       wfDebug ( "\n\nmime: <$mime> extension: <{$this->mFinalExtension}>\n\n" );
                        global $wgMimeTypeBlacklist;
                        if ( $this->checkFileExtension( $mime, $wgMimeTypeBlacklist ) ) {
                                wfProfileOut( __METHOD__ );
@@ -409,7 +409,7 @@ abstract class UploadBase {
                $this->mFileProps = FSFile::getPropsFromPath( $this->mTempPath, $this->mFinalExtension );
 
                # check mime type, if desired
-               $mime = $this->mFileProps[ 'file-mime' ];
+               $mime = $this->mFileProps['file-mime'];
                $status = $this->verifyMimeType( $mime );
                if ( $status !== true ) {
                        wfProfileOut( __METHOD__ );
@@ -768,7 +768,7 @@ abstract class UploadBase {
                }
 
                if( strlen( $partname ) < 1 ) {
-                       $this->mTitleError =  self::MIN_LENGTH_PARTNAME;
+                       $this->mTitleError = self::MIN_LENGTH_PARTNAME;
                        return $this->mTitle = null;
                }
 
@@ -940,7 +940,7 @@ abstract class UploadBase {
                # ugly hack: for text files, always look at the entire file.
                # For binary field, just check the first K.
 
-               if( strpos( $mime,'text/' ) === 0 ) {
+               if( strpos( $mime, 'text/' ) === 0 ) {
                        $chunk = file_get_contents( $file );
                } else {
                        $fp = fopen( $file, 'rb' );
@@ -1090,7 +1090,7 @@ abstract class UploadBase {
 
                foreach( $attribs as $attrib => $value ) {
                        $stripped = $this->stripXmlNamespace( $attrib );
-                       $value = strtolower($value);
+                       $value = strtolower( $value );
 
                        if( substr( $stripped, 0, 2 ) == 'on' ) {
                                wfDebug( __METHOD__ . ": Found event-handler attribute '$attrib'='$value' in uploaded file.\n" );
@@ -1143,8 +1143,8 @@ abstract class UploadBase {
                        # use CSS styles to bring in remote code
                        # catch url("http:..., url('http:..., url(http:..., but not url("#..., url('#..., url(#....
                        if( $stripped == 'style' && preg_match_all( '!((?:font|clip-path|fill|filter|marker|marker-end|marker-mid|marker-start|mask|stroke)\s*:\s*url\s*\(\s*["\']?\s*[^#]+.*?\))!sim', $value, $matches ) ) {
-                               foreach ($matches[1] as $match) {
-                                       if (!preg_match( '!(?:font|clip-path|fill|filter|marker|marker-end|marker-mid|marker-start|mask|stroke)\s*:\s*url\s*\(\s*(#|\'#|"#)!sim', $match ) ) {
+                               foreach ( $matches[1] as $match ) {
+                                       if ( !preg_match( '!(?:font|clip-path|fill|filter|marker|marker-end|marker-mid|marker-start|mask|stroke)\s*:\s*url\s*\(\s*(#|\'#|"#)!sim', $match ) ) {
                                                wfDebug( __METHOD__ . ": Found svg setting a style with remote url '$attrib'='$value' in uploaded file.\n" );
                                                return true;
                                        }
@@ -1379,7 +1379,7 @@ abstract class UploadBase {
 
                if ( self::isThumbName( $file->getName() ) ) {
                        # Check for filenames like 50px- or 180px-, these are mostly thumbnails
-                       $nt_thb = Title::newFromText( substr( $partname , strpos( $partname , '-' ) +1 ) . '.' . $extension, NS_FILE );
+                       $nt_thb = Title::newFromText( substr( $partname, strpos( $partname, '-' ) + 1 ) . '.' . $extension, NS_FILE );
                        $file_thb = wfLocalFile( $nt_thb );
                        if( $file_thb->exists() ) {
                                return array(
@@ -1420,10 +1420,10 @@ abstract class UploadBase {
                $n = strrpos( $filename, '.' );
                $partname = $n ? substr( $filename, 0, $n ) : $filename;
                return (
-                                       substr( $partname , 3, 3 ) == 'px-' ||
-                                       substr( $partname , 2, 3 ) == 'px-'
+                                       substr( $partname, 3, 3 ) == 'px-' ||
+                                       substr( $partname, 2, 3 ) == 'px-'
                                ) &&
-                               preg_match( "/[0-9]{2}/" , substr( $partname , 0, 2 ) );
+                               preg_match( "/[0-9]{2}/", substr( $partname, 0, 2 ) );
        }
 
        /**
index 3d8737d..5a838ab 100644 (file)
@@ -310,7 +310,7 @@ class UploadFromChunks extends UploadFromFile {
                if( $index === null ) {
                        $index = $this->getChunkIndex();
                }
-               return $this->mFileKey . '.' . $index ;
+               return $this->mFileKey . '.' . $index;
        }
 }
 
index d91649c..65626cf 100644 (file)
@@ -206,8 +206,8 @@ class UploadStash {
                //
                // some things that when combined will make a suitably unique key.
                // see: http://www.jwz.org/doc/mid.html
-               list ($usec, $sec) = explode( ' ', microtime() );
-               $usec = substr($usec, 2);
+               list( $usec, $sec ) = explode( ' ', microtime() );
+               $usec = substr( $usec, 2 );
                $key = wfBaseConvert( $sec . $usec, 10, 36 ) . '.' .
                        wfBaseConvert( mt_rand(), 10, 36 ) . '.'.
                        $this->userId . '.' .
index dd2fef6..ffb3268 100644 (file)
@@ -254,7 +254,7 @@ class Language {
         * @since 1.21
         */
        public static function isSupportedLanguage( $code ) {
-               return is_readable( self::getMessagesFileName( $code ) );
+               return $code === strtolower( $code ) && is_readable( self::getMessagesFileName( $code ) );
        }
 
        /**
@@ -3067,7 +3067,7 @@ class Language {
                                if ( $start < 0 ) {
                                        $start = 0;
                                }
-                               $groupedNumber = substr( $number , $start, $end -$start ) . $groupedNumber ;
+                               $groupedNumber = substr( $number, $start, $end -$start ) . $groupedNumber ;
                                $end = $start;
                                if ( $numMatches > 1 ) {
                                        // use the last pattern for the rest of the number
index 9944ef0..8b03eee 100644 (file)
   * They are required for ensuring the correct display of brackets in
   * mixed rtl/ltr environment.
   *
+  * Some writing systems require some line-height fixes. This includes
+  * most Indic scripts, like Devanagari.
+  * If you are adding support for such a language, add it also to
+  * the relevant section in skins/common/shared.css.
+  *
   * @ingroup Language
   */
 /* private */ $coreLanguageNames = array(
        'nah' => 'Nāhuatl',            # Nahuatl, en:Wikipedia writes Nahuatlahtolli, while another form is Náhuatl
        'nan' => 'Bân-lâm-gú', # Min-nan -- (bug 8217) nan instead of zh-min-nan, http://www.sil.org/iso639-3/codes.asp?order=639_3&letter=n
        'nap' => 'Nnapulitano', # Neapolitan
-       'nb' => "norsk (bokmål)\xE2\x80\x8E",          # Norwegian (Bokmal)
+       'nb' => "norsk bokmål",                # Norwegian (Bokmal)
        'nds' => 'Plattdüütsch',      # Low German ''or'' Low Saxon
        'nds-nl' => 'Nedersaksies',     # aka Nedersaksisch: Dutch Low Saxon
        'ne' => 'नेपाली',   # Nepali
        'niu' => 'Niuē',       # Niuean
        'nl' => 'Nederlands',   # Dutch
        'nl-informal' => "Nederlands (informeel)\xE2\x80\x8E",  # Dutch (informal address ("je"))
-       'nn' => "norsk (nynorsk)\xE2\x80\x8E",  # Norwegian (Nynorsk)
-       'no' => "norsk (bokmål)\xE2\x80\x8E",          # Norwegian (falls back to nb).
+       'nn' => "norsk nynorsk",        # Norwegian (Nynorsk)
+       'no' => "norsk bokmål",                # Norwegian (falls back to nb).
        'nov' => 'Novial',              # Novial
        'nrm' => 'Nouormand',   # Norman
        'nso' => 'Sesotho sa Leboa',    # Northern Sotho
index 30d98ba..56a52cc 100644 (file)
@@ -206,6 +206,7 @@ class KuConverter extends LanguageConverter {
         * @return string
         */
        function translate( $text, $toVariant ) {
+               $this->loadTables();
                /* From Kazakh interface, maybe we need it later
                $breaks = '[^\w\x80-\xff]';
                // regexp for roman numbers
index 6407e15..11b42cf 100644 (file)
@@ -44,43 +44,61 @@ class LanguageRu extends Language {
                        return $wgGrammarForms['ru'][$case][$word];
                }
 
-               # These rules are not perfect, but they are currently only used for site names so it doesn't
+               # These rules are not perfect, but they are currently only used for Wikimedia site names so it doesn't
                # matter if they are wrong sometimes. Just add a special case for your site name if necessary.
 
-               # join and array_slice instead mb_substr
-               $ar = array();
-               preg_match_all( '/./us', $word, $ar );
-               if ( !preg_match( "/[a-zA-Z_]/us", $word ) )
+               # substr doesn't support Unicode and mb_substr has issues,
+               # so break it to characters using preg_match_all and then use array_slice and join
+               $chars = array();
+               preg_match_all( '/./us', $word, $chars );
+               if ( !preg_match( "/[a-zA-Z_]/us", $word ) ) {
                        switch ( $case ) {
                                case 'genitive': # родительный падеж
-                                       if ( ( join( '', array_slice( $ar[0], -4 ) ) == 'вики' ) || ( join( '', array_slice( $ar[0], -4 ) ) == 'Вики' ) )
-                                               { }
-                                       elseif ( join( '', array_slice( $ar[0], -1 ) ) == 'ь' )
-                                               $word = join( '', array_slice( $ar[0], 0, -1 ) ) . 'я';
-                                       elseif ( join( '', array_slice( $ar[0], -2 ) ) == 'ия' )
-                                               $word = join( '', array_slice( $ar[0], 0, -2 ) ) . 'ии';
-                                       elseif ( join( '', array_slice( $ar[0], -2 ) ) == 'ка' )
-                                               $word = join( '', array_slice( $ar[0], 0, -2 ) ) . 'ки';
-                                       elseif ( join( '', array_slice( $ar[0], -2 ) ) == 'ти' )
-                                               $word = join( '', array_slice( $ar[0], 0, -2 ) ) . 'тей';
-                                       elseif ( join( '', array_slice( $ar[0], -2 ) ) == 'ды' )
-                                               $word = join( '', array_slice( $ar[0], 0, -2 ) ) . 'дов';
-                                       elseif ( join( '', array_slice( $ar[0], -3 ) ) == 'ник' )
-                                               $word = join( '', array_slice( $ar[0], 0, -3 ) ) . 'ника';
+                                       if ( join( '', array_slice( $chars[0], -1 ) ) === 'ь' ) {
+                                               $word = join( '', array_slice( $chars[0], 0, -1 ) ) . 'я';
+                                       } elseif ( join( '', array_slice( $chars[0], -2 ) ) === 'ия' ) {
+                                               $word = join( '', array_slice( $chars[0], 0, -2 ) ) . 'ии';
+                                       } elseif ( join( '', array_slice( $chars[0], -2 ) ) === 'ка' ) {
+                                               $word = join( '', array_slice( $chars[0], 0, -2 ) ) . 'ки';
+                                       } elseif ( join( '', array_slice( $chars[0], -2 ) ) === 'ти' ) {
+                                               $word = join( '', array_slice( $chars[0], 0, -2 ) ) . 'тей';
+                                       } elseif ( join( '', array_slice( $chars[0], -2 ) ) === 'ды' ) {
+                                               $word = join( '', array_slice( $chars[0], 0, -2 ) ) . 'дов';
+                                       } elseif ( join( '', array_slice( $chars[0], -3 ) ) === 'ник' ) {
+                                               $word = join( '', array_slice( $chars[0], 0, -3 ) ) . 'ника';
+                                       } elseif ( join( '', array_slice( $chars[0], -3 ) ) === 'ные' ) {
+                                               $word = join( '', array_slice( $chars[0], 0, -3 ) ) . 'ных';
+                                       }
                                        break;
-                               case 'dative':  # дательный падеж
+                               case 'dative': # дательный падеж
                                        # stub
                                        break;
                                case 'accusative': # винительный падеж
                                        # stub
                                        break;
-                               case 'instrumental':  # творительный падеж
+                               case 'instrumental': # творительный падеж
                                        # stub
                                        break;
                                case 'prepositional': # предложный падеж
-                                       # stub
+                                       if ( join( '', array_slice( $chars[0], -1 ) ) === 'ь' ) {
+                                               $word = join( '', array_slice( $chars[0], 0, -1 ) ) . 'е';
+                                       } elseif ( join( '', array_slice( $chars[0], -2 ) ) === 'ия' ) {
+                                               $word = join( '', array_slice( $chars[0], 0, -2 ) ) . 'ии';
+                                       } elseif ( join( '', array_slice( $chars[0], -2 ) ) === 'ка' ) {
+                                               $word = join( '', array_slice( $chars[0], 0, -2 ) ) . 'ке';
+                                       } elseif ( join( '', array_slice( $chars[0], -2 ) ) === 'ти' ) {
+                                               $word = join( '', array_slice( $chars[0], 0, -2 ) ) . 'тях';
+                                       } elseif ( join( '', array_slice( $chars[0], -2 ) ) === 'ды' ) {
+                                               $word = join( '', array_slice( $chars[0], 0, -2 ) ) . 'дах';
+                                       } elseif ( join( '', array_slice( $chars[0], -3 ) ) === 'ник' ) {
+                                               $word = join( '', array_slice( $chars[0], 0, -3 ) ) . 'нике';
+                                       } elseif ( join( '', array_slice( $chars[0], -3 ) ) === 'ные' ) {
+                                               $word = join( '', array_slice( $chars[0], 0, -3 ) ) . 'ных';
+                                       }
                                        break;
                        }
+               }
+
                return $word;
        }
 
@@ -104,28 +122,35 @@ class LanguageRu extends Language {
         * @return string
         */
        function convertPlural( $count, $forms ) {
-               if ( !count( $forms ) ) { return ''; }
+               if ( !count( $forms ) ) {
+                       return '';
+               }
 
                // If the actual number is not mentioned in the expression, then just two forms are enough:
-               // singular for $count == 1
-               // plural   for $count != 1
+               // singular for $count === 1
+               // plural   for $count !== 1
                // For example, "This user belongs to {{PLURAL:$1|one group|several groups}}."
-               if ( count( $forms ) === 2 ) return $count == 1 ? $forms[0] : $forms[1];
+               if ( count( $forms ) === 2 ) {
+                       return $count === 1 ? $forms[0] : $forms[1];
+               }
 
                // @todo FIXME: CLDR defines 4 plural forms. Form with decimals missing.
                // See http://unicode.org/repos/cldr-tmp/trunk/diff/supplemental/language_plural_rules.html#ru
                $forms = $this->preConvertPlural( $forms, 3 );
 
-               if ( $count > 10 && floor( ( $count % 100 ) / 10 ) == 1 ) {
+               if ( $count > 10 && (int)floor( ( $count % 100 ) / 10 ) === 1 ) {
                        return $forms[2];
-               } else {
-                       switch ( $count % 10 ) {
-                               case 1:  return $forms[0];
-                               case 2:
-                               case 3:
-                               case 4:  return $forms[1];
-                               default: return $forms[2];
-                       }
+               }
+
+               switch ( $count % 10 ) {
+                       case 1:
+                               return $forms[0];
+                       case 2:
+                       case 3:
+                       case 4:
+                               return $forms[1];
+                       default:
+                               return $forms[2];
                }
        }
 
index 3610c1e..55aec32 100644 (file)
@@ -167,6 +167,7 @@ class SrConverter extends LanguageConverter {
                $matches = preg_split( $reg, $text, -1, PREG_SPLIT_OFFSET_CAPTURE );
 
                $m = array_shift( $matches );
+               $this->loadTables();
                if ( !isset( $this->mTables[$toVariant] ) ) {
                        throw new MWException( "Broken variant table: " . implode( ',', array_keys( $this->mTables ) ) );
                }
index d129d19..3bbee94 100644 (file)
@@ -207,7 +207,7 @@ $messages = array(
 
 'underline-always' => 'Sabe',
 'underline-never' => "H'an tom",
-'underline-default' => 'Penjelajah web bawaan',
+'underline-default' => 'Kulet atawa ngon peuhah web teupasang',
 
 # Font style option in Special:Preferences
 'editfont-style' => 'Gaya seunurat komputer bak plok andam',
@@ -292,7 +292,8 @@ $messages = array(
 'newwindow' => '(peuhah bak tingkap barô)',
 'cancel' => 'Peubateuë',
 'moredotdotdot' => 'Lom...',
-'mypage' => 'Ôn lôn',
+'morenotlisted' => 'Lom...',
+'mypage' => 'Ôn',
 'mytalk' => 'Marit',
 'anontalk' => 'Peugah haba IP nyoë.',
 'navigation' => 'Navigasi',
@@ -315,7 +316,7 @@ $messages = array(
 'vector-action-protect' => 'Peulindông',
 'vector-action-undelete' => 'Bateuë sampôh',
 'vector-action-unprotect' => 'Gantoe neulindông',
-'vector-simplesearch-preference' => 'Peuudep mita saran nyang geupeusamporeuna (keu kulet Vector khong)',
+'vector-simplesearch-preference' => 'Peuudep beunteueng mita biasa (kulet Vector khong)',
 'vector-view-create' => 'Peugöt',
 'vector-view-edit' => 'Andam',
 'vector-view-history' => 'Atra u likôt',
@@ -325,6 +326,7 @@ $messages = array(
 'namespaces' => 'Ruweuëng nan',
 'variants' => 'Ragam',
 
+'navigation-heading' => 'Menu navigasi',
 'errorpagetitle' => 'Seunalah',
 'returnto' => 'Gisa u $1.',
 'tagline' => 'Nibak {{SITENAME}}',
@@ -421,10 +423,10 @@ $1",
 'youhavenewmessages' => 'Droëneuh   na $1 ($2).',
 'newmessageslink' => 'peusan barô',
 'newmessagesdifflink' => 'neuubah keuneulheuëh',
-'youhavenewmessagesfromusers' => "Droeneuh na $1 nibak {{PLURAL:$3||}}ureueng nguy la'en ($2).",
+'youhavenewmessagesfromusers' => "Droeneuh na $1 nibak {{PLURAL:$3|ureueng nguy la'en|$3 ureueng nguy}} ($2).",
 'youhavenewmessagesmanyusers' => "Droeneuh na $1 nibak ureueng nguy la'en ($2)",
 'newmessageslinkplural' => '{{PLURAL:$1|saboh peusan baro|peusan baro}}',
-'newmessagesdifflinkplural' => '{{PLURAL:$1|neuubah|neuubah}} baro',
+'newmessagesdifflinkplural' => '{{PLURAL:$1|neuubah}} keuneulheueh',
 'youhavenewmessagesmulti' => 'Droëneuh na padum boh peusan barô bak $1',
 'editsection' => 'andam',
 'editold' => 'andam',
@@ -467,7 +469,8 @@ $1",
 'nosuchaction' => 'Hana buet nyan',
 'nosuchactiontext' => 'Buet nyang geulakee le URL nyan hana sah. Droeneuh kadang salah neukeutik URL, atawa neuseutot saboh neuhubong nyang hana beutoy. Hay nyoe kadang jeuet keu lageuem saboh bug bak alat leumiek nyang geunguy le {{SITENAME}}.',
 'nosuchspecialpage' => 'Hana on kusuih lagee nyan',
-'nospecialpagetext' => '<strong>Droeneuh neulakee on kusuih nyang hana sah.</strong>',
+'nospecialpagetext' => "<strong>Droeneuh ka neulakee on kusuih nyang hana sah.</strong>
+Dapeuta on kusuih nyang sah jeuet neu'eu bak [[Special:SpecialPages|{{int:specialpages}}]].",
 
 # General errors
 'error' => 'Seunalah',
@@ -484,17 +487,51 @@ Neulakee basis data nyang keuneulheueh nakeuh:
 nibak fungsi "$2"
 Basis data geupeuhase salah "$3: $4".',
 'laggedslavemode' => 'Peuneugah: On nyoe kadang hana neuubah baro',
+'readonly' => 'Basis data geurok',
+'enterlockreason' => 'Pasoe daleh neurok ngon pajan jeuet geupeuhah',
+'readonlytext' => "Basis data hat nyoe geurok keu teunamong baro ngon geunantoe la'en, kadang keu peulara basis data rutin, lheueh nyan baro lagee biasa teuma.
+
+Ureueng uroh nyang rok nyoe geupeutaba jeuneulaih nyoe: $1",
 'missing-article' => 'Basis data h’an jeuët jiteumèë naseukah nibak ôn nyang sipatôtjih na, nakeuh "$1" $2.
 
 Nyoë biasajih sabab hubông useuëng u geunantoë away nyang ka teusampôh.
 
 Meunyo kön nyoë sababjih, Droëneuh kadang ka neuteumèë saboh bug lam software. Neutulông peugah bhah nyoë bak salah sidroë [[Special:ListUsers/sysop|Nyang urôh]], ngön neupeugah alamat URL nyang neusaweuë.',
 'missingarticle-rev' => '(revisi#: $1)',
+'missingarticle-diff' => '(Bida: $1, $2)',
+'readonly_lag' => 'Basis data ka geurok otomatis silawet basis data sekunder teungoh geupeusinkron ngon basis data utama',
 'internalerror' => 'Salah bak dalam',
 'internalerror_info' => 'Salah bak dalam: $1',
+'fileappenderrorread' => 'H\'an jitem beuet "$1" \'oh geutamah',
+'fileappenderror' => 'H\'an jeuet jipasoe "$1" u "$2"',
+'filecopyerror' => 'H\'an jeuet salen beureukaih "$1" u "$2".',
+'filerenameerror' => 'H\'an jeuet boh nan beureukaih "$1" u "$2".',
+'filedeleteerror' => 'H\'an jeuet sampoh beureukaih "$1".',
+'directorycreateerror' => 'H\'an jeuet peugot direktori "$1".',
+'filenotfound' => 'Beureukaih "$1" hana meurumpok.',
+'fileexistserror' => 'H\'an jeuet geusalen u beureukaih "$1": Beureukaih ka na.',
+'unexpected' => 'Yum hana geuharap: "$1"="$2".',
+'formerror' => "Reuloh: H'an jeuet peu'et formulir.",
+'badarticleerror' => "Buet nyoe h'an jeuet geupeulaku bak on nyoe.",
+'cannotdelete' => 'On atawa beureukaih "$1" h\'an jeuet geusampoh.
+Kadang ka na soe sampoh.',
+'cannotdelete-title' => 'H\'an jeuet sampoh on "$1"',
+'delete-hook-aborted' => "Seunampoh geupeubateue le kaw'et parser.
+Hana jeuneulaih.",
 'badtitle' => 'Nan hana sah',
 'badtitletext' => 'Nan ôn nyang neulakèë hana sah, soh, atawa nan antarabahsa atawa antarawiki nyang salah sambông.',
+'perfcached' => 'Data di yup nyoe geucok nibak peuniyoh ngon kadang kon data baro. {{PLURAL:$1||}}$1 hase maksimum na bak beuen.',
+'perfcachedts' => 'Data di yup nyoe geupeusom, ngon geupeubaro keuneulheueh bak $1. {{PLURAL:$1||}}$1 hase maksimal na lam beuen.',
+'querypage-no-updates' => "Beunaro keu on nyoe hat nyoe teungoh h'an jeuet.
+Data sinoe h'an geupasoe ulang.",
+'wrong_wfQuery_params' => 'Parameter salah u wfQuery()<br />
+Meunafaat: $1<br />
+Neulakee: $2',
 'viewsource' => 'Eu nè',
+'viewsource-title' => 'Eu ne keu $1',
+'actionthrottled' => 'Buet geupeubataih',
+'actionthrottledtext' => 'Sibagoe saboh seunipat lawan-spam, droeneuh geupeubataih nibak neupeulaku buet nyoe le that go lam watee paneuk, ngon droeneuh ka leubeh nibak bataih.
+Neuci lom lam padum minet.',
 'viewsourcetext' => 'Droëneuh  jeuët neu’eu',
 
 # Login and logout pages
@@ -529,9 +566,9 @@ Préksa keulayi neu’ija Droëneuh.',
 'passwordtooshort' => "Lageuëm paléng h'an haroh na {{PLURAL:$1|1 karakter|$1 karakter}}.",
 'mailmypassword' => "Peu'ét lageuëm barô",
 'passwordremindertitle' => 'Lageuëm seumeuntara barô keu {{SITENAME}}',
-'passwordremindertext' => 'Salah sidroë (kadang Droëneuh, ngön alamat IP $1) geulakèë kamoë keu meukirém lageuëm rahsia nyang barô keu {{SITENAME}} ($4).
-Lageuëm rahsia keu ureuëng nguy "$2" jinoë nakeuh "$3".
-Droëneuh geupeusaran keu neutamong sigra, lheuëh nyan neugantoë lageuëm rahsia.',
+'passwordremindertext' => 'Salah sidroë (kadang Droëneuh, ngön alamat IP $1) geulakèë lageuëm barô keu {{SITENAME}} ($4). Lageuëm si\'at keu ureuëng nguy "$2" ka geupeuna ngon ka geuato jeuet keu "$3". Meunyo nyoe nakeuh meukeusud droeneuh, droeneuh peureulee neutamong ngon neupileh lageuem baro jinoe. Lageuem siat droeneuh meung abeh lam {{PLURAL:$5|siuroe|$5 uroe}}.
+
+Meunyo ureueng la\'en nyang peugot neulakee nyoe, atawa meunyo droeneuh ka neuingat lageuem droeneuh, ngon droeneuh h\'an ek neugantoe le, droeneuh jeuet hana neupeureumeuen peusan nyoe ngon neulanjut neunguy lageuem awayneuh.',
 'noemail' => 'Hana alamat surat-e nyang teucatat keu ureuëng nguy "$1".',
 'passwordsent' => 'Lageuëm barô ka geupeu\'ét u surat-e nyang geupeudapeuta keu "$1". Neutamong teuma lheuëh neuteurimong surat-e nyan.',
 'eauthentsent' => 'Saboh surat èlèktronik keu peunyoë ka geukirém u alamat surat èlèktronik Droëneuh. Droëneuh beuneuseutöt préntah lam surat nyan keu neupeunyoë meunyo alamat nyan nakeuh beutôy atra Droëneuh. {{SITENAME}} h‘an geupeuudép surat Droëneuh meunyo langkah nyoë hana neupeulaku lom.',
@@ -906,7 +943,7 @@ Teuneurang bak [$2 on teuneurangjih] geupeuleumah di yup nyoe.",
 'emailuser' => 'Surat-e ureuëng nguy',
 
 # Watchlist
-'watchlist' => 'Dapeuta keunalön lôn',
+'watchlist' => 'Dapeuta keunalön',
 'mywatchlist' => 'Keunalön',
 'watchlistfor2' => 'Keu $1 $2',
 'addedwatchtext' => "Ôn \"[[:\$1]]\" ka geupeutamah u [[Special:Watchlist|dapeuta keunalön]] Droëneuh. Neu’ubah-neu’ubah bak masa u keuë bak ôn nyan ngön bak ôn peugah habajih, euntreuk leumah nyoë pat. Ôn nyan euntreuk geupeuleumah ''teubay'' bak [[Special:RecentChanges|dapeuta neu’ubah paléng barô]] mangat leubèh mudah leumah.",
index bd39bd0..3a743a7 100644 (file)
@@ -54,6 +54,7 @@
  * @author Uwe a
  * @author Zack wadghiri
  * @author Zanatos
+ * @author أحمد
  * @author ترجمان05
  * @author خالد حسني
  * @author روخو
@@ -469,42 +470,42 @@ $imageFiles = array(
 
 $messages = array(
 # User preference toggles
-'tog-underline' => 'ضع خطا تحت الوصلات:',
-'tog-justify' => 'ساÙ\88 الفقرات',
-'tog-hideminor' => 'أخÙ\81 Ø§Ù\84تعدÙ\8aÙ\84ات الطفيفة في أحدث التغييرات',
-'tog-hidepatrolled' => 'أخÙ\81 Ø§Ù\84تعدÙ\8aÙ\84ات المراجعة في أحدث التغييرات',
+'tog-underline' => 'ضع خطا تحت الروابط:',
+'tog-justify' => 'حاذ الفقرات',
+'tog-hideminor' => 'أخÙ\81 Ø§Ù\84تحرÙ\8aرات الطفيفة في أحدث التغييرات',
+'tog-hidepatrolled' => 'أخÙ\81 Ø§Ù\84تحرÙ\8aرات المراجعة في أحدث التغييرات',
 'tog-newpageshidepatrolled' => 'أخف الصفحات المراجعة من قائمة الصفحات الجديدة',
 'tog-extendwatchlist' => 'مدد قائمة المراقبة لعرض كل التغييرات، وليس الأحدث فقط',
-'tog-usenewrc' => 'جÙ\85Ù\91ع Ø§Ù\84تعدÙ\8aÙ\84ات حسب الصفحة في أحدث التغييرات وقائمة المراقبة (يتطلب جافاسكربت)',
+'tog-usenewrc' => 'جÙ\85Ù\91ع Ø§Ù\84تغÙ\8aÙ\8aرات حسب الصفحة في أحدث التغييرات وقائمة المراقبة (يتطلب جافاسكربت)',
 'tog-numberheadings' => 'رقم العناوين تلقائياً',
 'tog-showtoolbar' => 'أظهر شريط التحرير (يتطلب جافاسكربت)',
-'tog-editondblclick' => 'عدÙ\84 Ø§Ù\84صÙ\81حات Ø¹Ù\86د Ø§Ù\84ضغط المزدوج (جافاسكربت)',
-'tog-editsection' => 'Ù\85Ù\83Ù\86 ØªØ¹Ø¯Ù\8aÙ\84 Ø§Ù\84Ø£Ù\82ساÙ\85 Ø¹Ù\86 Ø·Ø±Ù\8aÙ\82 Ù\88صÙ\84ات [عدل]',
-'tog-editsectiononrightclick' => 'Ù\81عÙ\84 ØªØ¹Ø¯Ù\8aÙ\84 Ø§Ù\84Ø£Ù\82ساÙ\85 Ø¨Ù\88اسطة Ù\83بسة Ø§Ù\84Ù\81أرة Ø§Ù\84Ù\8aÙ\85Ù\8aÙ\86 Ø¹Ù\84Ù\89 Ø¹Ù\86اÙ\88Ù\8aÙ\86 Ø§Ù\84Ø£Ù\82ساÙ\85 (جافاسكريبت)',
+'tog-editondblclick' => 'تحرÙ\8aر Ø§Ù\84صÙ\81حات Ø¨Ø§Ù\84Ù\86Ù\82ر المزدوج (جافاسكربت)',
+'tog-editsection' => 'Ù\85Ù\83Ù\86 ØªØ­Ø±Ù\8aر Ø§Ù\84Ø£Ù\82ساÙ\85 Ø¨Ø±Ù\88ابط [عدل]',
+'tog-editsectiononrightclick' => 'Ù\81عÙ\90Ù\91Ù\84 ØªØ­Ø±Ù\8aر Ø§Ù\84Ø£Ù\82ساÙ\85 Ø¨Ø§Ù\84Ù\86Ù\82ر Ø¨Ø§Ù\84Ù\8aÙ\85Ù\8aÙ\86 Ø¹Ù\84Ù\89 Ø¹Ù\86اÙ\88Ù\8aÙ\86 Ø§Ù\84Ø£Ù\82ساÙ\85 (Ù\8aتطÙ\84ب جافاسكريبت)',
 'tog-showtoc' => 'اعرض فهرس المحتويات (للصفحات التي تحتوي على أكثر من 3 عناوين)',
 'tog-rememberpassword' => 'تذكر دخولي بهذا المتصفح (لمدة أقصاها {{PLURAL:$1||يوم واحد|يومان|$1 أيام|$1 يوما|$1 يوم}})',
 'tog-watchcreations' => 'أضف الصفحات التي أنشئها والملفات التي أرفعها إلى قائمة مراقبتي.',
-'tog-watchdefault' => '!!أضÙ\81 Ø§Ù\84صÙ\81حات Ù\88اÙ\84Ù\85Ù\84Ù\81ات Ø§Ù\84تÙ\8a Ø£Ø¹Ø¯Ù\84ها إلى قائمة مراقبتي',
+'tog-watchdefault' => '!!أضÙ\81 Ø§Ù\84صÙ\81حات Ù\88اÙ\84Ù\85Ù\84Ù\81ات Ø§Ù\84تÙ\8a Ø£Ø­Ø±Ø±ها إلى قائمة مراقبتي',
 'tog-watchmoves' => 'أضف الصفحات والملفات التي أنقلها إلى قائمة مراقبتي',
 'tog-watchdeletion' => 'أضف الصفحات والملفات التي أحذفها إلى قائمة مراقبتي',
-'tog-minordefault' => 'عÙ\84Ù\85 Ù\83Ù\84 Ø§Ù\84تعدÙ\8aÙ\84ات Ø·Ù\81Ù\8aÙ\81Ø© Ø§Ù\81تراضيا',
+'tog-minordefault' => 'أشÙ\90Ù\91ر Ù\83Ù\84 Ø§Ù\84تعدÙ\8aÙ\84ات Ø¹Ù\84Ù\89 Ø£Ù\86Ù\87ا Ø·Ù\81Ù\8aÙ\81Ø© Ù\85بدئيا',
 'tog-previewontop' => 'أظهر العرض المسبق قبل صندوق التحرير',
-'tog-previewonfirst' => 'أظÙ\87ر Ù\85عاÙ\8aÙ\86Ø© Ù\85ع Ø£Ù\88Ù\84 ØªØ¹Ø¯Ù\8aÙ\84',
+'tog-previewonfirst' => 'أظÙ\87ر Ù\85عاÙ\8aÙ\86Ø© Ù\85ع Ø£Ù\88Ù\84 ØªØ­Ø±Ù\8aر',
 'tog-nocache' => 'عطّل تخزين المتصفح للصفحة',
-'tog-enotifwatchlistpages' => 'أرسل لي رسالة إلكترونية عندما تُغيّر صفحة أو ملف في قائمة مراقبتي',
+'tog-enotifwatchlistpages' => 'أرسل لي رسالة إلكترونية عندما تتغيّر صفحة أو ملف في قائمة مراقبتي',
 'tog-enotifusertalkpages' => 'أرسل لي رسالة إلكترونية عندما تعدل صفحة نقاشي',
-'tog-enotifminoredits' => 'أرسÙ\84 Ù\84Ù\8a Ø±Ø³Ø§Ù\84Ø© Ø¥Ù\84Ù\83ترÙ\88Ù\86Ù\8aØ© Ø¹Ù\86 Ø§Ù\84تعدÙ\8aÙ\84ات Ø§Ù\84Ø·Ù\81Ù\8aÙ\81Ø© Ù\84Ù\84صÙ\81حات Ù\88اÙ\84Ù\85Ù\84Ù\81ات Ø£Ù\8aضا',
+'tog-enotifminoredits' => 'أرسÙ\84 Ù\84Ù\8a Ø±Ø³Ø§Ù\84Ø© Ø¥Ù\84Ù\83ترÙ\88Ù\86Ù\8aØ© Ø¨Ø´Ø£Ù\86 Ø§Ù\84تحرÙ\8aرات Ø§Ù\84Ø·Ù\81Ù\8aÙ\81Ø© Ù\84Ù\84صÙ\81حات Ù\88اÙ\84Ù\85Ù\84Ù\81ات',
 'tog-enotifrevealaddr' => 'أظهر عنوان بريدي الإلكتروني في رسائل الإخطار',
-'tog-shownumberswatching' => 'اعرض عدد المستخدمين المراقبين',
+'tog-shownumberswatching' => 'اعرض Ø¹Ø¯Ø¯ Ø§Ù\84Ù\85ستخدÙ\85Ù\8aÙ\86 Ø§Ù\84Ù\85راÙ\82بÙ\90Ù\8aÙ\86',
 'tog-oldsig' => 'التوقيع الحالي:',
 'tog-fancysig' => 'عامل التوقيع كنص ويكي (بدون وصلة أوتوماتيكية)',
-'tog-externaleditor' => 'استخدم محرراً خارجياً بشكل افتراضي (للخبراء فقط، يحتاج إعدادات خاصة على حاسوبك) ([//www.mediawiki.org/wiki/Manual:External_editors لمزيد من المعلومات].)',
-'tog-externaldiff' => 'استخدÙ\85 Ù\81رÙ\82اÙ\8b Ø®Ø§Ø±Ø¬Ù\8aاÙ\8b Ø¨Ø´Ù\83Ù\84 Ø§Ù\81تراضÙ\8a (Ù\84Ù\84خبراء Ù\81Ù\82Ø·Ø\8c Ù\8aحتاج إعدادات خاصة على حاسوبك) ([//www.mediawiki.org/wiki/Manual:External_editors للمزيد من المعلومات].)',
+'tog-externaleditor' => 'استخدم محررًا خارجيًا مبدئيا (للخبراء فقط، يتطلب إعدادات خاصة على حاسوبك) ([//www.mediawiki.org/wiki/Manual:External_editors لمزيد من المعلومات].)',
+'tog-externaldiff' => 'استخدÙ\85 Ù\85ستعرض Ù\81رÙ\88Ù\82ات Ø®Ø§Ø±Ø¬Ù\8aÙ\8bا Ù\85بدئÙ\8aا (Ù\84Ù\84خبراء Ù\81Ù\82Ø·Ø\8c Ù\8aتطÙ\84Ù\91ب إعدادات خاصة على حاسوبك) ([//www.mediawiki.org/wiki/Manual:External_editors للمزيد من المعلومات].)',
 'tog-showjumplinks' => 'مكن وصلات "اذهب إلى" المساعدة',
 'tog-uselivepreview' => 'استخدم الاستعراض السريع (جافاسكريبت) (تجريبي)',
-'tog-forceeditsummary' => 'Ù\86بÙ\87Ù\86Ù\8a Ø¹Ù\86د Ø¥Ø¯Ø®Ø§Ù\84 Ù\85Ù\84خص ØªØ¹Ø¯Ù\8aÙ\84 فارغ',
-'tog-watchlisthideown' => 'أخÙ\81 ØªØ¹Ø¯Ù\8aÙ\84اتي من قائمة المراقبة',
-'tog-watchlisthidebots' => 'أخÙ\81 ØªØ¹Ø¯Ù\8aÙ\84ات Ø§Ù\84بÙ\88ت من قائمة المراقبة',
+'tog-forceeditsummary' => 'Ù\86بÙ\87Ù\86Ù\8a Ø¹Ù\86د Ø¥Ø¯Ø®Ø§Ù\84 Ù\85Ù\84خص ØªØ­Ø±Ù\8aر فارغ',
+'tog-watchlisthideown' => 'أخÙ\81 ØªØ­Ø±Ù\8aراتي من قائمة المراقبة',
+'tog-watchlisthidebots' => 'أخÙ\81 ØªØ­Ø±Ù\8aرات Ø§Ù\84رÙ\88بÙ\88تات من قائمة المراقبة',
 'tog-watchlisthideminor' => 'أخف التعديلات الطفيفة من قائمة المراقبة',
 'tog-watchlisthideliu' => 'أخف تعديلات المستخدمين المسجلين من قائمة المراقبة',
 'tog-watchlisthideanons' => 'أخف تعديلات المستخدمين المجهولين من قائمة المراقبة',
@@ -512,7 +513,7 @@ $messages = array(
 'tog-ccmeonemails' => 'أرسل لي نسخا من رسائل البريد الإلكتروني التي أرسلها للمستخدمين الآخرين',
 'tog-diffonly' => 'لا تعرض محتوى الصفحة أسفل الفروقات',
 'tog-showhiddencats' => 'أظهر التصنيفات المخفية',
-'tog-noconvertlink' => 'عطل تحويل عناوين الوصلات',
+'tog-noconvertlink' => 'عطل تحويل عناوين الروابط',
 'tog-norollbackdiff' => 'أزل الفرق بعد القيام باسترجاع',
 
 'underline-always' => 'دائما',
@@ -580,10 +581,10 @@ $messages = array(
 
 # Categories related messages
 'pagecategories' => '{{PLURAL:$1|لا تصنيف|تصنيف|تصنيفان|تصنيفات}}',
-'category_header' => 'صÙ\81حات تصنيف "$1"',
+'category_header' => 'اÙ\84صÙ\81حات Ù\81Ù\8a Ø§Ù\84تصنيف "$1"',
 'subcategories' => 'التصنيفات الفرعية',
 'category-media-header' => 'الوسائط في التصنيف "$1"',
-'category-empty' => "''هذا التصنيف لا يحتوي حاليا على صفحات أو وسائط.''",
+'category-empty' => "''هذا التصنيف لا يحتوي حاليا على صفحات و لا وسائط.''",
 'hidden-categories' => '{{PLURAL:$1|لا تصنيف مخفيا|تصنيف مخفي|تصنيفان مخفيان|تصنيفات مخفية}}',
 'hidden-category-category' => 'تصنيفات مخفية',
 'category-subcat-count' => '{{PLURAL:$2|لا تصانيف فرعية في هذا التصنيف|هذا التصنيف فيه التصنيف الفرعي التالي فقط.|هذا التصنيف فيه {{PLURAL:$1||هذا التصنيف الفرعي|هذين التصنيفين الفرعيين|هذه ال$1 تصانيف الفرعية|هذه ال$1 تصنيفا فرعيا|هذه ال$1 تصنيف فرعي}}، من إجمالي $2.}}',
@@ -595,13 +596,14 @@ $messages = array(
 'listingcontinuesabbrev' => 'متابعة',
 'index-category' => 'صفحات مفهرسة',
 'noindex-category' => 'صفحات غير مفهرسة',
-'broken-file-category' => 'صفحات تحتوي وصلات ملفات معطوبة',
+'broken-file-category' => 'صفحات تحتوي روابط ملفات معطوبة',
 
 'about' => 'عن',
 'article' => 'صفحة محتوى',
 'newwindow' => '(تفتح في نافذة جديدة)',
-'cancel' => 'Ø¥Ù\84غاء',
+'cancel' => 'Ø£Ù\84غÙ\90',
 'moredotdotdot' => 'المزيد...',
+'morenotlisted' => 'يوجد المزيد غير مسرود...',
 'mypage' => 'صفحة',
 'mytalk' => 'نقاش',
 'anontalk' => 'النقاش لعنوان الأيبي هذا',
@@ -611,7 +613,7 @@ $messages = array(
 # Cologne Blue skin
 'qbfind' => 'جد',
 'qbbrowse' => 'تصفح',
-'qbedit' => 'تعدÙ\8aÙ\84',
+'qbedit' => 'حرÙ\91ر',
 'qbpageoptions' => 'هذه الصفحة',
 'qbmyoptions' => 'صفحاتي',
 'qbspecialpages' => 'الصفحات الخاصة',
@@ -624,15 +626,15 @@ $messages = array(
 'vector-action-move' => 'انقل',
 'vector-action-protect' => 'احم',
 'vector-action-undelete' => 'استرجع الحذف',
-'vector-action-unprotect' => 'غير الحماية',
+'vector-action-unprotect' => 'غيّر الحماية',
 'vector-simplesearch-preference' => 'مكّن شريط البحث المبسط (لواجهة فكتور فقط)',
 'vector-view-create' => 'أنشئ',
 'vector-view-edit' => 'تعديل',
 'vector-view-history' => 'اعرض التاريخ',
 'vector-view-view' => 'اقرأ',
-'vector-view-viewsource' => 'اعرض المصدر',
+'vector-view-viewsource' => 'طاÙ\84ع المصدر',
 'actions' => 'أفعال',
-'namespaces' => 'النطاقات',
+'namespaces' => 'فضاءات التسمية',
 'variants' => 'المتغيرات',
 
 'navigation-heading' => 'قائمة التصفح',
@@ -641,24 +643,24 @@ $messages = array(
 'tagline' => 'من {{SITENAME}}',
 'help' => 'مساعدة',
 'search' => 'بحث',
-'searchbutton' => 'بحث',
+'searchbutton' => 'ابحث',
 'go' => 'اذهب',
 'searcharticle' => 'اذهب',
 'history' => 'تاريخ الصفحة',
 'history_short' => 'تاريخ',
-'updatedmarker' => 'تÙ\85 ØªØ­Ø¯Ù\8aØ«Ù\87ا منذ زيارتي الأخيرة',
+'updatedmarker' => 'Ø­Ù\8fدÙ\90Ù\91Ø«Ù\8eت منذ زيارتي الأخيرة',
 'printableversion' => 'نسخة للطباعة',
-'permalink' => 'وصلة دائمة',
+'permalink' => 'رابط دائم',
 'print' => 'اطبع',
-'view' => 'عرض',
-'edit' => 'تعدÙ\8aÙ\84',
-'create' => 'Ø£Ù\86شئ',
-'editthispage' => 'تعدÙ\8aÙ\84 هذه الصفحة',
+'view' => 'مطالعة',
+'edit' => 'تحرÙ\8aر',
+'create' => 'Ø¥Ù\86شاء',
+'editthispage' => 'حرÙ\90Ù\91ر هذه الصفحة',
 'create-this-page' => 'أنشئ هذه الصفحة',
 'delete' => 'حذف',
 'deletethispage' => 'احذف هذه الصفحة',
 'undelete_short' => 'استرجاع {{PLURAL:$1|تعديل واحد|تعديلين|$1 تعديلات|$1 تعديل|$1 تعديلا}}',
-'viewdeleted_short' => 'عرض {{PLURAL:$1|تعديل محذوف|$1 تعديلات محذوفة}}',
+'viewdeleted_short' => 'استعرض {{PLURAL:$1|تعدÙ\8aÙ\84 Ù\85حذÙ\88Ù\81|$1 ØªØ¹Ø¯Ù\8aÙ\84ات Ù\85حذÙ\88Ù\81Ø©}}',
 'protect' => 'احم',
 'protect_change' => 'غير',
 'protectthispage' => 'احم هذه الصفحة',
@@ -908,7 +910,7 @@ $2',
 'gotaccount' => "لديك حساب؟ '''$1'''.",
 'gotaccountlink' => 'تسجيل الدخول',
 'userlogin-resetlink' => 'نسيت تفاصيل الدخول؟',
-'createaccountmail' => 'بÙ\88اسطة Ø§Ù\84برÙ\8aد Ø§Ù\84Ø¥Ù\84Ù\83ترÙ\88Ù\86Ù\8a',
+'createaccountmail' => 'استخدÙ\85 Ù\83Ù\84Ù\85Ø© Ø³Ø± Ø¹Ø´Ù\88ائÙ\8aØ© Ù\85ؤÙ\82تة Ù\88ارسÙ\84Ù\87ا Ø¥Ù\84Ù\89 Ø¹Ù\86Ù\88اÙ\86 Ø§Ù\84برÙ\8aد Ø§Ù\84Ø¥Ù\84Ù\83ترÙ\88Ù\86Ù\8a Ø§Ù\84Ù\85حدد Ø£Ø¯Ù\86اÙ\87',
 'createaccountreason' => 'السبب:',
 'badretype' => 'كلمات السر التي أدخلتها لا تتطابق.',
 'userexists' => 'اسم المستخدم الذي تم إدخاله مستعمل بالفعل.
@@ -1728,7 +1730,7 @@ $1",
 'grouppage-bot' => '{{ns:project}}:بوتات',
 'grouppage-sysop' => '{{ns:project}}:إداريون',
 'grouppage-bureaucrat' => '{{ns:project}}:بيروقراطيون',
-'grouppage-suppress' => '{{ns:project}}:أوفرسايت',
+'grouppage-suppress' => '{{ns:project}}:نظار',
 
 # Rights
 'right-read' => 'قراءة الصفحات',
@@ -1845,7 +1847,7 @@ $1",
 'recentchanges-feed-description' => 'تابع أحدث التغييرات للويكي عبر هذه التلقيمة.',
 'recentchanges-label-newpage' => 'أنشأ هذا التعديل صفحة جديدة',
 'recentchanges-label-minor' => 'هذا تعديل طفيف',
-'recentchanges-label-bot' => 'أجرى هذا التعديل بوت',
+'recentchanges-label-bot' => 'أُجْرِيَ هذا التعديل بواسطة بوت',
 'recentchanges-label-unpatrolled' => 'لم يراجع هذا التعديل إلى الآن',
 'rcnote' => "بالأسفل {{PLURAL:$1|لا توجد تغييرات|التغيير الأخير|آخر تغييرين|آخر '''$1''' تغييرات|آخر '''$1''' تغييرا|آخر '''$1''' تغيير}} في {{PLURAL:$2||'''اليوم''' الماضي|'''اليومين''' الماضيين|ال'''$2''' أيام الماضية|ال'''$2''' يوما الماضيا|ال'''$2''' يوم الماضي}}، كما في $5، $4.",
 'rcnotefrom' => "بالأسفل التغييرات منذ '''$2''' (إلى '''$1''' معروضة).",
@@ -2199,7 +2201,7 @@ $1',
 'shared-repo' => 'مستودع مشترك',
 'shared-repo-name-wikimediacommons' => 'ويكيميديا كومنز',
 'filepage.css' => '/* CSS المعروض هنا سيضمن في صفحات وصف الملفات، أيضا على الويكيات الأجنبية */',
-'upload-disallowed-here' => 'للأسف لا يمكنك تعديل هذه الصورة.',
+'upload-disallowed-here' => 'لا يمكنك تعديل هذه الصورة.',
 
 # File reversion
 'filerevert' => 'استرجع $1',
@@ -2276,7 +2278,7 @@ $1',
 'statistics-views-peredit' => 'المشاهدات لكل تعديل',
 'statistics-users' => '[[Special:ListUsers|مستخدمون]] مسجلون',
 'statistics-users-active' => 'مستخدمون نشطون',
-'statistics-users-active-desc' => 'المستخدمون الذين قاموا بفعل في آخر {{PLURAL:$1|يوم|$1 يوم}}',
+'statistics-users-active-desc' => 'المستخدمون الذين قاموا بفعل في آخر {{PLURAL:$1||يوم|يومين|$1 أيام|$1 يوماً|$1 يوم}}',
 'statistics-mostpopular' => 'أكثر الصفحات مشاهدة',
 
 'disambiguations' => 'الصفحات التي ترتبط بصفحات توضيح',
@@ -2452,7 +2454,7 @@ $1',
 # Special:ActiveUsers
 'activeusers' => 'قائمة المستخدمين النشطين',
 'activeusers-intro' => 'هذه قائمة بالمستخدمين الذين مارسوا نوعاً من النشاط خلال {{PLURAL:$1||اليوم الماضي|اليومين الماضيين|ال$1 أيام الماضية|ال$1 يوماً ماضياً|ال$1 يوم ماضي}}.',
-'activeusers-count' => '{{PLURAL:$1|Ù\85ا Ù\85Ù\86 ØªØ¹Ø¯Ù\8aÙ\84ات|تعدÙ\8aÙ\84 Ø­Ø¯Ù\8aØ« Ù\88احد|تعدÙ\8aÙ\84اÙ\86 Ø­Ø¯Ù\8aثاÙ\86|$1 ØªØ¹Ø¯Ù\8aÙ\84ات Ø­Ø¯Ù\8aثة|$1 ØªØ¹Ø¯Ù\8aÙ\84ا Ø­Ø¯Ù\8aثا|$1 ØªØ¹Ø¯Ù\8aÙ\84 Ø­Ø¯Ù\8aØ«}} Ù\85Ù\86Ø° {{PLURAL:$3||Ù\8aÙ\88Ù\85\8aÙ\88Ù\85Ù\8aÙ\86|$3 Ø£Ù\8aاÙ\85|$3 Ù\8aÙ\88Ù\85ا|$1 يوم}}',
+'activeusers-count' => '{{PLURAL:$1|Ù\84ا Ø£Ù\81عاÙ\84\81عÙ\84 Ù\88احد|Ù\81عÙ\84اÙ\86 Ø§Ø«Ù\86اÙ\86|$1 Ø£Ù\81عاÙ\84|$1 Ù\81عÙ\84اÙ\8b|$1 Ù\81عÙ\84}} Ù\85Ù\86Ø° {{PLURAL:$3||Ù\8aÙ\88Ù\85\8aÙ\88Ù\85Ù\8aÙ\86|$3 Ø£Ù\8aاÙ\85|$3 Ù\8aÙ\88Ù\85اÙ\8b|$1 يوم}}',
 'activeusers-from' => 'اعرض المستخدمين بدءاً من:',
 'activeusers-hidebots' => 'أخف البوتات',
 'activeusers-hidesysops' => 'أخف الإداريين',
@@ -2989,7 +2991,7 @@ $1',
 # Move page
 'move-page' => 'نقل $1',
 'move-page-legend' => 'نقل صفحة',
-'movepagetext' => "باستخدام  الاستمارة بالأسفل بإمكانك أن تغير اسم الصفحة، وأن تنقل تاريخها إلى لاسم الجديد.
+'movepagetext' => "باستخدام  الاستمارة بالأسفل بإمكانك أن تغير اسم الصفحة، وأن تنقل تاريخها إلى الاسم الجديد.
 العنوان القديم سيصبح تحويلة للعنوان الجديد.
 يمكنك أن تترك التحويلات التي تشير إلى العنوان الأصلي كما هي لتقوم البوتات بتحديثها تلقائياً.
 إذا اخترت أن تقوم بالتحديث يدوياً، فتأكد من عدم وجود تحويلات [[Special:DoubleRedirects|مزدوجة]] أو [[Special:BrokenRedirects|مكسورة]] وقم بتصحيحها.
@@ -3351,6 +3353,7 @@ $1',
 'pageinfo-robot-noindex' => 'غير قابلة للفهرسة',
 'pageinfo-views' => 'عدد المشاهدات',
 'pageinfo-watchers' => 'عدد المراقبين',
+'pageinfo-few-watchers' => 'أقل من {{PLURAL:$1||مراقب واحد|مراقبين اثنين|$1 مراقبين|$1 مراقباً|$1 مراقب}}',
 'pageinfo-redirects-name' => 'التحويلات إلى هذه الصفحة',
 'pageinfo-subpages-name' => 'الصفحات الفرعية لهذه الصفحة',
 'pageinfo-subpages-value' => '$1 ({{PLURAL:$2|لا تحويلات|تحويلة واحدة|تحويلتان|$2 تحويلات|$2 تحويلة}}؛ $3 {{PLURAL:$3|من غير  التحويلات}})',
@@ -3401,6 +3404,7 @@ $1',
 'markedaspatrollederrortext' => 'يجب عليك اختيار المراجعة التي تريد أن تشير أنها مراجعة',
 'markedaspatrollederror-noautopatrol' => 'لا يجوز لك تعليم تغييراتك الشخصية بعلامة المراجعة.',
 'markedaspatrollednotify' => 'هذا التغيير لـ $1  تم تعليمه كمراقب.',
+'markedaspatrollederrornotify' => 'لم ينجح وسم هذه النسخة بأنها مراجعة',
 
 # Patrol log
 'patrol-log-page' => 'سجل الخفر',
@@ -4252,7 +4256,7 @@ $5
 'specialpages-group-highuse' => 'صفحات استخدام عال',
 'specialpages-group-pages' => 'قوائم الصفحات',
 'specialpages-group-pagetools' => 'أدوات الصفحات',
-'specialpages-group-wiki' => 'بÙ\8aاÙ\86ات Ø§Ù\84Ù\88Ù\8aÙ\83Ù\8a Ù\88أدوات',
+'specialpages-group-wiki' => 'اÙ\84بÙ\8aاÙ\86ات Ù\88اÙ\84أدوات',
 'specialpages-group-redirects' => 'صفحات خاصة تحول',
 'specialpages-group-spam' => 'أدوات السبام',
 
@@ -4349,6 +4353,7 @@ $5
 'logentry-newusers-newusers' => 'تم إنشاء الحساب $1',
 'logentry-newusers-create' => 'تم إنشاء الحساب $1',
 'logentry-newusers-create2' => 'أنشأ $1 الحساب $3',
+'logentry-newusers-byemail' => 'أنشئ حساب المستخدم $3 من قبل $1 وأرسلت كلمة السر بالبريد الإلكتروني',
 'logentry-newusers-autocreate' => 'أنشئ حساب $1 تلقائياً',
 'logentry-rights-rights' => 'غير $1 صلاحيات $3 من $4 إلى $5',
 'logentry-rights-rights-legacy' => 'غير $1 صلاحيات $3',
@@ -4407,6 +4412,7 @@ $5
 'api-error-ok-but-empty' => 'خطأ داخلي : لم يكن هناك استجابة من الملقم.',
 'api-error-overwrite' => 'لا يسمح بالكتابة فوق ملف موجود.',
 'api-error-stashfailed' => 'خطأ داخلي: فشل الملقم في تخزين الملفات المؤقتة.',
+'api-error-publishfailed' => 'خطأ داخلي: لم ينجح الخادوم في نشر ملف مؤقت',
 'api-error-timeout' => 'لم يستجب الملقم في الوقت المتوقع.',
 'api-error-unclassified' => 'حدث خطأ غير معروف',
 'api-error-unknown-code' => 'خطأ غير معروف : " $1 "',
index de0d4bc..409dd92 100644 (file)
@@ -141,6 +141,8 @@ $messages = array(
 'tog-underline' => 'ܪܫܘܡ ܣܪܛܐ ܬܚܝܬ ܐܣܪܐ:',
 'tog-justify' => 'ܫܘܐ ܦܬܓܡ̈ܐ',
 'tog-hideminor' => 'ܛܫܝ ܫܘܚܠܦ̈ܐ ܙܥܘܪ̈ܐ ܒܫܘܚܠܦ̈ܐ ܚܕ̈ܬܐ',
+'tog-hidepatrolled' => 'ܛܫܝ ܫܘܚܠܦ̈ܐ ܟܪ̈ܝܟܐ ܒܫܘܚܠܦ̈ܐ ܚܕ̈ܬܐ',
+'tog-newpageshidepatrolled' => 'ܛܫܝ ܦܐܬܬ̈ܐ ܟܪ̈ܝܟܬܐ ܡܢ ܡܟܬܒܘܬܐ ܕܦܐܬܐ ܚܕܬܐ',
 'tog-extendwatchlist' => 'ܐܪܘܚ ܪ̈ܗܝܬܐ ܠܚܘܘܝܐ ܕܟܠܗܘܢ ܫܘܚܠܦ̈ܐ، ܠܐ ܚܕ̈ܬܐ ܒܠܚܘܕ',
 'tog-editondblclick' => 'ܫܚܠܦ ܦܐܬ̈ܐ ܬܪ ܢܩܪܐ ܙܘܓܢܝܐ (ܣܢܝܩ ܠ JavaScript)',
 'tog-editsection' => 'ܡܫܟܚ ܫܘܚܠܦܐ ܕܦܘܣܩ̈ܐ ܒܐܘܪܚܐ ܕܐܝܨܘܪ̈ܐ  [ܫܚܠܦ]',
@@ -402,7 +404,7 @@ $1',
 # General errors
 'error' => 'ܦܘܕܐ',
 'databaseerror' => 'ܦܘܕܐ ܒܐܣ ܝܕ̈ܥܬܐ',
-'missingarticle-rev' => '(ܬܢÜ\9dܬÜ\90#: $1)',
+'missingarticle-rev' => '(Ü¡Ü¢Ü\9dÜ¢Ü\90 Ü\95ܬܢÜ\9dܬÜ\90: $1)',
 'missingarticle-diff' => '(ܦܘܪܫܐ: $1, $2)',
 'internalerror' => 'ܦܘܕܐ ܓܘܝܐ',
 'internalerror_info' => 'ܦܘܕܐ ܓܘܝܐ: $1',
@@ -488,8 +490,10 @@ $1',
 # Special:PasswordReset
 'passwordreset' => 'ܣܘܡ ܡܠܬܐ ܕܥܠܠܐ ܙܒܢ ܐܚܪܝܢ',
 'passwordreset-legend' => 'ܣܘܡ ܡܠܬܐ ܕܥܠܠܐ ܙܒܢ ܐܚܪܝܢ',
+'passwordreset-pretext' => '{{PLURAL:$1||ܐܥܠ ܚܕ ܡܢ ܡܢܘܬ̈ܐ ܕܝܕ̈ܥܬܐ ܠܬܬܚܬ}}',
 'passwordreset-username' => 'ܫܡܐ ܕܡܦܠܚܢܐ:',
 'passwordreset-domain' => 'ܪܘܚܬܐ:',
+'passwordreset-email' => 'ܡܘܢܥܐ ܕܒܝܠܕܪܐ ܐܠܩܛܪܘܢܝܐ:',
 
 # Special:ChangeEmail
 'changeemail' => 'ܫܚܠܦ ܒܝܠܕܪܐ ܐܠܩܛܪܘܢܝܐ',
@@ -1094,6 +1098,7 @@ $1',
 'movethispage' => 'ܫܢܝ ܦܐܬܐ ܗܕܐ',
 'notargettitle' => 'ܕܠܐ ܢܘܦܐ',
 'nopagetitle' => 'ܠܝܬ ܗܟܘܬ ܦܐܬܐ ܕܢܘܦܐ',
+'nopagetext' => 'ܦܐܬܐ ܕܢܘܦܐ ܕܬܬܚܡܬ ܠܝܬ ܠܗ ܐܝܬܘܬܐ.',
 'pager-newer-n' => '{{PLURAL:$1|1 1 ܚܕܬܐ|$1 ܚܕ̈ܬܐ}}',
 'pager-older-n' => '{{PLURAL:$1|1 ܥܬܝܩܐ|$1 ܥܬܝܩ̈ܐ}}',
 'suppress' => 'ܚܝܘܪܐ',
@@ -1108,6 +1113,9 @@ $1',
 'speciallogtitlelabel' => 'ܢܘܦܐ (ܟܘܢܝܐ ܐܘ ܡܦܠܚܢܐ):',
 'log' => 'ܣܓܠ̈ܐ',
 'all-logs-page' => 'ܟܠ ܣܓܠ̈ܐ ܓܘܢܝ̈ܐ',
+'alllogstext' => 'ܓܠܚܐ ܟܠܢܝܐ ܠܟܠ ܣܓܠ̈ܐ ܡܪ ܐܝܬܘܬܐ ܒ{{SITENAME}}.
+ܡܨܬ ܕܬܙܥܪ ܠܦܠܛܐ ܒܓܒܝܬܐ ܕܐܕܫܐ ܕܣܓܠܐ ܐܘ ܫܡܐ ܕܡܦܠܚܢܐ (ܪܓܫܬܢܐ ܠܐܕܫܐ ܕܐܬܘܬܐ) ܐܘ ܦܐܬܐ ܬܘܥܒܕܬܐ (ܐܦ ܪܓܫܬܢܐ ܠܐܕܫܐ ܕܐܬܘܬܐ).',
+'logempty' => 'ܠܝܬ ܡܠܘܐ̈ܐ ܠܐ̈ܝܡܐ ܒܣܓܠܐ ܗܢܐ.',
 'log-title-wildcard' => 'ܒܨܝ ܥܠ ܟܘܢܝ̈ܐ ܕܫܪܝܢ ܥܡ ܟܬܒܬܐ ܗܕܐ',
 'showhideselectedlogentries' => 'ܚܘܝ/ܛܫܝ ܣܓܠ̈ܐ ܕܥܠܠܐ ܓܒܝ̈ܐ',
 
@@ -1555,6 +1563,16 @@ Do you want to change the settings?',
 'pageinfo-contentpage-yes' => 'ܐܝܢ',
 'pageinfo-protect-cascading-yes' => 'ܐܝܢ',
 
+# Patrolling
+'markaspatrolleddiff' => 'ܫܘܕܥ ܐܝܟ ܟܪܝܟܐ',
+'markaspatrolledtext' => 'ܫܘܕܥ ܦܐܬܐ ܗܕܐ ܐܝܟ ܟܪܝܟܬܐ',
+'markedaspatrolled' => 'ܫܘܕܥܬ ܐܝܟ ܟܪܝܟܐ',
+'markedaspatrollednotify' => 'ܫܘܚܠܦܐ ܗܢܐ ܥܠ $1 ܐܫܬܘܕܥ ܐܝܟ ܟܪܝܟܐ.',
+
+# Patrol log
+'patrol-log-page' => 'ܣܓܠܐ ܕܟܪܟܐ',
+'log-show-hide-patrol' => '$1 ܣܓܠܐ ܕܟܪܟܐ',
+
 # Image deletion
 'filedeleteerror-short' => 'ܦܘܕܐ ܒܫܝܦܐ ܕܠܦܦܐ: $1',
 'filedeleteerror-long' => 'ܦܘܕ̈ܐ ܐܫܟܚܬ ܟܕ ܫܝܦܐ ܠܦܦܐ:
@@ -1592,6 +1610,7 @@ $1',
 'hours' => '{{PLURAL:$1|$1 ܫܥܬܐ|$1 ܫܥܬ̈ܐ}}',
 'days' => '{{PLURAL:$1|$1 ܝܘܡܐ|$1 ܝܘܡܬ̈ܐ}}',
 'ago' => 'ܩܕܡ $1',
+'just-now' => 'ܗܫܐ ܒܪ ܫܥܬܗ',
 
 # Metadata
 'metadata' => 'ܓܠܝܬ̈ܐ ܕܡܝܛܐ',
@@ -1784,6 +1803,7 @@ $1',
 'logentry-move-move-noredirect' => '$1 ܫܢܐ ܦܐܬܐ ܕ $3 ܠ $4 ܕܠܐ ܫܒܩܐ ܦܐܬܐ ܕܨܘܝܒܐ',
 'logentry-move-move_redir' => '$1 ܫܢܐ ܦܐܬܐ ܕ $3 ܠ $4 ܕܐܝܬܘܗܝ ܦܐܬܐ ܕܨܘܝܒܐ',
 'logentry-move-move_redir-noredirect' => '$1 ܫܢܐ ܦܐܬܐ ܕ $3 ܠ $4 ܕܐܝܬܘܗܝ ܦܐܬܐ ܕܨܘܝܒܐ ܘܕܠܐ ܫܒܩܐ ܦܐܬܐ ܕܨܘܝܒܐ',
+'logentry-patrol-patrol-auto' => '$1 ܝܬܐܝܬ ܫܘܕܥ ܬܢܝܬܐ $4 ܕܦܐܬܐ $3 ܟܪܝܟܬܐ',
 'logentry-newusers-newusers' => 'ܚܘܫܒܢܐ ܕܡܦܠܚܢܐ $1 ܐܬܒܪܐ',
 'logentry-newusers-create' => 'ܚܘܫܒܢܐ ܕܡܦܠܚܢܐ $1 ܐܬܒܪܐ',
 'logentry-newusers-create2' => 'ܚܘܫܒܢܐ ܕܡܦܠܚܢܐ $3 ܐܬܒܪܐ ܒܝܕ $1',
index b39cbe1..f71437c 100644 (file)
@@ -1126,7 +1126,7 @@ Se puen alcontrar más detalles nel [{{fullurl:{{#Special:Log}}/delete|page={{FU
 'search-interwiki-default' => '$1 resultaos:',
 'search-interwiki-more' => '(más)',
 'search-relatedarticle' => 'Rellacionáu',
-'mwsuggest-disable' => 'Desactivar les suxerencies AJAX',
+'mwsuggest-disable' => 'Desactivar les suxerencies de gueta',
 'searcheverything-enable' => 'Buscar en tolos espacios de nome',
 'searchrelated' => 'rellacionáu',
 'searchall' => 'toos',
@@ -2104,7 +2104,7 @@ La direición de corréu electrónicu qu\'especificasti nes [[Special:Preference
 'usermessage-editor' => 'Mensaxería del sistema',
 
 # Watchlist
-'watchlist' => 'La mio llista de vixilancia',
+'watchlist' => 'Llista de vixilancia',
 'mywatchlist' => 'Llista de vixilancia',
 'watchlistfor2' => 'Pa $1 $2',
 'nowatchlist' => 'La to llista de vixilancia ta vacia.',
@@ -2571,11 +2571,11 @@ Pues actualizar les redireiciones qu'enllacien al títulu orixinal automáticame
 Si prefieres nun lo facer, asegúrate de que nun dexes [[Special:DoubleRedirects|redireiciones dobles]] o [[Special:BrokenRedirects|rotes]].
 Tu yes el responsable de facer que los enllaces queden apuntando au se supón que tienen d'apuntar.
 
-Recuerda que la páxina '''nun''' va movese si yá hai una páxina col nuevu títulu, a nun ser que seya una redireición y nun tenga historial.
+Recuerda que la páxina '''nun''' va movese si yá hai una páxina col nuevu títulu, a nun ser que la mesma seya una redireición y nun tenga historial.
 Esto significa que pues volver a renomar una páxina col nome orixinal si t'enquivoques, y nun pues sobreescribir una páxina yá esistente.
 
-¡AVISU!'''
-Esti pue ser un cambéu importante y inesperáu pa una páxina popular;
+¡Avisu!'''
+Esti pue ser un cambéu importante ya inesperáu pa una páxina popular;
 por favor, asegúrate d'entender les consecuencies de lo que vas facer enantes de siguir.",
 'movepagetext-noredirectfixer' => "Usando'l siguiente formulariu vas renomar una páxina, treslladando'l so historial al nuevu nome.
 El nome vieyu va convertise nuna redireición al nuevu.
@@ -2924,6 +2924,7 @@ Probablemente tea causao por un enllaz a un sitiu esternu de la llista prieta.',
 'pageinfo-robot-noindex' => 'Nun pue ser índiz',
 'pageinfo-views' => 'Númberu de visites',
 'pageinfo-watchers' => 'Númberu de vixilantes de la páxina',
+'pageinfo-few-watchers' => 'Menos de $1 {{PLURAL:$1|vixilante|vixilantes}}',
 'pageinfo-redirects-name' => 'Redireiciones a esta páxina',
 'pageinfo-subpages-name' => "Subpáxines d'esta páxina",
 'pageinfo-subpages-value' => '$1 ($2 {{PLURAL:$2|redireición|redireiciones}}; $3 {{PLURAL:$3|non-redireición|non-redireiciones}})',
index 13ee6c9..bfdc182 100644 (file)
@@ -16,6 +16,7 @@
  * @author Erdemaslancan
  * @author Gulmammad
  * @author Kaganer
+ * @author Khan27
  * @author PPerviz
  * @author PrinceValiant
  * @author Sortilegus
@@ -248,6 +249,7 @@ $messages = array(
 'namespaces' => 'Adlar fəzası',
 'variants' => 'Variantlar',
 
+'navigation-heading' => 'Naviqasiya menyusu',
 'errorpagetitle' => 'Xəta',
 'returnto' => '$1 səhifəsinə qayıt.',
 'tagline' => '{{SITENAME}} saytından',
@@ -477,12 +479,16 @@ Göstərilən səbəb: "\'\'$2\'\'".',
 'logouttext' => "'''Sistemdən çıxdınız.'''
 
 Siz {{SITENAME}} saytını anonim olaraq istifadə etməyə davam edə bilər və ya eyni, yaxud başqa istifadəçi adı ilə <span class='plainlinks'>[$1 yenidən daxil ola]</span> bilərsiniz. Veb-brauzerin keş yaddaşını təmizləyənədək bəzi səhifələr hələ də sistemdə imişsiniz kimi görünə bilər.",
+'welcomeuser' => 'Xoş gəldin $1!',
+'welcomecreation-msg' => 'Hesabınız yaradıldı.
+[[Special:Preferences|{{SITENAME}} nizamlamalarınızı]] dəyişdirməyi unutmayın.',
 'yourname' => 'İstifadəçi adı',
 'yourpassword' => 'Parol:',
 'yourpasswordagain' => 'Parolu təkrar yazın:',
 'remembermypassword' => 'Məni bu kompyuterdə xatırla (maksimum $1 {{PLURAL:$1|gün|gün}})',
 'securelogin-stick-https' => 'Daxil olduqdan sonra HTTPS-lə əlaqədə qal',
 'yourdomainname' => 'Sizin domain',
+'password-change-forbidden' => 'Bu vikidə parolunuzu dəyişdirə bilməzsiniz.',
 'externaldberror' => 'Verilənlər bazasının doğruluğunu yoxlamada xəta baş verib və yaxud sizin xarici istifadəçi qeydiyyatını yeniləmək hüququnuz yoxdur.',
 'login' => 'Daxil ol',
 'nav-login-createaccount' => 'Daxil ol / hesab yarat',
@@ -544,6 +550,7 @@ Aşağıdakı xidmətlərin heç biri üçün Sizə e-məktub göndərilməyəc
 'emailconfirmlink' => 'E-poçt ünvanını təsdiq et',
 'invalidemailaddress' => 'E-poçt ünvanınızı qeyri-düzgün formatda olduğu üçün qəbul edə bilmirik.
 Xahiş edirik düzgün formatlı ünvan daxil edin və ya bu sahəni boş qoyun.',
+'emaildisabled' => 'Bu saytdan e-poçt göndərə bilməzsiniz.',
 'accountcreated' => 'Hesab yaradıldı',
 'accountcreatedtext' => '$1 üçün istifadəçi hesabı yaradıldı.',
 'createaccount-title' => '{{SITENAME}} hesabın yaradılması',
index 85f4ee5..48e75a4 100644 (file)
@@ -32,8 +32,8 @@ $namespaceNames = array(
        NS_USER             => 'Удзельнік',
        NS_USER_TALK        => 'Размовы_з_удзельнікам',
        NS_PROJECT_TALK     => 'Размовы_пра_{{GRAMMAR:вінавальны|$1}}',
-       NS_FILE             => 'Ð\92Ñ\8bÑ\8fва',
-       NS_FILE_TALK        => 'Размовы_пра_выяву',
+       NS_FILE             => 'Файл',
+       NS_FILE_TALK        => 'Размовы_пра_файл',
        NS_MEDIAWIKI        => 'MediaWiki',
        NS_MEDIAWIKI_TALK   => 'Размовы_пра_MediaWiki',
        NS_TEMPLATE         => 'Шаблон',
@@ -46,6 +46,8 @@ $namespaceNames = array(
 
 $namespaceAliases = array(
        '$1_размовы' => NS_PROJECT_TALK,
+       'Выява' => NS_FILE,
+       'Размовы_пра_выяву' => NS_FILE_TALK,
 );
 
 $magicWords = array(
index 385547d..308bf30 100644 (file)
@@ -1296,7 +1296,7 @@ $1",
 'search-interwiki-default' => 'вынікі з $1:',
 'search-interwiki-more' => '(яшчэ)',
 'search-relatedarticle' => 'Зьвязаны',
-'mwsuggest-disable' => 'Адключыць AJAX-падказкі',
+'mwsuggest-disable' => 'Адключыць пошукавыя падказкі',
 'searcheverything-enable' => 'Шукаць ва ўсіх прасторах назваў',
 'searchrelated' => 'зьвязаны',
 'searchall' => 'усе',
@@ -2257,7 +2257,7 @@ $1',
 'usermessage-editor' => 'Дастаўка сыстэмных паведамленьняў',
 
 # Watchlist
-'watchlist' => 'Ð\9cой Ñ\81ьпіс назіраньня',
+'watchlist' => 'Сьпіс назіраньня',
 'mywatchlist' => 'Сьпіс назіраньня',
 'watchlistfor2' => 'Для $1 $2',
 'nowatchlist' => 'Ваш сьпіс назіраньня пусты.',
@@ -3047,6 +3047,7 @@ $1',
 'pageinfo-robot-noindex' => 'Не індэксуецца',
 'pageinfo-views' => 'Колькасьць праглядаў',
 'pageinfo-watchers' => 'Колькасьць назіральнікаў і назіральніц',
+'pageinfo-few-watchers' => 'Менш за $1 {{PLURAL:$1|назіральніка|назіральнікаў}}',
 'pageinfo-redirects-name' => 'Перанакіраваньняў на гэтую старонку',
 'pageinfo-subpages-name' => 'Колькасьць падстаронак',
 'pageinfo-subpages-value' => '$1 ($2 {{PLURAL:$2|перанакіраваньне|перанакіраваньні|перанакіраваньняў}}; $3 {{PLURAL:$3|звычайная|звычайныя|звычайных}})',
@@ -3931,6 +3932,7 @@ MediaWiki распаўсюджваецца з надзеяй, што будзе
 'logentry-newusers-newusers' => 'Быў створаны рахунак $1',
 'logentry-newusers-create' => 'Быў створаны рахунак $1',
 'logentry-newusers-create2' => '$1 стварыў рахунак $3',
+'logentry-newusers-byemail' => '$1 {{GENDER:$2|стварыў|стварыла}} рахунак $3, пароль быў дасланы электроннай поштай',
 'logentry-newusers-autocreate' => 'Рахунак $1 быў створаны аўтаматычна',
 'logentry-rights-rights' => '$1 {{GENDER:$1|зьмяніў|зьмяніла}} прыналежнасьць $3 да групы з $4 на $5',
 'logentry-rights-rights-legacy' => '$1 {{GENDER:$1|зьмяніў|зьмяніла}} прыналежнасьць $3 да групаў',
index 63257d3..71ce78c 100644 (file)
@@ -616,7 +616,7 @@ $1',
 'protectedinterface' => 'Тази страница съдържа текст, нужен за работата на системата. Тя е защитена против редактиране, за да се предотвратят възможни злоупотреби.
 За извършване на промяна за всички уикита, посетете [//translatewiki.net/ translatewiki.net], проектът за локализация на MediaWiki.',
 'editinginterface' => "'''Внимание:''' Редактирате страница, която се използва за интерфейса на софтуера. Промяната й ще повлияе на външния вид на уикито.
-За превеждане обмислете използването на [//translatewiki.net/wiki/Main_Page?setlang=bg translatewiki.net], проектът за локализиране на MediaWiki.",
+За превеждане, обмислете използването на [//translatewiki.net/ translatewiki.net], проектът за локализиране на MediaWiki.",
 'sqlhidden' => '(Заявка на SQL — скрита)',
 'cascadeprotected' => 'Тази страница е защитена против редактиране, защото е включена в {{PLURAL:$1|следната страница, която от своя страна има|следните страници, които от своя страна имат}} каскадна защита:
 $2',
@@ -626,9 +626,9 @@ $2',
 'ns-specialprotected' => 'Специалните страници не могат да бъдат редактирани.',
 'titleprotected' => "Тази страница е била защитена срещу създаване от [[User:$1|$1]].
 Посочената причина е ''$2''.",
-'filereadonlyerror' => "Файлът „$1“ не може да бъде променен, тъй като файловото хранилище „$2“ е в режим само за четене.
+'filereadonlyerror' => 'Файлът „$1“ не може да бъде променен, тъй като файловото хранилище „$2“ е в режим само за четене.
 
\94аденаÑ\82а Ð¿Ñ\80иÑ\87ина Ðµ â\80\9e''$3''â\80\9c.",
\90дминиÑ\81Ñ\82Ñ\80аÑ\82оÑ\80Ñ\8aÑ\82, ÐºÐ¾Ð¹Ñ\82о Ð³Ð¾ Ðµ Ð·Ð°ÐºÐ»Ñ\8eÑ\87ил, Ðµ Ð¿Ð¾Ñ\81оÑ\87ил Ñ\81леднаÑ\82а Ð¿Ñ\80иÑ\87ина: â\80\9e$3â\80\9c.',
 
 # Virus scanner
 'virus-badscanner' => "Лоша конфигурация: непознат скенер за вируси: ''$1''",
@@ -955,7 +955,9 @@ $2
 <div style=\"font-variant:small-caps\">'''Не публикувайте произведения с авторски права без разрешение!'''</div>",
 'longpageerror' => "'''ГРЕШКА: Изпратеният текст е с големина {{PLURAL:$1|един килобайт|$1 килобайта}}, което надвишава позволения максимум от {{PLURAL:$2|един килобайт|$2 килобайта}}.'''
 Поради тази причина той не може да бъде съхранен.",
-'readonlywarning' => "'''ВНИМАНИЕ: Базата от данни беше затворена за поддръжка, затова в момента промените ви не могат да бъдат съхранени. Ако желаете, можете да съхраните страницата като текстов файл и да се опитате да я публикувате по-късно.'''
+'readonlywarning' => "'''ВНИМАНИЕ: Базата от данни беше затворена за поддръжка, затова в момента промените няма да могат да бъдат съхранени.'''
+
+Ако желаете, можете да съхраните страницата като текстов файл и да се опитате да я публикувате по-късно.
 
 Администраторът, който е затворил базата от данни, е посочил следната причина: $1",
 'protectedpagewarning' => "'''Внимание: Страницата е защитена и само потребители със статут на администратори могат да я редактират.'''
@@ -1358,7 +1360,7 @@ $1",
 'youremail' => 'Е-поща:',
 'username' => '{{GENDER:$1|Потребителско име}}:',
 'uid' => '{{GENDER:$1|Потребителски}} номер:',
-'prefs-memberingroups' => 'Член на {{PLURAL:$1|група|групи}}:',
+'prefs-memberingroups' => '{{GENDER:$2|Член}} на {{PLURAL:$1|група|групи}}:',
 'prefs-registration' => 'Регистрация:',
 'yourrealname' => 'Истинско име:',
 'yourlanguage' => 'Език:',
@@ -1921,7 +1923,7 @@ $1',
 
 'disambiguations' => 'Страници, сочещи към пояснителни страници',
 'disambiguationspage' => 'Template:Пояснение',
-'disambiguations-text' => "Следните страници сочат към '''пояснителна страница''', вместо към истинската тематична страница.<br />Една страница се смята за пояснителна, ако ползва шаблон, към който се препраща от [[MediaWiki:Disambiguationspage]]",
+'disambiguations-text' => "Следните страници сочат към '''пояснителна страница''', вместо към истинската тематична страница.<br />Една страница се смята за пояснителна, ако ползва шаблон, към който се препраща от [[MediaWiki:Disambiguationspage]].",
 
 'doubleredirects' => 'Двойни пренасочвания',
 'doubleredirectstext' => 'Тази страница съдържа списък със страници, които пренасочват към друга пренасочваща страница.
@@ -2066,7 +2068,9 @@ $1',
 'linksearch-pat' => 'Търсене по:',
 'linksearch-ns' => 'Именно пространство:',
 'linksearch-ok' => 'Търсене',
-'linksearch-text' => 'Възможна е употребата на заместващи знаци като: „*.wikipedia.org“.<br />Поддържани протоколи: <code>$1</code>',
+'linksearch-text' => 'Възможна е употребата на заместващи знаци като: „*.wikipedia.org“.
+Необходим е поне домейн от най-високо ниво, например „*.org“.<br />
+{{PLURAL:$2|Поддържан протокол|Поддържани протоколи}}: <code>$1</code> (ако не е посочено, по подразбиране се използва http:// ).',
 'linksearch-line' => '$1 с препратка от $2',
 'linksearch-error' => 'Заместващите знаци могат да стоят само в началото на името на хоста.',
 
@@ -2288,8 +2292,8 @@ $UNWATCHURL
 'protect-cascadeon' => 'Тази страница е защитена против редактиране, защото е включена в {{PLURAL:$1|следната страница, която от своя страна има|следните страници, които от своя страна имат}} каскадна защита. Можете да промените нивото на защита на страницата, но това няма да повлияе върху каскадната защита.',
 'protect-default' => 'Позволяване за всички потребители',
 'protect-fallback' => 'Позволяване само за потребители с права на „$1“',
-'protect-level-autoconfirmed' => 'Ð\91локиÑ\80ане Ð½Ð° Ð½Ð¾Ð²Ð¸ Ð¸ Ð½ÐµÑ\80егиÑ\81Ñ\82Ñ\80иÑ\80ани потребители',
-'protect-level-sysop' => 'Само за администратори',
+'protect-level-autoconfirmed' => 'Ð\9fозволено Ñ\81амо Ð·Ð° Ð°Ð²Ñ\82омаÑ\82иÑ\87но Ð¾Ð´Ð¾Ð±Ñ\80ени потребители',
+'protect-level-sysop' => 'Ð\9fозволено Ñ\81амо за администратори',
 'protect-summary-cascade' => 'каскадно',
 'protect-expiring' => 'изтича на $1 (UTC)',
 'protect-expiring-local' => 'срок на изтичане $1',
@@ -2426,7 +2430,7 @@ $1',
 'whatlinkshere-hideredirs' => '$1 на пренасочващи страници',
 'whatlinkshere-hidetrans' => '$1 на включени страници',
 'whatlinkshere-hidelinks' => '$1 на препратки',
-'whatlinkshere-hideimages' => '$1 препратки към файла',
+'whatlinkshere-hideimages' => '$1 Ð½Ð° Ð¿Ñ\80епÑ\80аÑ\82ки ÐºÑ\8aм Ñ\84айла',
 'whatlinkshere-filters' => 'Филтри',
 
 # Block/unblock
@@ -2579,11 +2583,11 @@ $1',
 # Move page
 'move-page' => 'Преместване на $1',
 'move-page-legend' => 'Преместване на страница',
-'movepagetext' => "Ð\9fоÑ\81Ñ\80едÑ\81Ñ\82вом Ð´Ð¾Ð»Ð½Ð¸Ñ\8f Ñ\84оÑ\80мÑ\83лÑ\8fÑ\80 Ð¼Ð¾Ð¶ÐµÑ\82е Ð´Ð° Ð¿Ñ\80еименÑ\83ваÑ\82е Ñ\81Ñ\82Ñ\80аниÑ\86а, Ð¿Ñ\80емеÑ\81Ñ\82вайки Ñ\86Ñ\8fлаÑ\82а Ð¹ история на новото име. Старото заглавие ще се превърне в пренасочваща страница.
\9fÑ\80епÑ\80аÑ\82киÑ\82е ÐºÑ\8aм Ñ\81Ñ\82аÑ\80аÑ\82а Ñ\81Ñ\82Ñ\80аниÑ\86а Ð½Ñ\8fма Ð´Ð° Ð±Ñ\8aдаÑ\82 Ð¿Ñ\80оменени; Ð·Ð°Ñ\82ова Ð¿Ñ\80овеÑ\80еÑ\82е Ð·Ð° Ð´Ð²Ð¾Ð¹Ð½Ð¸ Ð¸Ð»Ð¸ Ð½ÐµÐ²Ð°Ð»Ð¸Ð´Ð½Ð¸ Ð¿Ñ\80енаÑ\81оÑ\87ваниÑ\8f.
-Вие сами би трябвало да се убедите в това, дали препратките продължават да сочат там, където се предполага.
+'movepagetext' => "Ð\98зползванеÑ\82о Ð½Ð° Ñ\84оÑ\80мÑ\83лÑ\8fÑ\80а Ð¿Ð¾-долÑ\83 Ñ\89е Ð¿Ñ\80еименÑ\83ва Ñ\81Ñ\82Ñ\80аниÑ\86а, ÐºÐ°Ñ\82о Ñ\81е Ð¿Ñ\80емеÑ\81Ñ\82и Ñ\86Ñ\8fлаÑ\82а Ñ\9d Ñ\80едакÑ\86ионна Ð¸Ñ\81Ñ\82оÑ\80иÑ\8f история на новото име. Старото заглавие ще се превърне в пренасочваща страница.
\9cоже Ð´Ð° Ñ\81е Ð¸Ð·Ð±ÐµÑ\80е Ð²Ñ\8aзможноÑ\81Ñ\82 Ð¿Ñ\80енаÑ\81оÑ\87ваниÑ\8fÑ\82а ÐºÑ\8aм Ð¾Ñ\80игиналноÑ\82о Ð·Ð°Ð³Ð»Ð°Ð²Ð¸Ðµ Ð´Ð° Ð±Ñ\8aдаÑ\82 Ð¾Ð±Ð½Ð¾Ð²ÐµÐ½Ð¸ Ð°Ð²Ñ\82омаÑ\82иÑ\87но. Ð\92 Ñ\81лÑ\83Ñ\87ай, Ñ\87е Ñ\82ази Ð²Ñ\8aзможноÑ\81Ñ\82 Ð½Ðµ Ðµ Ð¸Ð·Ð±Ñ\80ана, Ð¿Ñ\80епоÑ\80Ñ\8aÑ\87иÑ\82елно Ðµ Ð´Ð° Ñ\81е Ð¿Ñ\80овеÑ\80и Ð·Ð° [[Special:DoubleRedirects|двойни]] Ð¸Ð»Ð¸ [[Special:BrokenRedirects|невалидни Ð¿Ñ\80енаÑ\81оÑ\87ваниÑ\8f]].
+Вие сами би трябвало да се убедите в това дали препратките продължават да сочат там, където се предполага.
 
¡траницата '''няма''' да бъде преместена, ако вече съществува страница с новото име, освен ако е празна или пренасочване и няма редакционна история.
\9eбÑ\8aÑ\80неÑ\82е Ð²Ð½Ð¸Ð¼Ð°Ð½Ð¸Ðµ, Ñ\87е Ñ\81траницата '''няма''' да бъде преместена, ако вече съществува страница с новото име, освен ако е празна или пренасочване и няма редакционна история.
 
 '''ВНИМАНИЕ!'''
 Това може да е голяма и неочаквана промяна за известна страница. Уверете се, че разбирате последствията, преди да продължите.",
@@ -2972,7 +2976,10 @@ $1',
 'minutes' => '{{PLURAL:$1|$1 минута|$1 минути}}',
 'hours' => '{{PLURAL:$1|$1 час|$1 часа}}',
 'days' => '{{PLURAL:$1|$1 ден|$1 дни}}',
+'months' => '{{PLURAL:$1|един месец|$1 месеца}}',
+'years' => '{{PLURAL:$1|една година|$1 години}}',
 'ago' => 'преди $1',
+'just-now' => 'току що',
 
 # Bad image list
 'bad_image_list' => 'Спазва се следният формат:
@@ -3558,14 +3565,14 @@ MediaWiki се разпространява с надеждата, че ще б
 * <span class="mw-specialpagecached">Само складирани специални страници (възможно е да са остарели).</span>',
 'specialpages-group-maintenance' => 'Доклади по поддръжката',
 'specialpages-group-other' => 'Други специални страници',
-'specialpages-group-login' => 'Ð\92лизане / Ñ\80егиÑ\81Ñ\82Ñ\80иÑ\80ане',
+'specialpages-group-login' => 'Ð\92лизане / Ñ\81Ñ\8aздаване Ð½Ð° Ñ\81меÑ\82ка',
 'specialpages-group-changes' => 'Последни промени и дневници',
 'specialpages-group-media' => 'Доклади за файловете и качванията',
 'specialpages-group-users' => 'Потребители и права',
 'specialpages-group-highuse' => 'Широко използвани страници',
 'specialpages-group-pages' => 'Списъци на страниците',
 'specialpages-group-pagetools' => 'Инструменти за страниците',
-'specialpages-group-wiki' => 'Уики Ð´анни и инструменти',
+'specialpages-group-wiki' => 'Ð\94анни и инструменти',
 'specialpages-group-redirects' => 'Пренасочващи специални страници',
 'specialpages-group-spam' => 'Инструменти против спам',
 
@@ -3704,6 +3711,7 @@ $1 е автоматично повишен от $4 до $5',
 'api-error-ok-but-empty' => 'Вътрешна грешка: Няма отговор от сървъра.',
 'api-error-overwrite' => 'Не е позволено презаписването върху съществуващ файл.',
 'api-error-stashfailed' => 'Вътрешна грешка: Сървърът не успя да съхрани временния файл.',
+'api-error-publishfailed' => 'Вътрешна грешка: Сървърът не успя да съхрани временния файл.',
 'api-error-timeout' => 'Сървърът не отговори в рамките на предвиденото време.',
 'api-error-unclassified' => 'Възникна непозната грешка.',
 'api-error-unknown-code' => 'Непозната грешка: "$1"',
index f5c45ed..48d18c0 100644 (file)
@@ -211,6 +211,7 @@ $1',
 'disclaimerpage' => 'Project:सामान्य अस्विकरण',
 'edithelp' => 'मदद सम्पादन',
 'edithelppage' => 'Help:सम्पादन',
+'helppage' => 'मदद:सामग्री',
 'mainpage' => 'मुख्य पन्ना',
 'mainpage-description' => 'पहिलका पन्ना',
 'portal' => 'सामुदायिक पन्ना',
@@ -642,7 +643,7 @@ Legend: '''({{int:cur}})''' = हाल के संशोधन के सा
 'tooltip-pt-mytalk' => 'राउर वार्ता पन्ना',
 'tooltip-pt-preferences' => 'राउर पसन्द',
 'tooltip-pt-mycontris' => 'राउर योगदान के सूची',
-'tooltip-pt-login' => 'रà¤\89à¤\86 à¤\95à¥\87 à¤\96ाता à¤ªà¥\8dरवà¥\87श à¤\96ातिर à¤ªà¥\8dरà¥\8bतà¥\8dसाहित à¤\95रल à¤\9cा à¤°à¤¹à¤² à¤¬à¤¾, à¤¬à¤¾à¤\81à¤\95ि à¤\88 à¤\85निवारà¥\8dय à¤¨à¤\88à¤\96à¥\87',
+'tooltip-pt-login' => 'रउआ के खाता प्रवेश खातिर प्रोत्साहित करल जा रहल बा, बाकि ई अनिवार्य नईखे',
 'tooltip-pt-anonlogin' => 'रउआ के खाता प्रवेश खातिर प्रोत्साहित करल जा रहल बा, बाँकि ई अनिवार्य नईखे',
 'tooltip-pt-logout' => 'खाता से बाहर',
 'tooltip-ca-talk' => 'सामग्री पन्ना के बारे में बात-चीत',
index 838e0be..c425d6a 100644 (file)
@@ -17,6 +17,7 @@
  * @author Prometheus.pyrphoros
  * @author RIPENDIL
  * @author Reedy
+ * @author Runab
  * @author Samritmaity
  * @author Sayak Sarkar
  * @author Sm faysal
@@ -2044,7 +2045,7 @@ Maybe you want to edit the description on its [$2 file description page] there.'
 'usermessage-editor' => 'সিস্টেম ম্যাসেঞ্জার',
 
 # Watchlist
-'watchlist' => 'à¦\86মার à¦¨à¦\9cর à¦¤à¦¾à¦²à¦¿à¦\95া',
+'watchlist' => 'নজর তালিকা',
 'mywatchlist' => 'নজর তালিকা',
 'watchlistfor2' => '$1 ($2)-এর জন্য',
 'nowatchlist' => 'আপনার নজরতালিকা খালি।',
index 3d00bf1..28f9d5b 100644 (file)
@@ -1117,8 +1117,8 @@ $1",
 'diff-multi' => '({{PLURAL:$1|پیاچوونەوەیەکی نێوانی|$1 پیاچوونەوەی نێوانی}}ی {{PLURAL:$2|بەکارھێنەرێک|$2 بەکارھێنەر}} نیشان نەدراوە)',
 
 # Search results
-'searchresults' => 'ئەنجامەکانی گەڕان',
-'searchresults-title' => 'ئەنجامەکانی گەڕان بۆ "$1"',
+'searchresults' => 'ئاکامەکانی گەڕان',
+'searchresults-title' => 'ئاکامەکانی گەڕان بۆ «$1»',
 'searchresulttext' => 'بۆ زانیاری زیاتر دەربارەی گەڕان {{SITENAME}} ، بڕوانە لە  [[{{MediaWiki:Helppage}}|{{int:help}}]].',
 'searchsubtitle' => "گەڕایت بۆ '''[[:$1]]''' ([[Special:Prefixindex/$1|ھەموو ئەو پەڕانەی بە «$1»ەوە دەستپێدەکەن]]{{int:pipe-separator}}[[Special:WhatLinksHere/$1|ھەموو ئەو پەڕانەی بەستەریان ھەیە بۆ «$1»]])",
 'searchsubtitleinvalid' => "گەڕایت بۆ '''$1'''",
@@ -1964,7 +1964,7 @@ $1',
 # Special:ActiveUsers
 'activeusers' => 'پێرستی بەکارھێنەرە چالاکەکان',
 'activeusers-intro' => 'ئەمە لیستێکی ئەو بەکارھێنەرانەیە کە لە  $1 {{PLURAL:$1|ڕۆژ|ڕۆژ}}ی ڕابردوودا بە جۆرێک چالاکییەکیان ھەبووە.',
-'activeusers-count' => '$1 گۆڕانکاری لە دوایین {{PLURAL:$3|ڕۆژدا|$3 ڕۆژدا}}',
+'activeusers-count' => '$1 {{PLURAL:$1|کردەوە}} لە دوایین {{PLURAL:$3|ڕۆژ|$3 ڕۆژ}}دا',
 'activeusers-from' => 'نیشاندانی بەکارھێنەران بە دەستپێکردن لە:',
 'activeusers-hidebots' => 'بۆتەکان بشارەوە',
 'activeusers-hidesysops' => 'بەڕێوبەران بشارەوە',
@@ -2024,7 +2024,7 @@ $1',
 'usermessage-editor' => 'پەیامنێری سیستەم',
 
 # Watchlist
-'watchlist' => 'پێرستی چاودێرییەکانم',
+'watchlist' => 'پێرستی چاودێری',
 'mywatchlist' => 'پێرستی چاودێری',
 'watchlistfor2' => 'بۆ $1 $2',
 'nowatchlist' => 'لە لیستی چاودێڕییەکانتدا ھیچ نیە.',
@@ -2115,7 +2115,7 @@ $UNWATCHURL
 'historywarning' => "'''وشیار بە:''' پەڕەیەک کە دەتەوێ بیسڕیتەوە مێژوویەکی ھەیە بە نزیکەی $1 {{PLURAL:$1|پێداچوونەوە|پێداچوونەوە}}وە:",
 'confirmdeletetext' => 'تۆ خەریکی پەڕەیەک بە ھەموو مێژووەکەیەوە دەسڕیتەو.
 تکایە پشتڕاستی بکەوە کە دەتەوێت ئەم کارە بکەی، لە ئاکامەکەی تێدەگەی، و ئەم کارە بە پێی [[{{MediaWiki:Policy-url}}|سیاسەتنامە]] ئەنجام دەدەی.',
-'actioncomplete' => 'کردەوە بە ئاکام گەیشت',
+'actioncomplete' => 'کردەوە بە ئاکام گەییشت',
 'actionfailed' => 'کردارەکە سەرنەکەوت',
 'deletedtext' => '«$1»  سڕایەوە.
 سەیری $2 بکە بۆ تۆمارێکی دوایین سڕینەوەکان.',
@@ -2188,7 +2188,7 @@ $UNWATCHURL
 'protect-default' => 'بە ھەموو بەکارھێنەران ڕێگە بدە',
 'protect-fallback' => 'پێویستی بە ئیزنی «$1» ھەیە',
 'protect-level-autoconfirmed' => 'بەکارھێنەرانی نوێ و تۆمارنەکراو ئاستەنگ بکە',
-'protect-level-sysop' => 'تەنھا بەڕێوەبەران',
+'protect-level-sysop' => 'تەنیا بەڕێوەبەران',
 'protect-summary-cascade' => 'تاڤگەیی',
 'protect-expiring' => 'بەسەردەچێ لە ڕێکەوتی $1 (UTC)',
 'protect-expiring-local' => 'بە سەر دەچێ لە $1',
@@ -3299,8 +3299,8 @@ $5
 # Hijri month names
 'hijri-calendar-m1' => 'موحەڕەم',
 'hijri-calendar-m2' => 'سەفەر',
-'hijri-calendar-m3' => 'ڕەبيع ئەلئەووەڵ',
-'hijri-calendar-m4' => 'ڕەبيع ئەسسانی',
+'hijri-calendar-m3' => 'ڕەبیعەلئەووەڵ',
+'hijri-calendar-m4' => 'ڕەبیعەلئاخیر',
 'hijri-calendar-m5' => 'جومادەلئەووەل',
 'hijri-calendar-m6' => 'جومادەسسانی',
 'hijri-calendar-m7' => 'ڕەجەب',
@@ -3376,7 +3376,7 @@ $5
 'specialpages-group-highuse' => 'پەڕە زۆر بەکار ھێنراوەکان',
 'specialpages-group-pages' => 'پێرستەکانی پەڕەکان',
 'specialpages-group-pagetools' => 'ئامرازەکانی پەڕە',
-'specialpages-group-wiki' => 'دراوەکان و ئامرازەکانی ویکی',
+'specialpages-group-wiki' => 'دراوەکان و ئامرازەکان',
 'specialpages-group-redirects' => 'پەڕە تایبەتەکانی رەوانکردنەوە',
 'specialpages-group-spam' => 'ئامرازەکانی سپەم',
 
index d410db6..4df9899 100644 (file)
@@ -549,7 +549,7 @@ Sylwer y bydd rhai tudalennau yn parhau i ymddangos fel ag yr oeddent pan oeddec
 'gotaccount' => "Oes cyfrif gennych eisoes? '''$1'''.",
 'gotaccountlink' => 'Mewngofnodwch',
 'userlogin-resetlink' => 'Ydych chi wedi anghofio eich manylion mewngofnodi?',
-'createaccountmail' => 'trwy e-bost',
+'createaccountmail' => "Defnyddier cyfrinair ar hap dros dro a'i anfon i'r cyfeiriad e-bost isod",
 'createaccountreason' => 'Rheswm:',
 'badretype' => "Nid yw'r cyfrineiriau'n union yr un fath.",
 'userexists' => 'Mae rhywun arall wedi dewis yr enw defnyddiwr hwn. 
@@ -831,9 +831,10 @@ Rydych chi'n cadarnhau mai chi yw awdur y cyfraniad, neu eich bod chi wedi'i gop
 '''PEIDIWCH Â CHYFRANNU GWAITH O DAN HAWLFRAINT HEB GANIATÂD!'''",
 'longpageerror' => "'''GWALL: Mae'r testun yr ydych wedi ei osod yma yn {{PLURAL:$1|$1 cilobeit}} o hyd, ac yn hwy na'r hyd eithaf o {{PLURAL:$2|$2}} cilobeit.
 Ni ellir ei roi ar gadw.'''",
-'readonlywarning' => "'''RHYBUDD: Mae'r databas wedi'i gloi am gyfnod er mwyn cynnal a chadw, felly fyddwch chi ddim yn gallu cadw'ch golygiadau ar hyn o bryd. Rydyn ni'n argymell eich bod chi'n copïo a gludo'r testun i ffeil a'i gadw ar eich disg tan bod y sustem yn weithredol eto.'''
+'readonlywarning' => "'''RHYBUDD: Mae'r gronfa ddata wedi'i chloi am gyfnod er mwyn cynnal a chadw, felly fyddwch chi ddim yn gallu cadw'ch golygiadau ar hyn o bryd.''' 
+Gallwch gopïo'r testun a'i gludo i ffeil destun er mwyn ei gadw tan yn hwyrach.
 
-Cynigiodd y gweinyddwr a glodd y databas y rheswm hwn dros ei gloi: $1",
+Cynigiodd y gweinyddwr a glodd y gronfa ddata y rheswm hwn dros ei chloi: $1",
 'protectedpagewarning' => "'''RHYBUDD: Mae'r dudalen hon wedi'i diogelu. Dim ond gweinyddwyr sydd yn gallu ei golygu.'''
 Dyma'r cofnod lòg diweddaraf, er gwybodaeth:",
 'semiprotectedpagewarning' => "'''Sylwer:''' Mae'r dudalen hon wedi ei chloi; dim ond defnyddwyr cofrestredig a allant ei golygu.
@@ -870,6 +871,9 @@ Ymddengys iddi gael ei dileu.",
 'edit-already-exists' => 'Ni ellid creu tudalen newydd.
 Mae ar gael yn barod.',
 'defaultmessagetext' => 'Y testun rhagosodedig',
+'content-failed-to-parse' => "Ni lwyddwyd i ddosrannu'r cynnwys sydd ar ffurf $2 yn ôl y model $1: $3",
+'invalid-content-data' => "Data annilys i'r cynnwys",
+'content-not-allowed-here' => 'Nid yw cynnwys ar ffurf "$1" yn cael ei ganiatau ar y dudalen [[$2]]',
 
 # Content models
 'content-model-wikitext' => 'cystrawen wici',
@@ -1132,7 +1136,7 @@ Mae manylion pellach i'w cael yn [{{fullurl:{{#Special:Log}}/delete|page={{FULLP
 'search-interwiki-default' => 'Y canlyniadau o $1:',
 'search-interwiki-more' => '(rhagor)',
 'search-relatedarticle' => 'Erthyglau eraill tebyg',
-'mwsuggest-disable' => 'Analluogi awgrymiadau AJAX',
+'mwsuggest-disable' => 'Analluogi awgrymiadau chwilio',
 'searcheverything-enable' => 'Chwilio pob parth',
 'searchrelated' => 'erthyglau eraill tebyg',
 'searchall' => 'oll',
@@ -1626,6 +1630,7 @@ Os yw'r broblem yn parhau, cysylltwch â [[Special:ListUsers/sysop|gweinyddwr]].
 'backend-fail-notsame' => "Mae ffeil gwahanol a'r enw $1 arni eisoes ar gael.",
 'backend-fail-invalidpath' => 'Nid yw $1 yn lwybr dilys i roi ffeil ar gadw.',
 'backend-fail-delete' => "Wedi methu dileu'r ffeil $1.",
+'backend-fail-describe' => 'Ni lwyddwyd newid metadata\'r ffeil "$1".',
 'backend-fail-alreadyexists' => "Mae'r ffeil $1 ar gael yn barod.",
 'backend-fail-store' => "Wedi methu rhoi'r ffeil $1 ar gadw yn $2.",
 'backend-fail-copy' => "Wedi methu copïo'r ffeil $1 i $2.",
@@ -2027,7 +2032,7 @@ Mae angen parth lefel-uchaf o leiaf, er enghraifft "*.org".<br />
 # Special:ActiveUsers
 'activeusers' => 'Rhestr defnyddwyr gweithgar',
 'activeusers-intro' => 'Dyma restr y defnyddwyr a fuont yn weithgar o fewn y {{PLURAL:$1|diwrnod|diwrnod|deuddydd|tridiau|$1 diwrnod|$1 diwrnod}} diwethaf.',
-'activeusers-count' => '$1 {{PLURAL:$1|golygiad|golygiad|olygiad|golygiad|golygiad|golygiad}} yn ystod y {{PLURAL:$3|diwrnod|diwrnod|deuddydd|tridiau|$3 diwrnod|$3 diwrnod}} diwethaf',
+'activeusers-count' => '$1 {{PLURAL:$1|golygiad|golygiad|olygiad|golygiad}} yn ystod y {{PLURAL:$3|diwrnod|diwrnod|deuddydd|tridiau|$3 diwrnod}} diwethaf',
 'activeusers-from' => "Rhestru'r defnyddwyr gan ddechrau gyda:",
 'activeusers-hidebots' => 'Cuddio botiau',
 'activeusers-hidesysops' => 'Cuddio gweinyddwyr',
@@ -2091,7 +2096,7 @@ Bydd y cyfeiriad e-bost a osodoch yn eich [[Special:Preferences|dewisiadau]] yn
 'usermessage-editor' => 'Golygydd neges y system',
 
 # Watchlist
-'watchlist' => 'Fy rhestr wylio',
+'watchlist' => 'Rhestr wylio',
 'mywatchlist' => 'Rhestr wylio',
 'watchlistfor2' => 'Yn ôl gofyn $1 $2',
 'nowatchlist' => "Mae eich rhestr wylio'n wag.",
@@ -2135,6 +2140,10 @@ Pan fydd y dudalen hon, neu ei thudalen sgwrs, yn newid, fe fyddant yn ymddangos
 'enotif_subject_restored' => 'Adferwyd y dudalen $1 ar {{SITENAME}} gan {{gender:$2|$2}}',
 'enotif_subject_changed' => 'Newidiwyd y dudalen $1 ar {{SITENAME}} gan {{gender:$2|$2}}',
 'enotif_body_intro_deleted' => 'Dilewyd y dudalen $1 ar {{SITENAME}} ar $PAGEEDITDATE gan {{gender:$2|$2}}, gweler $3.',
+'enotif_body_intro_created' => 'Dechrëwyd y dudalen $1 ar {{SITENAME}} ar $PAGEEDITDATE gan {{gender:$2|$2}}. Gweler y diwygiad cyfredol ohoni ar $3.',
+'enotif_body_intro_moved' => 'Symudwyd y dudalen $1 ar {{SITENAME}} ar $PAGEEDITDATE gan {{gender:$2|$2}}. Gweler y diwygiad cyfredol ar $3.',
+'enotif_body_intro_restored' => 'Adferwyd y dudalen $1 ar {{SITENAME}} ar $PAGEEDITDATE gan {{gender:$2|$2}}. Gweler y diwygiad cyfredol ohoni ar $3.',
+'enotif_body_intro_changed' => 'Newidiwyd y dudalen $1 ar {{SITENAME}} ar $PAGEEDITDATE gan {{gender:$2|$2}}. Gweler y diwygiad cyfredol ohoni ar $3.',
 'enotif_lastvisited' => 'Gwelwch $1 am bob newid ers eich ymweliad blaenorol.',
 'enotif_lastdiff' => 'Gallwch weld y newid ar $1.',
 'enotif_anon_editor' => 'defnyddiwr anhysbys $1',
@@ -2250,9 +2259,9 @@ Dyma'r gosodiadau diogelu cyfredol ar gyfer y dudalen '''$1''':",
 Dyma'r gosodiadau diogelu cyfredol ar gyfer y dudalen '''$1''':",
 'protect-cascadeon' => "Mae'r dudalen hon wedi ei diogelu ar hyn o bryd oherwydd ei bod wedi ei chynnwys yn y {{PLURAL:$1|dudalen|dudalen|tudalennau|tudalennau|tudalennau|tudalennau}} canlynol sydd wedi {{PLURAL:$1|ei|ei|eu|eu|eu|eu}} sgydol-diogelu.  Gallwch newid lefel diogelu'r dudalen hon, ond ni fydd hynny'n effeithio ar y sgydol-ddiogelu.",
 'protect-default' => "Caniatáu'r gallu i bob defnyddiwr",
-'protect-fallback' => 'Mynnu\'r gallu "$1"',
-'protect-level-autoconfirmed' => "Blocio defnyddwyr newydd a'r rhai heb gyfrif",
-'protect-level-sysop' => 'Gweinyddwyr yn unig',
+'protect-fallback' => 'Caniatau i\'r defnyddwyr gyda\'r gallu "$1" yn unig wneud hyn',
+'protect-level-autoconfirmed' => "Caniatau'r defnyddwyr sydd wedi eu cadarnhau'n awtomatig yn unig",
+'protect-level-sysop' => 'Gweinyddwyr yn unig caiff wneud',
 'protect-summary-cascade' => 'sgydol',
 'protect-expiring' => 'yn dod i ben am $1 (UTC)',
 'protect-expiring-local' => 'yn dod i ben am $1',
@@ -2547,17 +2556,18 @@ Er mwyn cloi'r gronfa ddata neu ei datgloi, mae'n rhaid i'r gweinydd gwe allu ys
 # Move page
 'move-page' => 'Symud $1',
 'move-page-legend' => 'Symud tudalen',
-'movepagetext' => "Drwy ddefnyddio'r ffurflen isod, byddwch yn ailenwi tudalen, felly yn symud ei holl hanes i'r enw tudalen newydd.
-Caiff yr hen deitl a oedd ar y dudalen ei droi'n dudalen sy'n ailgyfeirio i'r teitl newydd.
+'movepagetext' => "Drwy ddefnyddio'r ffurflen isod, byddwch yn ailenwi tudalen, ac felly yn symud ei holl hanes i'r dudalen a'r enw newydd.
+Caiff y dudalen a'r hen deitl ei throi'n dudalen sy'n ailgyfeirio i'r teitl newydd.
 Gallwch ddiweddaru tudalennau ailgyfeirio sy'n cyfeirio at y teitl gwreiddiol yn awtomatig.
-Os ydych yn dewis peidio â gwneud hyn, gwiriwch [[Special:BrokenRedirects|dudalennau ailgyfeirio nad ydynt yn ailgyfeirio]] neu [[Special:DoubleRedirects|dudalennau ailgyfeirio dwbl]].
-Chi sy'n gyfrifol am wirio bod cysylltiadau yn cyfeirio at y tudalennau cywir.
+Os ydych yn dewis peidio â gwneud hyn, gwiriwch [[Special:DoubleRedirects|dudalennau ailgyfeirio dwbl]] neu 
+[[Special:BrokenRedirects|dudalennau ailgyfeirio nad ydynt yn ailgyfeirio]].
+Chi sy'n gyfrifol am sicrhau bod cysylltiadau yn cyfeirio at y tudalennau cywir.
 
-Sylwer '''na''' chaiff y dudalen ei symud os oes enw ar y dudalen yn bodoli'n barod, oni bai ei bod hi'n wag neu'n dudalen ailgyfeirio ac nad oes hanes golygu ganddi.
-Mae hyn yn golygu y gallwch ailenwi tudalen yn ôl os yr ydych yn gwneud camgymeriad, ond nid ydych yn gallu trosysgrifo tudalen sy'n bodoli'n barod.
+Sylwer '''na''' chaiff y dudalen ei symud os oes tudalen a'r enw newydd ar gael yn barod, oni bai bod y dudalen a'r enw newydd yn dudalen ailgyfeirio ac nad oes hanes golygu ganddi.
+Mae hyn yn golygu y gallwch ailenwi tudalen yn ôl i'w henw gwreiddiol os ydych yn gwneud camgymeriad, ond na allwch drosysgrifo tudalen sy'n bodoli'n barod.
 
 '''Rhybudd!'''
-Gall hwn greu newid annisgwyl a chryf i dudalen boblogaidd;
+Gall hwn fod yn newid mawr ac annisgwyl i dudalen boblogaidd;
 gwnewch yn siŵr eich bod yn deall canlyniadau'r broses hon cyn i chi barhau.",
 'movepagetext-noredirectfixer' => "Wrth ddefnyddio'r ffurflen isod byddwch yn ail-enwi tudalen, gan symud ei hanes gyfan i'r enw newydd.
 Bydd yr hen deitl yn troi'n dudalen ailgyfeirio i'r teitl newydd.
@@ -2870,6 +2880,7 @@ Achos hyn yn fwy na thebyg yw presenoldeb cysylltiad i wefan ar y rhestr wahardd
 'pageinfo-robot-noindex' => 'Ni ellir ei rhestru gan beiriannau chwilio',
 'pageinfo-views' => 'Nifer yr ymweliadau',
 'pageinfo-watchers' => 'Nifer gwylwyr y dudalen',
+'pageinfo-few-watchers' => 'Llai na $1 {{PLURAL:$1|gwyliwr|gwyliwr|wyliwr|gwyliwr|o wylwyr}}',
 'pageinfo-redirects-name' => "Nifer yr ailgyfeiriadau i'r dudalen hon",
 'pageinfo-subpages-name' => "Nifer yr is-dudalennau i'r dudalen hon",
 'pageinfo-subpages-value' => '$1 ($2 {{PLURAL:$2|ailgyfeiriad}}; $3 {{PLURAL:$3|is-dudalen arall}})',
@@ -2939,6 +2950,7 @@ Mae'n bosib y bydd eich cyfrifiadur yn cael ei danseilio wrth ddefnyddio'r ffeil
 'file-nohires' => 'Wedi ei chwyddo hyd yr eithaf.',
 'svg-long-desc' => 'Ffeil SVG, maint mewn enw $1 × $2 picsel, maint y ffeil: $3',
 'svg-long-desc-animated' => 'Ffeil SVG animeiddiedig, maint mewn enw $1 × $2 picsel, maint y ffeil: $3',
+'svg-long-error' => 'Ffeil SVG annilys: $1',
 'show-big-image' => 'Maint llawn',
 'show-big-image-preview' => 'Maint y rhagolwg: $1.',
 'show-big-image-other' => '{{PLURAL:$2|Datrysiad arall|Datrysiad arall|Datrysiadau eraill|Datrysiadau eraill|Datrysiadau eraill|Datrysiadau eraill}}: $1.',
@@ -3569,6 +3581,7 @@ Gallwch hefyd [[Special:EditWatchlist|ddefnyddio\'r rhestr arferol]].',
 'version-license' => 'Trwydded',
 'version-poweredby-credits' => "Mae'r wici hwn wedi'i nerthu gan '''[//www.mediawiki.org/ MediaWiki]''', hawlfraint © 2001 - $1 $2.",
 'version-poweredby-others' => 'eraill',
+'version-credits-summary' => 'Hoffem gydnabod cyfraniad y bobl canlynol i [[Special:Version|MediaWiki]].',
 'version-license-info' => "Meddalwedd rhydd yw MediaWiki; gallwch ei ddefnyddio a'i addasu yn ôl termau'r GNU General Public License a gyhoeddir gan Free Software Foundation; naill ai fersiwn 2 o'r Drwydded, neu unrhyw fersiwn diweddarach o'ch dewis.
 
 Cyhoeddir MediaWiki yn y gobaith y bydd o ddefnydd, ond HEB UNRHYW WARANT; heb hyd yn oed gwarant ymhlyg o FARCHNADWYEDD nag o FOD YN ADDAS AT RYW BWRPAS ARBENNIG. Gweler y GNU General Public License am fanylion pellach.
@@ -3614,7 +3627,7 @@ Dangosir delweddau ar eu maint llawn, dechreuir ffeiliau o fathau eraill yn unio
 'specialpages-group-highuse' => 'Tudalennau aml eu defnydd',
 'specialpages-group-pages' => 'Rhestrau tudalennau',
 'specialpages-group-pagetools' => 'Offer trin tudalennau',
-'specialpages-group-wiki' => 'Data ac offer y wici',
+'specialpages-group-wiki' => 'Data ac offer',
 'specialpages-group-redirects' => 'Tudalennau arbennig ailgyfeirio',
 'specialpages-group-spam' => 'Offer sbam',
 
index da49af5..c6f969d 100644 (file)
@@ -1217,7 +1217,7 @@ Detaljer kan findes i [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}
 'search-interwiki-default' => '{{PLURAL:$1|et resultat|$1 resultater}}:',
 'search-interwiki-more' => '(mere)',
 'search-relatedarticle' => 'Relateret',
-'mwsuggest-disable' => 'Slå AJAX-forslag fra',
+'mwsuggest-disable' => 'Slå søgningsforslag fra',
 'searcheverything-enable' => 'Søg i alle navnerum',
 'searchrelated' => 'relateret',
 'searchall' => 'alle',
@@ -2636,7 +2636,17 @@ Se [[Special:BlockList|blokeringslisten]] for den nuværende liste med aktuelle
 # Move page
 'move-page' => 'Flyt $1',
 'move-page-legend' => 'Flyt side',
-'movepagetext' => "Når du bruger formularen herunder vil du få omdøbt en side og flyttet hele sidens historie til det nye navn. Den gamle titel vil blive en omdirigeringsside til den nye titel. Henvisninger til den gamle titel vil ikke blive ændret. Sørg for at tjekke for dobbelte eller dårlige omdirigeringer. Du er ansvarlig for, at alle henvisninger stadig peger derhen, hvor det er meningen de skal pege. Bemærk at siden '''ikke''' kan flyttes hvis der allerede er en side med den nye titel, medmindre den side er tom eller er en omdirigering uden nogen historie. Det betyder at du kan flytte en side tilbage hvor den kom fra, hvis du kommer til at lave en fejl. <b>ADVARSEL!</b> Dette kan være en drastisk og uventet ændring for en populær side; vær sikker på, at du forstår konsekvenserne af dette før du fortsætter.",
+'movepagetext' => "Når du bruger formularen herunder, vil du få omdøbt en side og flyttet hele sidens historie til det nye navn.
+Den gamle titel vil blive en omdirigeringsside til den nye titel.
+Du kan opdatere omdirigeringer, der peger på den oprindelige titel, automatisk.
+Hvis du vælger ikke at opdatere dem automatisk, så sørg for at tjekke efter [[Special:DoubleRedirects|dobbelte]] eller [[Special:BrokenRedirects|dårlige omdirigeringer]].
+Du er ansvarlig for, at alle henvisninger stadig peger derhen, hvor det er meningen de skal pege.
+
+Bemærk at siden '''ikke''' kan flyttes, hvis der allerede er en side med den nye titel, medmindre den side er en omdirigering uden nogen redigeringshistorik.
+Det betyder, at du kan flytte en side tilbage hvor den kom fra, hvis du kommer til at lave en fejl, og det betyder, at du ikke kan overskrive en eksisterende side.
+
+'''ADVARSEL!'''
+Dette kan være en drastisk og uventet ændring for en populær side; vær sikker på, at du forstår konsekvenserne af dette før du fortsætter.",
 'movepagetext-noredirectfixer' => "Brug formularen herunder du vil omdøbe en side og flyttet hele sidens historie til det nye navn.
 Den gamle titel vil blive en omdirigeringsside til den nye titel.
 Vær sikker på at tjekke for [[Special:DoubleRedirects|dobbelte]] eller [[Special:BrokenRedirects|ødelagte omdirigeringer]].
@@ -2954,6 +2964,7 @@ Dette skyldes sandsynligvis en henvisning til et sortlistet eksternt websted.',
 'pageinfo-robot-noindex' => 'Ikke indekserbar',
 'pageinfo-views' => 'Antal visninger',
 'pageinfo-watchers' => 'Antal brugere, der overvåger siden',
+'pageinfo-few-watchers' => 'Overvåget af færre end $1 {{PLURAL:$1|bruger|brugere}}',
 'pageinfo-redirects-name' => 'Omdirigeringer til denne side',
 'pageinfo-subpages-name' => 'Undersider til denne side',
 'pageinfo-subpages-value' => '$1 ($2 {{PLURAL:$2|omdirigering|omdirigeringer}}; $3 {{PLURAL:$3|der ikke er en omdirigering|der ikke er omdirigeringer}})',
index ff2e770..88182c6 100644 (file)
@@ -781,7 +781,7 @@ Die Daten werden bis auf Weiteres nicht erneuert.',
 Funktion: $1<br />
 Abfrage: $2',
 'viewsource' => 'Quelltext anzeigen',
-'viewsource-title' => 'Quelltext von Seite $1 ansehen',
+'viewsource-title' => 'Quelltext der Seite $1',
 'actionthrottled' => 'Aktionsanzahl limitiert',
 'actionthrottledtext' => 'Im Rahmen einer Anti-Spam-Maßnahme kann diese Aktion in einem kurzen Zeitabstand nur begrenzt oft ausgeführt werden. Diese Grenze hast du überschritten.
 Bitte versuche es in ein paar Minuten erneut.',
@@ -1434,7 +1434,7 @@ Einzelheiten sind im [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}}
 'search-interwiki-default' => '$1 Ergebnisse:',
 'search-interwiki-more' => '(weitere)',
 'search-relatedarticle' => 'Verwandte',
-'mwsuggest-disable' => 'Vorschläge per Ajax deaktivieren',
+'mwsuggest-disable' => 'Suchvorschläge deaktivieren',
 'searcheverything-enable' => 'In allen Namensräumen suchen',
 'searchrelated' => 'verwandt',
 'searchall' => 'alle',
@@ -3203,6 +3203,7 @@ Das liegt wahrscheinlich an einem Link auf eine externe Seite.',
 'pageinfo-robot-noindex' => 'Nicht indexierbar',
 'pageinfo-views' => 'Anzahl der Seitenaufrufe',
 'pageinfo-watchers' => 'Anzahl der Beobachter der Seite',
+'pageinfo-few-watchers' => 'Weniger als {{PLURAL:$1|ein|$1}} Beobachter',
 'pageinfo-redirects-name' => 'Weiterleitungen zu dieser Seite',
 'pageinfo-redirects-value' => '$1',
 'pageinfo-subpages-name' => 'Unterseiten dieser Seite',
index 3aa37e5..72d3adf 100644 (file)
@@ -1181,7 +1181,7 @@ Eke şıma serkari u devam bıkeri [$1 no vurnayiş şıma eşkeni bıvini].",
 Îdarekarî eşkeno ena dif bivîne; belki tiya de [{{fullurl:{{#Special:Log}}/suppress|page={{FULLPAGENAMEE}}}} ploxnayış] de teferruat esto.",
 'rev-delundel' => 'bımocne/bınımne',
 'rev-showdeleted' => 'bımocne',
-'revisiondelete' => 'Bıestere/çımraviyarnayışan peyser bia',
+'revisiondelete' => 'Bestere/çımraviyarnayışan peyser bia',
 'revdelete-nooldid-title' => 'Çımraviyarnayışo waşte nêvêreno',
 'revdelete-nooldid-text' => 'Şıma vıraştışê nê fonksiyoni rê ya yew çımraviyarnayışo waşte diyar nêkerdo, çımraviyarnayışo diyarkerde çıniyo, ya ki şıma wazenê ke çımraviyarnayışê nıkayêni bınımnê.',
 'revdelete-nologtype-title' => 'Qet qeydê cınêdiya',
@@ -1557,7 +1557,7 @@ Kaberê bini ke şıma de kewti irtıbat, adresa e-postey şıma eşkera nêbena
 'right-reupload-own' => 'Dosyeyê ke to bar kerdi, inan sero bınuse',
 'right-reupload-shared' => 'Dosyeyê ke ambarê medyao barekerde de, inan mehelli wedare',
 'right-upload_by_url' => 'Yew URL ra dosyan bar bıke',
-'right-purge' => 'Verde ju pela araşt kerdışi hafızay sita besterne',
+'right-purge' => 'Virê sita seba yew pele bêdestur bestere.',
 'right-autoconfirmed' => 'Pelanê ke nême kılit biyê, inan bıvurne',
 'right-bot' => 'Zey yew karê xoserkerdey be',
 'right-nominornewtalk' => 'Pelanê werênayışan rê vurnayışê qıckeki çıniyê, qutiya mesacanê newiyan bıgurene',
@@ -1627,7 +1627,7 @@ Kaberê bini ke şıma de kewti irtıbat, adresa e-postey şıma eşkera nêbena
 'action-upload_by_url' => 'Ena dosya yew URL ra bar bike',
 'action-writeapi' => 'ser nuşte API gure bike',
 'action-delete' => 'ena perer besternê',
-'action-deleterevision' => 'nê çımraviyarnayışi bıestere',
+'action-deleterevision' => 'nê çımraviyarnayışi bestere',
 'action-deletedhistory' => 'tarixê ena pel ki estereyî biya, ey bivine',
 'action-browsearchive' => 'pelanê esterıteyan bıgeyre',
 'action-undelete' => 'ena pele reyna biyere',
@@ -1960,7 +1960,7 @@ keyepel nıka zaf meşğulo yew dema herayi de newe ra tesel bıkerê.',
 'file-anchor-link' => 'Dosya',
 'filehist' => 'Ravêrdê dosya',
 'filehist-help' => 'bıploxne ser yew tarih u aye tarih dı versionê dosya bıvin.',
-'filehist-deleteall' => 'hemî biestere',
+'filehist-deleteall' => 'pêro bestere',
 'filehist-deleteone' => 'bestere',
 'filehist-revert' => 'reyna biyere',
 'filehist-current' => 'nıkayên',
@@ -2009,8 +2009,8 @@ listeya ke ha ver a têna na {{PLURAL:$1|dosyaya ewwili|dosyaya $1 ewwili}} mocn
 'filerevert-badversion' => 'Vesiyonê lokalê verniyê eno dosya pê ena pulêwext de çin o.',
 
 # File deletion
-'filedelete' => '$1 bıestere',
-'filedelete-legend' => 'Dosya bıestere',
+'filedelete' => '$1 bestere',
+'filedelete-legend' => 'Dosya bestere',
 'filedelete-intro' => "Ti ho dosyayê '''[[Media:$1|$1]]'''i u tarixê ey dosyayê hemî estereno.",
 'filedelete-intro-old' => "Ti ho versiyonê '''[[Media:$1|$1]]'''i [$4 $3, $2] estereno.",
 'filedelete-comment' => 'Sebeb:',
@@ -2393,13 +2393,13 @@ Qey hemkari u pêşniyazi:
 'changed' => 'vurneya',
 
 # Delete
-'deletepage' => 'Pele bıestere',
+'deletepage' => 'Pele bestere',
 'confirm' => 'Testiq ke',
 'excontent' => "behso kêm: '$1'",
 'excontentauthor' => "behso kêm: '$1' no/na ('[[Special:Contributions/$2|$2]]'  teyna iştıraq kerdo)",
 'exbeforeblank' => "behsê verê esteriyayişi: '$1'",
 'exblank' => 'zerreyê peli vengo',
-'delete-confirm' => '"$1" bıestere',
+'delete-confirm' => '"$1" bestere',
 'delete-legend' => 'Bestere',
 'historywarning' => "'''Teme:''' Pela ke şıma esterenê tede yew viyarte be teqriben $1 {{PLURAL:$1|versiyon esto|versiyoni estê}}:",
 'confirmdeletetext' => 'Tı ho yew pele u tarixê pele wederneno.
@@ -2839,11 +2839,11 @@ Yewna name bınus.',
 'movenosubpage' => 'pelê bınıni yê no peli çino.',
 'movereason' => 'Sebeb:',
 'revertmove' => 'peyser bia',
-'delete_and_move' => 'Biestere u bere',
+'delete_and_move' => 'Bestere u bere',
 'delete_and_move_text' => '==gani hewn a bıbıo/bıesteriyo==
 
 " no [[:$1]]" name de yew pel ca ra esto. şıma wazeni pê hewn a kerdışê ey peli vurnayişê nameyi bıkeri?',
-'delete_and_move_confirm' => 'Ya, ena pele biestere',
+'delete_and_move_confirm' => 'Heya, na pele bestere',
 'delete_and_move_reason' => '"[[$1]]" qey vurnayişê nameyi esteriya',
 'selfmove' => 'name yo ke şıma wazeni bıbo, ın name û name yo ke ca ra esto eyni yê /zepê yê. vurnayiş mumkin niyo.',
 'immobile-source-namespace' => '"$1" pelê cayi de nameyi nêkırışyenî',
@@ -4340,7 +4340,7 @@ Ma rica keno tesdiq bike ke ti raştî wazeno eno pel bivirazo.",
 
 # action=purge
 'confirm_purge_button' => 'Temam',
-'confirm-purge-top' => 'Cacheyê eno pel biestere?',
+'confirm-purge-top' => 'Vervirê na pele bestere?',
 'confirm-purge-bottom' => 'Purge kerdişê yew pel cacheyî estereno u revizyonê penîyî mucneno.',
 
 # action=watch/unwatch
index 47ccadb..e18bf80 100644 (file)
@@ -588,7 +588,7 @@ Móžoš {{SITENAME}} anomymnje dalej wužywaś abo móžoš <span class='plainl
 'gotaccount' => "Maš južo wužywarske konto? '''$1'''.",
 'gotaccountlink' => 'Pśizjawiś se',
 'userlogin-resetlink' => 'Sy pśizjawjeńske daty zabył?',
-'createaccountmail' => 'z e-mailku',
+'createaccountmail' => 'Nachylne pśidatne gronidło wužywaś a jo na slědujucu e-mailowu adresu pósłaś',
 'createaccountreason' => 'Pśicyna:',
 'badretype' => 'Šćitnej gronidle, kótarejž sy zapódał, se njemakajotej.',
 'userexists' => 'Wužywarske mě se južo wužywa.
@@ -795,7 +795,7 @@ Jo se snaź pśesunuł abo wulašował, mjaztym až woglědujoš se bok.',
 Gronidło za toś to nowe konto dajo se na boku ''[[Special:ChangePassword|Gronidło změniś]]'' pśi pśizjawjenju změniś.",
 'newarticle' => '(Nowy nastawk)',
 'newarticletext' => "Sy slědował wótkaz na bok, kótaryž hyšći njeeksistěrujo.
-Aby bok napórał, zapiš do kašćika dołojce (glědaj [[{{MediaWiki:Helppage}}|bok pomocy]] za dalšne informacije). Jolic sy zamólnje how, klikni na tłocašk '''Slědk'' w swójom wobglědowaku.",
+Aby bok napórał, zapiš do kašćika dołojce (glědaj [[{{MediaWiki:Helppage}}|bok pomocy]] za dalšne informacije). Jolic sy zamólnje how, klikni na tłocašk '''Slědk''' w swójom wobglědowaku.",
 'anontalkpagetext' => "---- ''Toś jo diskusijny bok za anonymnego wužywarja, kótaryž njejo dotychměst žedno wužywarske konto załožył abo swójo konto njewužywa. Togodla dejmy numerisku IP-adresu wužywaś, aby jogo/ju identificěrowali. Taka IP-adresa dajo se wót wšakich wužywarjow wužywaś. Jolic sy anonymny wužywaŕ a se mysliš, až su se njerelewantne komentary na tebje měrili, [[Special:UserLogin/signup|załož konto]] abo [[Special:UserLogin|pśizjaw se]], aby se w pśichoźe zmuśenje z drugimi anonymnymi wužywarjami wobinuł.''",
 'noarticletext' => 'Dotychměst toś ten bok hyšći njewopśimujo žeden tekst. Móžoš w drugich bokach [[Special:Search/{{PAGENAME}}|titel togo boka pytaś]], <span class="plainlinks">[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} wótpowědne protokole pytaś] abo [{{fullurl:{{FULLPAGENAME}}|action=edit}} toś ten bok wobźěłaś]</span>.',
 'noarticletext-nopermission' => 'Tuchylu njejo žeden tekst na toś tom boku.
@@ -859,7 +859,8 @@ Ty teke wobkšuśijoš, až sy tekst sam napisał abo sy jen wót public domainy
 '''NJEWÓZJAW WÓT COPYRIGHTA ŠĆITANE ŹĚŁA MIMO DOWÓLNOSĆI!'''",
 'copyrightwarning2' => "Pšosym buź se togo wědobny, až wšykne pśinoski na {{SITENAME}} mógu wót drugich wužywarjow se wobźěłaś, narownaś abo wulašowaś. Jolic až njocoš, až twój tekst se mimo zmilnosći wobźěłujo, ga pón jen how njeskładuj.<br /> Ty teke wobkšuśijoš, až sy tekst sam napisał abo sy jen wót public domainy resp. wót pódobneje lichotneje resursy kopěrował (glědaj $1 za dalše detaile). '''NJEWÓZJAW WÓT COPYRIGHTA ŠĆITANE ŹĚŁA MIMO DOWÓLNOSĆI!'''",
 'longpageerror' => "'''Zmólka: Tekst, kótaryž coš składowaś, jo {{PLURAL:$1| jaden kilobajt|$1 kilobajta|$1 kilobajty|$1 kilobajtow}} wjeliki. To jo wěcej ako dowólony maksimum {{PLURAL:$2|jaden kilobajt|$1 kilobajta|$1 kilobajty|$1 kilobajtow}}.''' Składowanje njejo móžno.",
-'readonlywarning' => "'''WARNOWANJE: Datowa banka jo se za wótwardowanje zacyniła, togodla njebuźo tuchylu móžno, twóje změny składowaś. Jolic až coš, ga móžoš tekst do tekstoweje dataje kopěrowaś a pózdźej składowaś.'''
+'readonlywarning' => "'''WARNOWANJE: Datowa banka jo se za wótwardowanje zacyniła, togodla njebuźo tuchylu móžno, twóje změny składowaś.'''
+Jolic coš, ga móžoš tekst do tekstoweje dataje kopěrowaś a pózdźej składowaś.
 
 Administrator, kenž jo ju zastajił, su toś tu pśicynu pódał: $1",
 'protectedpagewarning' => "'''Warnowanje: Toś ten bok jo se zastajił, tak až jano wužywarje z pšawami administratora mógu jen wobźěłaś.'''
@@ -2053,7 +2054,7 @@ Jo nanejmjenjej głowna domena trěbna, na pśikład "*.org"<br />
 # Special:ActiveUsers
 'activeusers' => 'Lisćina aktiwnych wužywarjow',
 'activeusers-intro' => 'To jo lisćina wužywarjow, kotrež su byli aktiwne za {{PLURAL:$1|slědny źeń|slědnej $1 dnja|slědne $1 dny|slědnych $1 dnjow}}.',
-'activeusers-count' => '$1 {{PLURAL:$1|změna|změnje|změny|změnow}} w {{PLURAL:$3|slědnem dnju|slědnyma $3 dnjoma|slědnych $3 dnjach|slědnych $3 dnjach}}',
+'activeusers-count' => '$1 {{PLURAL:$1|akcija|akciji|akcije|akcijow}} w {{PLURAL:$3|slědnem dnju|slědnyma $3 dnjoma|slědnych $3 dnjach}}',
 'activeusers-from' => 'Wužywarjow zwobrazniś, zachopinajucy z:',
 'activeusers-hidebots' => 'Boty schowaś',
 'activeusers-hidesysops' => 'Administratorow schowaś',
@@ -2563,7 +2564,7 @@ Móžoš awtomatiski aktualizěrowaś dalejposrědkowanja, kótarež pokazuju na
 Jolic njocoš, pśeglědaj za [[Special:DoubleRedirects|dwójnymi]] abo [[Special:BrokenRedirects|defektnymi daleposrědkowanjami]].
 Sy zagronity, až wótkaze wjedu tam, źož maju wjasć.
 
-Źiwaj na to, až se bok '''nje'''pśesuwa, jolic jo južo bok z nowym titelom, snaźkuli jo prozny abo dalejpósrědnjenje a njama stare wobźěłane wersije. To ma groniś, až móžoš bok zasej slědk pśemjenjowaś, jolic cyniš zmólku, a njemóžoš eksistěrujucy bok pśepisaś.
+Źiwaj na to, až se bok '''nje'''pśesuwa, jolic jo južo bok z nowym titelom, snaźkuli slědny jo dalejpósrědnjenje a njama stare wobźěłane wersije. To ma groniś, až móžoš bok zasej slědk pśemjenjowaś, jolic cyniš zmólku, a njemóžoš eksistěrujucy bok pśepisaś.
 
 '''WARNOWANJE!'''
 To móžo byś drastiska a njewocakowana změna za popularny bok;
@@ -3651,7 +3652,7 @@ Wobraze se w połnym wótgranicowanju pokazuju, druge datajowe typy se ze zwěza
 'specialpages-group-highuse' => 'Cesto wužywane boki',
 'specialpages-group-pages' => 'Lisćiny bokow',
 'specialpages-group-pagetools' => 'Rědy bokow',
-'specialpages-group-wiki' => 'Wikijowe daty a rědy',
+'specialpages-group-wiki' => 'Daty a rědy',
 'specialpages-group-redirects' => 'Dalej pósrědnjajuce boki',
 'specialpages-group-spam' => 'Spamowe rědy',
 
@@ -3748,6 +3749,7 @@ Wobraze se w połnym wótgranicowanju pokazuju, druge datajowe typy se ze zwěza
 'logentry-newusers-newusers' => 'Wužywarske konto $1 jo se załožyło',
 'logentry-newusers-create' => 'Wužywarske konto $1 jo se załožyło',
 'logentry-newusers-create2' => '$1 jo załožył wužywarske konto $3',
+'logentry-newusers-byemail' => 'Wužywarske konto $3 jo se wót $1 załožyło a gronidło jo se pśez e-mail pósłało.',
 'logentry-newusers-autocreate' => 'Konto $1 jo se awtomatiski załožyło',
 'logentry-rights-rights' => '$1 jo kupkowe cłonkojstwo za $3 z $4 do $5 změnił',
 'logentry-rights-rights-legacy' => '$1 jo kupkowe cłonkojstwo za $3 změnił',
@@ -3806,6 +3808,7 @@ Hować móžoš slědujucy jadnory formular wužywaś. Twój komentar pśidajo s
 'api-error-ok-but-empty' => 'Nutśikowna zmólka: Žedne wótegrono wót serwera.',
 'api-error-overwrite' => 'Pśepisowanje eksistujuceje dataje njejo dowólone.',
 'api-error-stashfailed' => 'Nutśikowna zmólka: Serwer njejo mógał temporernu dataju składowaś.',
+'api-error-publishfailed' => 'Nutśkowna zmólka: Serwer njejo mógł nachylnu dataju wozjawiś.',
 'api-error-timeout' => 'Serwer njejo we wócakanem casu wótgronił.',
 'api-error-unclassified' => 'Njeznata zmólka jo nastała.',
 'api-error-unknown-code' => 'Njeznata zmólka: "$1"',
index 5579fc8..180b191 100644 (file)
@@ -488,6 +488,7 @@ $messages = array(
 'newwindow' => '(ανοίγει σε ξεχωριστό παράθυρο)',
 'cancel' => 'Ακύρωση',
 'moredotdotdot' => 'Περισσότερα...',
+'morenotlisted' => 'Περισσότερα δεν αναφέρονται...',
 'mypage' => 'Σελίδα',
 'mytalk' => 'Συζήτηση',
 'anontalk' => 'Οι συζητήσεις αυτής της διεύθυνσης IP',
@@ -853,6 +854,7 @@ $2',
 # E-mail sending
 'php-mail-error-unknown' => 'Άγνωστο σφάλμα στη συνάρτηση mail() της PHP.',
 'user-mail-no-addy' => 'Προσπαθήσατε να στείλετε e-mail χωρίς μια διεύθυνση e-mail.',
+'user-mail-no-body' => 'Προσπάθησε να στείλει e-mail με ένα κενό ή αδικαιολόγητα σύντομο σώμα.',
 
 # Change password dialog
 'resetpass' => 'Αλλαγή κωδικού πρόσβασης',
@@ -1341,7 +1343,7 @@ $1",
 'viewprevnext' => 'Εμφάνιση ($1 {{int:pipe-separator}} $2) ($3).',
 'searchmenu-legend' => 'Επιλογές αναζήτησης',
 'searchmenu-exists' => "'''Υπάρχει μια σελίδα που ονομάζεται \"[[:\$1]]\" σε αυτό το wiki'''",
-'searchmenu-new' => "'''Δημιουργήστε τη σελίδα \"[[:\$1]]\" σε αυτό το wiki!'''",
+'searchmenu-new' => "'''Δημιουργήστε τη σελίδα «[[:$1]]» σε αυτό το wiki!'''",
 'searchhelp-url' => 'Help:Περιεχόμενα',
 'searchmenu-prefix' => '[[Special:PrefixIndex/$1|Πλοηγηθείτε σε σελίδες με αυτό το πρόθεμα]]',
 'searchprofile-articles' => 'Σελίδες περιεχομένων',
@@ -1364,14 +1366,14 @@ $1",
 'search-interwiki-default' => '$1 αποτελέσματα:',
 'search-interwiki-more' => '(περισσότερα)',
 'search-relatedarticle' => 'Σχετικά',
-'mwsuggest-disable' => 'Î\91Ï\80ενεÏ\81γοÏ\80οίηÏ\83η Ï\84Ï\89ν Ï\80Ï\81οÏ\84άÏ\83εÏ\89ν AJAX',
+'mwsuggest-disable' => 'Î\91Ï\80ενεÏ\81γοÏ\80οίηÏ\83η Ï\80Ï\81οÏ\84άÏ\83εÏ\89ν Î±Î½Î±Î¶Î®Ï\84ηÏ\83ηÏ\82',
 'searcheverything-enable' => 'Αναζήτηση σε όλες τις περιοχές ονομάτων',
 'searchrelated' => 'σχετικά',
 'searchall' => 'όλα',
 'showingresults' => "Δείτε παρακάτω μέχρι τα {{PLURAL:$1|'''1'''αποτέλεσμα|'''$1''' αποτελέσματα}} ξεκινώντας με #'''$2'''.",
 'showingresultsnum' => "Εμφάνιση {{PLURAL:$3|'''1''' αποτελέσματος|'''$3''' αποτελεσμάτων}} αρχίζοντας με #'''$2'''.",
 'showingresultsheader' => "{{PLURAL:$5|Αποτέλεσμα '''$1''' από '''$3'''|Αποτελέσματα '''$1 - $2''' από '''$3'''}} για '''$4'''",
-'nonefound' => "'''ΣημείÏ\89Ï\83η''': Î\9fι Î±Î½ÎµÏ\80ιÏ\84Ï\85Ï\87είÏ\82 Î±Î½Î±Î¶Î·Ï\84ήÏ\83ειÏ\82 Î¿Ï\86είλονÏ\84αι Ï\83Ï\85νήθÏ\89Ï\82 Ï\83Ï\84ο Ï\8cÏ\84ι Î­Ï\87οÏ\85με Ï\83Ï\85μÏ\80εÏ\81ιλάβει Ï\83Ï\84α ÎºÏ\81ιÏ\84ήÏ\81ια Î¼Ï\8cνο Ï\83Ï\85γκεκÏ\81ιμένεÏ\82 Ï\80εÏ\81ιοÏ\87έÏ\82 Î¿Î½Î¿Î¼Î¬Ï\84Ï\89ν. Î\94οκιμάÏ\83Ï\84ε Î½Î± Ï\80Ï\81οÏ\83θέÏ\83εÏ\84ε Ï\84ο Ï\80Ï\81Ï\8cθεμα ''all:'' - ''Ï\8cλα:'' Ï\83Ï\84ην Î±Î½Î±Î¶Î®Ï\84ηÏ\83η Î³Î¹Î± Î½Î± Ï\88άξεÏ\84ε Ï\83ε Ï\8cλα Ï\84α Ï\80εÏ\81ιεÏ\87Ï\8cμενα (Ï\83Ï\85μÏ\80εÏ\81ιλαμβανÏ\8cμενÏ\89ν Ï\84Ï\89ν Ï\83ελίδÏ\89ν Ï\83Ï\85ζηÏ\84ήÏ\83εÏ\89Ï\82, Ï\80Ï\81οÏ\84á½\90Ï\80Ï\89ν ÎºÏ\84λ.) Î® Ï\87Ï\81ηÏ\83ιμοÏ\80οιήÏ\83Ï\84ε Ï\84ην ÎµÏ\80ιθÏ\85μηÏ\84ή Ï\80εÏ\81ιοÏ\87ή Î¿Î½Î¿Î¼Î¬Ï\84Ï\89ν.",
+'nonefound' => "'''ΣημείÏ\89Ï\83η''': Î\9fι Î±Î½ÎµÏ\80ιÏ\84Ï\85Ï\87είÏ\82 Î±Î½Î±Î¶Î·Ï\84ήÏ\83ειÏ\82 Î¿Ï\86είλονÏ\84αι Ï\83Ï\85νήθÏ\89Ï\82 Ï\83Ï\84ο Ï\8cÏ\84ι Î­Ï\87οÏ\85με Ï\83Ï\85μÏ\80εÏ\81ιλάβει Ï\83Ï\84α ÎºÏ\81ιÏ\84ήÏ\81ια Î¼Ï\8cνο Ï\83Ï\85γκεκÏ\81ιμένοÏ\85Ï\82 Î¿Î½Î¿Î¼Î±Ï\84οÏ\87Ï\8eÏ\81οÏ\85Ï\82. Î\94οκιμάÏ\83Ï\84ε Î½Î± Ï\80Ï\81οÏ\83θέÏ\83εÏ\84ε Ï\84ο Ï\80Ï\81Ï\8cθεμα ''all:'' - ''Ï\8cλα:'' Ï\83Ï\84ην Î±Î½Î±Î¶Î®Ï\84ηÏ\83η Î³Î¹Î± Î½Î± Ï\88άξεÏ\84ε Ï\83ε Ï\8cλα Ï\84α Ï\80εÏ\81ιεÏ\87Ï\8cμενα (Ï\83Ï\85μÏ\80εÏ\81ιλαμβανÏ\8cμενÏ\89ν Ï\84Ï\89ν Ï\83ελίδÏ\89ν Ï\83Ï\85ζηÏ\84ήÏ\83εÏ\89Ï\82, Ï\80Ï\81οÏ\84Ï\8dÏ\80Ï\89ν ÎºÏ\84λ.) Î® Ï\87Ï\81ηÏ\83ιμοÏ\80οιήÏ\83Ï\84ε Ï\84ον ÎµÏ\80ιθÏ\85μηÏ\84Ï\8c Î¿Î½Î¿Î¼Î±Ï\84οÏ\87Ï\8eÏ\81ο.",
 'search-nonefound' => 'Δεν υπάρχουν αποτελέσματα που να ταιριάζουν με την αναζήτησή σας.',
 'powersearch' => 'Αναλυτική αναζήτηση',
 'powersearch-legend' => 'Αναλυτική αναζήτηση',
@@ -2052,11 +2054,11 @@ $1',
 
 # Random page
 'randompage' => 'Τυχαία σελίδα',
-'randompage-nopages' => 'Δεν υπάρχουν σελίδες σε {{PLURAL:$2|αυτή την περιοχή ονομάτων|αυτές τις περιοχές ονομάτων}}: $1.',
+'randompage-nopages' => 'Δεν υπάρχουν σελίδες {{PLURAL:$2|στον ακόλουθο ονοματοχώρο|στους ακόλουθους ονοματοχώρους}}: $1.',
 
 # Random redirect
 'randomredirect' => 'Τυχαία ανακατεύθυνση',
-'randomredirect-nopages' => 'Δεν υπάρχουν ανακατευθύνσεις σε αυτή την περιοχή ονόματος "$1".',
+'randomredirect-nopages' => 'Δεν υπάρχουν ανακατευθύνσεις στον ονοματοχώρο "$1".',
 
 # Statistics
 'statistics' => 'Στατιστικά',
@@ -2138,7 +2140,7 @@ $1',
 'mostinterwikis' => 'Σελίδες με τους περισσότερους διαγλωσσικούς συνδέσμους',
 'mostrevisions' => 'Άρθρα με τις περισσότερες αναθεωρήσεις',
 'prefixindex' => 'Όλες οι σελίδες με πρόθεμα',
-'prefixindex-namespace' => 'Όλες οι σελίδες με πρόθεμα (περιοχής  $1)',
+'prefixindex-namespace' => 'Όλες οι σελίδες με πρόθεμα (ονοματοχώρος $1)',
 'shortpages' => 'Σύντομες σελίδες',
 'longpages' => 'Εκτενείς σελίδες',
 'deadendpages' => 'Αδιέξοδες σελίδες',
@@ -2199,7 +2201,7 @@ $1',
 'allpagesfrom' => 'Εμφάνιση σελίδων που αρχίζουν από:',
 'allpagesto' => 'Εμφάνιση σελίδων που λήγουν σε:',
 'allarticles' => 'Όλα τα άρθρα',
-'allinnamespace' => 'Î\8cλεÏ\82 Î¿Î¹ Ï\83ελίδεÏ\82 (Ï\83Ï\84ην Ï\80εÏ\81ιοÏ\87ή $1)',
+'allinnamespace' => 'Î\8cλεÏ\82 Î¿Î¹ Ï\83ελίδεÏ\82 (Ï\83Ï\84ον Î¿Î½Î¿Î¼Î±Ï\84οÏ\87Ï\8eÏ\81ο $1)',
 'allnotinnamespace' => 'Όλες οι σελίδες (που δεν βρίσκονται στην περιοχή $1)',
 'allpagesprev' => 'Προηγούμενες',
 'allpagesnext' => 'Επόμενες',
@@ -2248,7 +2250,7 @@ $1',
 # Special:ActiveUsers
 'activeusers' => 'Κατάλογος ενεργών χρηστών',
 'activeusers-intro' => 'Αυτή είναι μια λίστα από χρήστες που είχαν κάποιου είδους δραστηριότητα {{PLURAL:$1|την τελευταία $1 μέρα|τις τελευταίες $1 μέρες}}.',
-'activeusers-count' => '$1 {{PLURAL:$1|ενέργεια|ενέργειες}} τις τελευταίες {{PLURAL:$3|μέρα|$3 μέρες}}',
+'activeusers-count' => '$1 {{PLURAL:$1|ενέργεια|ενέργειες}} {{PLURAL:$3|την τελευταία μέρα|τις τελευταίες $3 μέρες}}',
 'activeusers-from' => 'Προβολή χρηστών ξεκινώντας από:',
 'activeusers-hidebots' => 'Απόκρυψη bots',
 'activeusers-hidesysops' => 'Απόκρυψη διαχειριστών',
@@ -2460,6 +2462,7 @@ $UNWATCHURL
 'prot_1movedto2' => 'Η [[$1]] μετακινήθηκε στη θέση [[$2]]',
 'protect-badnamespace-title' => 'Μη-προστατευόμενη ομάδα σελίδων',
 'protect-badnamespace-text' => 'Οι  σελίδες σε αυτόν τον ονοματοχώρο δεν μπορούν να κλειδωθούν.',
+'protect-norestrictiontypes-title' => 'Μη-προστατευόμενη σελίδα',
 'protect-legend' => 'Επιβεβαίωση κλειδώματος',
 'protectcomment' => 'Αιτία:',
 'protectexpiry' => 'Λήξη',
@@ -2566,11 +2569,11 @@ $1',
 'undelete-show-file-submit' => 'Ναι',
 
 # Namespace form on various pages
-'namespace' => 'ΠεÏ\81ιοÏ\87ή:',
+'namespace' => 'Î\9fνομαÏ\84οÏ\87Ï\8eÏ\81οÏ\82:',
 'invert' => 'Αντιστροφή της επιλογής',
 'tooltip-invert' => 'Επιλέξτε αυτό το πλαίσιο για να αποκρύψετε αλλαγές σε σελίδες μέσα στον επιλεγμένο χώρο ονομάτων (και των συσχετικών χώρων ονομάτων, εάν επιλεγχθούν)',
 'namespace_association' => 'Συσχετισμένος ονοματοχώρος',
-'tooltip-namespace_association' => 'Επιλέξτε αυτό το πλαίσιο για να συμπεριλάβετε τον χώρο ονομάτων συζήτησης ή θέματος που σχετίζονται με τον επιλεγμένο χώρο ονομάτων',
+'tooltip-namespace_association' => 'Επιλέξτε αυτό το κουτάκι για να συμπεριλάβετε τον ονοματοχώρο συζήτησης ή θέματος που σχετίζεται με τον επιλεγμένο ονοματοχώρο',
 'blanknamespace' => '(Αρχική περιοχή)',
 
 # Contributions
@@ -2606,7 +2609,7 @@ $1',
 'whatlinkshere-page' => 'Σελίδα:',
 'linkshere' => "Οι ακόλουθες σελίδες συνδέουν στη σελίδα '''[[:$1]]''':",
 'nolinkshere' => "Δεν υπάρχουν σελίδες που να συνδέουν στη σελίδα '''[[:$1]]'''.",
-'nolinkshere-ns' => "Î\9aαμία Ï\83ελίδα Î´ÎµÎ½ Ï\83Ï\85νδέει Ï\83Ï\84ο '''[[:$1]]''' Ï\83Ï\84ην ÎµÏ\80ιλεγμένη Ï\80εÏ\81ιοÏ\87ή Î¿Î½Î¿Î¼Î¬Ï\84Ï\89ν.",
+'nolinkshere-ns' => "Î\9aαμία Ï\83ελίδα Î´ÎµÎ½ Ï\83Ï\85νδέει Ï\83Ï\84ο '''[[:$1]]''' Ï\83Ï\84ον ÎµÏ\80ιλεγμένο Î¿Î½Î¿Î¼Î±Ï\84οÏ\87Ï\8eÏ\81ο.",
 'isredirect' => 'σελίδα ανακατεύθυνσης',
 'istemplate' => 'ενσωμάτωση',
 'isimage' => 'σύνδεσμος αρχείου',
@@ -2774,7 +2777,8 @@ $1',
 Αν επιλέξετε να μην ενημερωθούν αυτόματα, μην ξεχάσετε να ελέγξετε για [[Special:DoubleRedirects|διπλές]] ή [[Special:BrokenRedirects|κατεστραμμένες ανακατευθύνσεις]].
 Είναι δική σας ευθύνη να επιβεβαιώσετε ότι οι σύνδεσμοι εξακολουθούν να δείχνουν προς τη σωστή κατεύθυνση.
 
-Λάβετε υπόψιν σας ότι η σελίδα '''δεν''' θα μετακινηθεί αν υπάρχει ήδη μια άλλη σελίδα υπό το νέο τίτλο, εκτός αν η σελίδα αυτή είναι κενή ή ανακατεύθυνση και δεν έχει ιστορικό επεξεργασίας.
+Λάβετε υπόψιν σας ότι η σελίδα '''δεν''' θα μετακινηθεί αν υπάρχει ήδη μια άλλη σελίδα υπό το νέο τίτλο, εκτός αν η σελίδα αυτή είναι ανακατεύθυνση και δεν έχει ιστορικό επεξεργασίας.
+
 Αυτό σημαίνει ότι σε περίπτωση λάθους μπορείτε να μετονομάσετε ξανά μια σελίδα δίνοντας της την αρχική της ονομασία αλλά δεν μπορείτε να αντικαταστήσετε μια υπάρχουσα σελίδα.
 
 '''ΠΡΟΣΟΧΗ!'''
@@ -2838,8 +2842,8 @@ $1',
 'delete_and_move_confirm' => 'Ναι, διέγραψε τη σελίδα',
 'delete_and_move_reason' => 'Διαγράφηκε για να δημιουργήσει χώρο για μετακίνηση από το "[[$1]]"',
 'selfmove' => 'Ο τίτλος προέλευσης είναι ο ίδιος με τον τίτλο προορισμού -δεν είναι δυνατόν να μετακινηθεί μια σελίδα προς τον εαυτό της.',
-'immobile-source-namespace' => 'Î\94εν Î¼Ï\80οÏ\81οÏ\8dν Î½Î± Î¼ÎµÏ\84ακινηθοÏ\8dν Ï\83ελίδεÏ\82 Ï\83Ï\84η Ï\80εÏ\81ιοÏ\87ή "$1"',
-'immobile-target-namespace' => 'Î\94εν Î¼Ï\80οÏ\81οÏ\8dν Î½Î± Î¼ÎµÏ\84ακινηθοÏ\8dν Ï\83ελίδεÏ\82 Ï\83Ï\84ην Ï\80εÏ\81ιοÏ\87ή "$1"',
+'immobile-source-namespace' => 'Î\94εν Î¼Ï\80οÏ\81οÏ\8dν Î½Î± Î¼ÎµÏ\84ακινηθοÏ\8dν Ï\83ελίδεÏ\82 Ï\83Ï\84ον Î¿Î½Î¿Î¼Î±Ï\84οÏ\87Ï\8eÏ\81ο "$1"',
+'immobile-target-namespace' => 'Î\94εν Î¼Ï\80οÏ\81οÏ\8dν Î½Î± Î¼ÎµÏ\84ακινηθοÏ\8dν Ï\83ελίδεÏ\82 Ï\83Ï\84ον Î¿Î½Î¿Î¼Î±Ï\84οÏ\87Ï\8eÏ\81ο "$1"',
 'immobile-target-namespace-iw' => 'Ο σύνδεσμος-interwiki δεν είναι έγκυρος στόχος για την μετακίνηση σελίδας.',
 'immobile-source-page' => 'Αυτή η σελίδα δεν είναι δυνατό να μετακινηθεί.',
 'immobile-target-page' => 'Δεν μπορεί να μετακινηθεί σε αυτόν τον τίτλο.',
@@ -2920,7 +2924,7 @@ $1',
 'import-interwiki-history' => 'Αντιγραφή όλων των εκδόσεων του ιστορικού για αυτή τη σελίδα',
 'import-interwiki-templates' => 'Συμπερίληψη όλων των προτύπων',
 'import-interwiki-submit' => 'Εισαγωγή',
-'import-interwiki-namespace' => 'ΠÏ\81οοÏ\81ιÏ\83μÏ\8cÏ\82 Ï\83Ï\84ην Ï\80εÏ\81ιοÏ\87ή Î¿Î½Î¿Î¼Î¬Ï\84Ï\89ν:',
+'import-interwiki-namespace' => 'ΠÏ\81οοÏ\81ιÏ\83μÏ\8cÏ\82 Ï\83Ï\84ον Î¿Î½Î¿Î¼Î±Ï\84οÏ\87Ï\8eÏ\81ο:',
 'import-upload-filename' => 'Όνομα αρχείου:',
 'import-comment' => 'Σχόλιο:',
 'importtext' => 'Παρακαλούμε εξάγετε το αρχείο από το πηγαίο wiki (χρησιμοποιώντας το [[Special:Export|εργαλείο εξαγωγής]]), αποθηκεύστε το στον υπολογιστή σας και μεταφορτώστε το από εκεί.',
@@ -3132,6 +3136,7 @@ $1',
 'pageinfo-protect-cascading' => 'Οι προστασίες ξεκινούν τη διαδοχή τους από εδώ',
 'pageinfo-protect-cascading-yes' => 'Ναι',
 'pageinfo-protect-cascading-from' => 'Οι προστασίες ξεκινούν τη διαδοχή τους από',
+'pageinfo-category-info' => 'Πληροφορίες κατηγορίας',
 'pageinfo-category-pages' => 'Αριθμός σελίδων',
 'pageinfo-category-subcats' => 'Αριθμός υποκατηγοριών',
 'pageinfo-category-files' => 'Αριθμός αρχείων',
@@ -3216,6 +3221,8 @@ $1',
 'minutes' => '{{PLURAL:$1|$1 λεπτό|$1 λεπτά}}',
 'hours' => '{{PLURAL:$1|$1 ώρα|$1 ώρες}}',
 'days' => '{{PLURAL:$1|$1 μέρα|$1 μέρες}}',
+'months' => '{{PLURAL:$1|$1 μήνας|$1 μήνες}}',
+'years' => '{{PLURAL:$1|$1 έτος|$1 έτη}}',
 'ago' => '$1 πριν',
 'just-now' => 'μόλις τώρα',
 
@@ -3666,42 +3673,51 @@ $1',
 'confirmemail_loggedin' => 'Η ηλεκτρονική σας διεύθυνση επαληθεύτηκε.',
 'confirmemail_error' => 'Παρουσιάστηκε λάθος κατά την αποθήκευση των ρυθμίσεών σας.',
 'confirmemail_subject' => 'Επαλήθευση ηλεκτρονικής διεύθυνσης του {{SITENAME}}',
-'confirmemail_body' => 'Κάποιος -πιθανόν εσείς- από τη διεύθυνση IP $1, δημιούργησε στον ιστότοπο {{SITENAME}} το λογαριασμό χρήστη "$2" με αυτή την ηλεκτρονική διεύθυνση.
+'confirmemail_body' => 'Κάποιος, πιθανότατα εσείς, από τη διεύθυνση IP $1,
+δημιούργησε λογαριασμό χρήστη «$2»
+με αυτήν τη διεύθυνση ηλεκτρονικού ταχυδρομείου στον ιστότοπο {{SITENAME}}.
 
-Για να επιβεβαιώσετε ότι αυτός ο λογαριασμός χρήστη ανήκει πραγματικά σε εσάς και για να ενεργοποιηθούν οι δυνατότητες e-mail του {{SITENAME}}, ακολουθήστε αυτό το σύνδεσμο:
+Για να επιβεβαιώσετε ότι αυτός ο λογαριασμός χρήστη ανήκει πραγματικά σε σας και να ενεργοποιήσετε
+τις δυνατότητες ηλεκτρονικού ταχυδρομείου στον ιστότοπο {{SITENAME}}, ανοίξτε στον περιηγητή σας αυτόν το σύνδεσμο:
 
 $3
 
-Αν *δεν* δημιουργήσατε εσείς το συγκεκριμένο λογαριασμό, ακολουθήστε τον παρακάτω σύνδεσμο για να ακυρώσετε την επιβεβαίωση της διεύθυνσης e-mail:
+Εάν *δεν* δημιουργήσατε εσείς το λογαριασμό χρήστη, ακολουθήστε αυτόν τον σύνδεσμο
+για να ακυρώσετε την επιβεβαίωση της διεύθυνσης ηλεκτρονικού ταχυδρομείου:
 
 $5
 
-Ο κωδικός επιβεβαίωσης θα λήξει στις $4.',
-'confirmemail_body_changed' => 'Κάποιος - πιθανόν εσείς - από τη διεύθυνση IP $1, άλλαξε στον ιστότοπο {{SITENAME}} την ηλεκτρονική διεύθυνση του λογαριασμού χρήστη "$2".
+Αυτός ο κωδικός επιβεβαίωσης θα λήξει στις $6, στις $7.',
+'confirmemail_body_changed' => 'Κάποιος, πιθανότατα εσείς, από τη διεύθυνση IP $1,
+άλλαξε τη διεύθυνση ηλεκτρονικού ταχυδρομείου του λογαριασμού χρήστη «$2»
+σε αυτήν τη διεύθυνση ηλεκτρονικού ταχυδρομείου στον ιστότοπο {{SITENAME}}.
 
-Για να επιβεβαιώσετε ότι αυτός ο λογαριασμός χρήστη ανήκει πραγματικά σε εσάς και για να ενεργοποιηθούν οι δυνατότητες e-mail του {{SITENAME}}, ακολουθήστε αυτό το σύνδεσμο:
+Για να επιβεβαιώσετε ότι αυτός ο λογαριασμός χρήστη ανήκει πραγματικά σε σας και να ενεργοποιήσετε πάλι
+τις δυνατότητες ηλεκτρονικού ταχυδρομείου στον ιστότοπο {{SITENAME}}, ανοίξτε στον περιηγητή σας αυτόν το σύνδεσμο:
 
 $3
 
-Αν ο λογαριασμός *δεν* ανήκει σε σας, ακολουθήστε τον παρακάτω σύνδεσμο για να ακυρώσετε την επιβεβαίωση της διεύθυνσης e-mail:
+Εάν ο λογαριασμός *δεν* ανήκει σε σας, ακολουθήστε αυτόν τον σύνδεσμο
+για να ακυρώσετε την επιβεβαίωση της διεύθυνσης ηλεκτρονικού ταχυδρομείου:
 
 $5
 
-Αυτός ο κωδικός επιβεβαίωσης θα λήξει στις $4.',
-'confirmemail_body_set' => 'Κάποιος, πιθανόν εσείς, από τη διεύθυνση IP $1, έχει θέσει τη διεύθυνση 
-ηλεκτρονικού ταχυδρομείου (e-mail) του λογαριασμού " $2 "σε αυτή τη διεύθυνση στο {{SITENAME}}.
+Αυτός ο κωδικός επιβεβαίωσης θα λήξει στις $6, στις $7.',
+'confirmemail_body_set' => 'Κάποιος, πιθανότατα εσείς, από τη διεύθυνση IP $1,
+όρισε αυτήν τη διεύθυνση ηλεκτρονικού ταχυδρομείου ως διεύθυνση ηλεκτρονικού ταχυδρομείου
+του λογαριασμού χρήστη «$2» στον ιστότοπο {{SITENAME}}.
 
-Για να επιβεβαιώσετε ότι αυτός ο λογαριασμός χρήστη ανήκει πραγματικά σε σας και να επανενεργοποιήσετε
-τις δυνατότητες ηλεκτρονικού ταχυδρομείου στον/στην/στα {{SITENAME}}, ανοίξτε αυτό το σύνδεσμο στον φυλλομετρητή (browser) σας:
+Για να επιβεβαιώσετε ότι αυτός ο λογαριασμός χρήστη ανήκει πραγματικά σε σας και να ενεργοποιήσετε πάλι
+τις δυνατότητες ηλεκτρονικού ταχυδρομείου στον ιστότοπο {{SITENAME}}, ανοίξτε στον περιηγητή σας αυτόν το σύνδεσμο:
 
 $3
 
-Εάν ο λογαριασμός * δεν * ανήκει σε σας, ακολουθήστε αυτόν τον σύνδεσμο
-για Î½Î± Î±ÎºÏ\85Ï\81Ï\8eÏ\83εÏ\84ε Ï\84ο e-mail ÎµÏ\80ιβεβαίÏ\89Ï\83ηÏ\82 Ï\84ηÏ\82 Î´Î¹ÎµÏ\8dθÏ\85νÏ\83ηÏ\82
+Εάν ο λογαριασμός *δεν* ανήκει σε σας, ακολουθήστε αυτόν τον σύνδεσμο
+για Î½Î± Î±ÎºÏ\85Ï\81Ï\8eÏ\83εÏ\84ε Ï\84ην ÎµÏ\80ιβεβαίÏ\89Ï\83η Ï\84ηÏ\82 Î´Î¹ÎµÏ\8dθÏ\85νÏ\83ηÏ\82 Î·Î»ÎµÎºÏ\84Ï\81ονικοÏ\8d Ï\84αÏ\87Ï\85δÏ\81ομείοÏ\85:
 
 $5
 
-Αυτός ο κωδικός επιβεβαίωσης θα λήξει στις $4.',
+Αυτός ο κωδικός επιβεβαίωσης θα λήξει στις $6, στις $7.',
 'confirmemail_invalidated' => 'Η επιβεβαίωσης της διεύθυνσης e-mail ακυρώθηκε',
 'invalidateemail' => 'Ακύρωση επιβεβαίωσης της διεύθυνσης e-mail',
 
@@ -3895,13 +3911,13 @@ $5
 'tags-hitcount' => '$1 {{PLURAL:$1|αλλαγή|αλλαγές}}',
 
 # Special:ComparePages
-'comparepages' => 'ΣÏ\85γκÏ\81ίνεÏ\84ε Ï\84ιÏ\82 Ï\83ελίδεÏ\82',
+'comparepages' => 'ΣÏ\8dγκÏ\81ιÏ\83η Ï\83ελίδÏ\89ν',
 'compare-selector' => 'Συγκρίνετε τις αναθεωρήσεις των σελίδων',
 'compare-page1' => 'Σελίδα 1',
 'compare-page2' => 'Σελίδα 2',
 'compare-rev1' => 'Αναθεώρηση 1',
 'compare-rev2' => 'Αναθεώρηση 2',
-'compare-submit' => 'ΣÏ\85γκÏ\81ίνεÏ\84ε',
+'compare-submit' => 'ΣÏ\8dγκÏ\81ιÏ\83η',
 'compare-invalid-title' => 'Ο τίτλος που καθορίσατε δεν είναι έγκυρος.',
 'compare-title-not-exists' => 'Ο τίτλος που καθορίσατε δεν υπάρχει.',
 'compare-revision-not-exists' => 'Η αναθεώρηση που καθορίσατε δεν υπάρχει.',
@@ -4017,6 +4033,7 @@ $5
 'api-error-ok-but-empty' => 'Εσωτερικό σφάλμα: δεν υπάρχει απάντηση από το διακομιστή.',
 'api-error-overwrite' => 'Αντικατάσταση ενός υπάρχοντος αρχείου δεν επιτρέπεται.',
 'api-error-stashfailed' => 'Εσωτερικό σφάλμα: ο διακομιστής απέτυχε να αποθηκεύσει το προσωρινό αρχείο.',
+'api-error-publishfailed' => 'Εσωτερικό σφάλμα: ο διακομιστής απέτυχε να αποθηκεύσει το προσωρινό αρχείο.',
 'api-error-timeout' => 'Ο διακομιστής δεν αποκρίθηκε εντός του αναμενόμενου χρόνου.',
 'api-error-unclassified' => 'Προέκυψε ένα άγνωστο σφάλμα.',
 'api-error-unknown-code' => 'Άγνωστο σφάλμα: "$1"',
index 7ed6123..d3f1327 100644 (file)
@@ -1764,7 +1764,7 @@ Details can be found in the [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENA
 'search-interwiki-custom'          => '', # do not translate or duplicate this message to other languages
 'search-interwiki-more'            => '(more)',
 'search-relatedarticle'            => 'Related',
-'mwsuggest-disable'                => 'Disable AJAX suggestions',
+'mwsuggest-disable'                => 'Disable search suggestions',
 'searcheverything-enable'          => 'Search in all namespaces',
 'searchrelated'                    => 'related',
 'searchall'                        => 'all',
@@ -3336,7 +3336,7 @@ You can update redirects that point to the original title automatically.
 If you choose not to, be sure to check for [[Special:DoubleRedirects|double]] or [[Special:BrokenRedirects|broken redirects]].
 You are responsible for making sure that links continue to point where they are supposed to go.
 
-Note that the page will '''not''' be moved if there is already a page at the new title, unless it is a redirect and has no past edit history.
+Note that the page will '''not''' be moved if there is already a page at the new title, unless the latter is a redirect and has no past edit history.
 This means that you can rename a page back to where it was renamed from if you make a mistake, and you cannot overwrite an existing page.
 
 '''Warning!'''
@@ -3768,6 +3768,7 @@ This is probably caused by a link to a blacklisted external site.',
 'pageinfo-robot-noindex'          => 'Not indexable',
 'pageinfo-views'                  => 'Number of views',
 'pageinfo-watchers'               => 'Number of page watchers',
+'pageinfo-few-watchers'           => 'Fewer than $1 {{PLURAL:$1|watcher|watchers}}',
 'pageinfo-redirects-name'         => 'Redirects to this page',
 'pageinfo-redirects-value'        => '$1', # only translate this message to other languages if you have to change it
 'pageinfo-subpages-name'          => 'Subpages of this page',
index 7f2703f..a0f8627 100644 (file)
@@ -751,7 +751,7 @@ Ne forgesu ŝanĝi viajn [[Special:Preferences|{{SITENAME}}-preferojn]]',
 'gotaccount' => "Ĉu vi jam havas konton? '''$1'''.",
 'gotaccountlink' => 'Ensaluti',
 'userlogin-resetlink' => 'Ĉu vi forgesis ensalutajn detalojn?',
-'createaccountmail' => 'retpoŝte',
+'createaccountmail' => 'Uzi provizoran hazardsignan pasvorton kaj sendi ĝin al la retpoŝto suben',
 'createaccountreason' => 'Kialo:',
 'badretype' => 'La pasvortojn kiujn vi tajpis ne egalas.',
 'userexists' => 'Salutnomo enigita jam estas uzata.
@@ -2313,7 +2313,7 @@ La retadreso kiun vi enigis en [[Special:Preferences|viaj preferoj]] aperos kiel
 'usermessage-editor' => 'Mesaĝanto de sistemo',
 
 # Watchlist
-'watchlist' => 'Atentaro',
+'watchlist' => 'Mia atentaro',
 'mywatchlist' => 'Atentaro',
 'watchlistfor2' => 'Por $1 $2',
 'nowatchlist' => 'Vi ne jam elektis priatenti iun ajn paĝon.',
@@ -3152,6 +3152,10 @@ Datoj de versioj kaj nomoj de redaktantoj estos preservitaj.
 'pageinfo-protect-cascading' => 'Protektado kaskade fontas el ĉi tie',
 'pageinfo-protect-cascading-yes' => 'Jes',
 'pageinfo-protect-cascading-from' => 'Protektado kaskade fontas el',
+'pageinfo-category-info' => 'Informo pri kategorio',
+'pageinfo-category-pages' => 'Nombro de paĝoj',
+'pageinfo-category-subcats' => 'Nombro de subkategorioj',
+'pageinfo-category-files' => 'Nombro de dosieroj',
 
 # Skin names
 'skinname-standard' => 'Klasiko',
@@ -3239,6 +3243,7 @@ $1',
 'hours' => '{{PLURAL:$1|$1 horo|$1 horoj}}',
 'days' => '{{PLURAL:$1|$1 tago|$1 tagoj}}',
 'months' => '{{PLURAL:$1|$1 monato|$1 monatoj}}',
+'years' => '{{PLURAL:$1|$1 jaro|$1 jaroj}}',
 'ago' => 'antaŭ $1',
 'just-now' => 'ĵus nune',
 
@@ -3950,7 +3955,7 @@ Bildoj montriĝas en plena distingivo, aliaj dosiertipoj estas malfermataj rekte
 'specialpages-group-highuse' => 'Plej uzitaj paĝoj',
 'specialpages-group-pages' => 'Listoj de paĝoj',
 'specialpages-group-pagetools' => 'Paĝaj iloj',
-'specialpages-group-wiki' => 'Vikidatenoj kaj iloj',
+'specialpages-group-wiki' => 'Datenoj kaj iloj',
 'specialpages-group-redirects' => 'Alidirektantaj specialaj paĝoj',
 'specialpages-group-spam' => 'Kontraŭspamiloj',
 
@@ -4104,7 +4109,8 @@ Aŭ vi povas uzi la facilan formularon sube. Via komento estos aldonita al la pa
 'api-error-nomodule' => 'Interna eraro: ne troveblas alŝuta helpilaro.',
 'api-error-ok-but-empty' => 'Interna eraro: nenia respondo de la servilo.',
 'api-error-overwrite' => 'Anstataŭigo de ekzistanta dosiero ne permesatas.',
-'api-error-stashfailed' => 'Interna eraro: la servilo malsukcesis stoki dumtempan dosieron.',
+'api-error-stashfailed' => 'Interna eraro: la servilo malsukcesis stoki provizoran dosieron.',
+'api-error-publishfailed' => 'Interna eraro: Servilo malsukcesis eldoni provizoran dosieron.',
 'api-error-timeout' => 'La servilo ne respondis ene de la antaŭvidita tempo.',
 'api-error-unclassified' => 'Okazis nekonata eraro',
 'api-error-unknown-code' => 'Nekonata eraro: "$1"',
index 699c640..bcb860f 100644 (file)
@@ -43,6 +43,7 @@
  * @author Fluence
  * @author Gustronico
  * @author Gwickwire
+ * @author Hazard-SJ
  * @author Hercule
  * @author Icvav
  * @author Imre
@@ -629,7 +630,7 @@ $1',
 'youhavenewmessagesmanyusers' => 'Tienes $1 de muchos usuarios ($2).',
 'newmessageslinkplural' => '{{PLURAL:$1|un nuevo mensaje|mensajes nuevos}}',
 'newmessagesdifflinkplural' => '{{PLURAL:$1|última modificación|últimos cambios}}',
-'youhavenewmessagesmulti' => 'Tienes nuevos mensajes en $1',
+'youhavenewmessagesmulti' => 'Tienes mensajes nuevos en $1',
 'editsection' => 'editar',
 'editold' => 'editar',
 'viewsourceold' => 'ver código fuente',
@@ -783,7 +784,7 @@ No olvides cambiar tus [[Special:Preferences|preferencias de {{SITENAME}} ]].',
 'externaldberror' => 'Hubo un error de autenticación externa de la base de datos o bien no tienes autorización para actualizar tu cuenta externa.',
 'login' => 'Iniciar sesión',
 'nav-login-createaccount' => 'Iniciar sesión / crear cuenta',
-'loginprompt' => "Es necesario habilitar las ''cookies'' en el navegador para registrarse en {{SITENAME}}.",
+'loginprompt' => "Necesita activar las ''cookies'' en el navegador para iniciar sesión en {{SITENAME}}.",
 'userlogin' => 'Iniciar sesión / crear cuenta',
 'userloginnocreate' => 'Iniciar sesión',
 'logout' => 'Cerrar sesión',
@@ -795,7 +796,7 @@ No olvides cambiar tus [[Special:Preferences|preferencias de {{SITENAME}} ]].',
 'gotaccount' => '¿Ya tienes una cuenta? $1.',
 'gotaccountlink' => 'Entrar',
 'userlogin-resetlink' => '¿Olvidaste tus datos de acceso?',
-'createaccountmail' => 'por correo electrónico',
+'createaccountmail' => 'Usar una contraseña aleatoria temporal y enviarla a la siguiente dirección de correo electrónico',
 'createaccountreason' => 'Motivo:',
 'badretype' => 'Las contraseñas no coinciden.',
 'userexists' => 'El nombre de usuario indicado ya está en uso.
@@ -1405,7 +1406,7 @@ Los detalles pueden encontrarse en el [{{fullurl:{{#Special:Log}}/delete|page={{
 'search-interwiki-default' => 'Resultados de $1:',
 'search-interwiki-more' => '(más)',
 'search-relatedarticle' => 'Relacionado',
-'mwsuggest-disable' => 'Desactivar AJAX al realizar búsquedas',
+'mwsuggest-disable' => 'Desactivar las sugerencias de búsqueda',
 'searcheverything-enable' => 'Buscar en todos los espacios de nombres',
 'searchrelated' => 'relacionado',
 'searchall' => 'todos',
@@ -1502,8 +1503,8 @@ Cualquiera que conozca la clave en este campo será capaz de leer tu lista de se
 'allowemail' => 'Aceptar correo electrónico de otros usuarios',
 'prefs-searchoptions' => 'Buscar',
 'prefs-namespaces' => 'Espacios de nombres',
-'defaultns' => 'Buscar en estos espacios de nombres por defecto:',
-'default' => 'por defecto',
+'defaultns' => 'De lo contrario, buscar en estos espacios de nombres:',
+'default' => 'predeterminado',
 'prefs-files' => 'Archivos',
 'prefs-custom-css' => 'CSS personalizado',
 'prefs-custom-js' => 'JavaScript personalizado',
@@ -2004,7 +2005,7 @@ Para óptima seguridad, img_auth.php está desactivado.',
 
 # Special:ListFiles
 'listfiles-summary' => 'Esta página especial muestra todos los archivos subidos.
-Cuando es filtrado por el usuario, sólo los archivos cargados por el usuario se muestran en su versión más reciente.',
+Cuando el usuario la filtra, solo se muestran los archivos cargados por el usuario en su versión más reciente.',
 'listfiles_search_for' => 'Buscar por nombre de imagen:',
 'imgfile' => 'archivo',
 'listfiles' => 'Lista de archivos',
@@ -2309,7 +2310,7 @@ Es necesario, por lo menos, un dominio de alto nivel, por ejemplo "*.org".<br />
 # Special:ActiveUsers
 'activeusers' => 'Lista de usuarios activos',
 'activeusers-intro' => 'Esta es una lista de usuarios que han tenido alguna actividad en los últimos $1 {{PLURAL:$1|día|días}}.',
-'activeusers-count' => '$1 {{PLURAL:$1|edición|ediciones}} en los últimos {{PLURAL:$3|día|$3 días}}',
+'activeusers-count' => '$1 {{PLURAL:$1|acción|acciones}} en los últimos {{PLURAL:$3|día|$3 días}}',
 'activeusers-from' => 'Mostrando a los usuarios empezando por:',
 'activeusers-hidebots' => 'Ocultar robots',
 'activeusers-hidesysops' => 'Ocultar administradores',
@@ -2337,7 +2338,7 @@ Puede haber información adicional sobre privilegios individuales en [[{{MediaWi
 # E-mail user
 'mailnologin' => 'Ninguna dirección de envio',
 'mailnologintext' => 'Debes [[Special:UserLogin|iniciar sesión]] y tener una dirección electrónica válida en tus [[Special:Preferences|preferencias]] para enviar un correo electrónico a otros usuarios.',
-'emailuser' => 'Enviar correo electrónico a este usuario',
+'emailuser' => 'Enviar un correo electrónico a {{GENDER:{{BASEPAGENAME}}|este usuario|esta usuaria}}',
 'emailuser-title-target' => 'Enviar un correo electrónico a {{GENDER:$1|este usuario|esta usuaria}}',
 'emailuser-title-notarget' => 'Enviar un correo electrónico al usuario',
 'emailpage' => 'Correo electrónico a usuario',
@@ -2533,7 +2534,7 @@ A continuación se muestran las opciones actuales de la página '''$1''':",
 A continuación se muestran las opciones actuales de la página '''$1''':",
 'protect-cascadeon' => 'Actualmente esta página está protegida porque está incluida en {{PLURAL:$1|la siguiente página|las siguientes páginas}}, que tienen activada la opción de protección en cascada. Puedes cambiar el nivel de protección de esta página, pero no afectará a la protección en cascada.',
 'protect-default' => 'Permitir todos los usuarios',
-'protect-fallback' => 'Necesita el permiso «$1»',
+'protect-fallback' => 'Solo permitir usuarios con el permiso «$1»',
 'protect-level-autoconfirmed' => 'Permitir solo usuarios autoconfirmados',
 'protect-level-sysop' => 'Permitir solo administradores',
 'protect-summary-cascade' => 'en cascada',
@@ -2823,18 +2824,18 @@ Sin embargo, está bloqueada como parte del rango $2, que puede ser desbloqueado
 # Move page
 'move-page' => 'Trasladar $1',
 'move-page-legend' => 'Renombrar página',
-'movepagetext' => "Usando el siguiente formulario se renombrará una página, trasladando todo su historial al nuevo nombre.
-El título anterior se convertirá en una redirección al nuevo título.
-Los enlaces al antiguo título de la página no se cambiarán.
-Asegúrate de no dejar [[Special:DoubleRedirects|redirecciones dobles]] o [[Special:BrokenRedirects|rotas]].
-Tú eres responsable de hacer que los enlaces sigan apuntando a donde se supone que deberían hacerlo.
-
-Recuerda que la página '''no''' será renombrada si ya existe una página con el nuevo título, a no ser que sea una página vacía o una redirección sin historial.
-Esto significa que podrás renombrar una página a su título original si has cometido un error, pero que no podrás sobrescribir una página existente.
-
-'''¡Aviso!'''
-Este puede ser un cambio drástico e inesperado para una página popular;
-por favor, asegúrate de entender las consecuencias del procedimiento antes de seguir adelante.",
+'movepagetext' => "Mediante el siguiente formulario puedes renombrar una página, moviendo todo su historial al nombre nuevo.
+El título anterior redirigirá al nuevo.
+Puedes actualizar automáticamente las redirecciones que apuntan al título original.
+Si eliges no hacerlo, asegúrate de revisar posibles redirecciones [[Special:DoubleRedirects|dobles]] o [[Special:BrokenRedirects|rotas]].
+Tú eres responsable de asegurar que los enlaces continúen funcionando correctamente.
+
+Nota que la página '''no''' se moverá si ya hay una página con el título nuevo, a menos de que ésta sea una redirección y no tenga historial de ediciones pasadas.
+Esto significa que puedes deshacer el renombrado en caso de un error, y que no puedes sobreescribir una página existente.
+
+'''Aviso'''
+Esto puede representar un cambio drástico e inesperado para una página popular;
+asegúrate de entender las consecuencias de esta acción antes de proceder.",
 'movepagetext-noredirectfixer' => "Usando el siguiente formulario se renombrará una página, trasladando todo su historial al nuevo nombre.
 El título anterior se convertirá en una redirección al nuevo título.
 Asegúrate de no dejar [[Special:DoubleRedirects|redirecciones dobles]] o [[Special:BrokenRedirects|rotas]].
@@ -3184,6 +3185,7 @@ Esto podría estar causado por un enlace a un sitio externo incluido en la lista
 'pageinfo-robot-noindex' => 'No indexable',
 'pageinfo-views' => 'Número de vistas',
 'pageinfo-watchers' => 'Número de usuarios que vigilan la página',
+'pageinfo-few-watchers' => 'Menos de $1 {{PLURAL:$1|vigilante|vigilantes}}',
 'pageinfo-redirects-name' => 'Redirecciones a esta página',
 'pageinfo-redirects-value' => '$1',
 'pageinfo-subpages-name' => 'Subpáginas de esta página',
@@ -3960,7 +3962,7 @@ Las imágenes se muestran en resolución máxima, otros tipos de archivo se inic
 'specialpages-group-highuse' => 'Páginas sobre usos',
 'specialpages-group-pages' => 'Listas de páginas',
 'specialpages-group-pagetools' => 'Herramientas de páginas',
-'specialpages-group-wiki' => 'Herramientas y datos del wiki',
+'specialpages-group-wiki' => 'Herramientas y datos',
 'specialpages-group-redirects' => 'Búsquedas y redirecciones',
 'specialpages-group-spam' => 'Herramientas anti-SPAM',
 
@@ -4058,6 +4060,7 @@ Este sitio está experimentando dificultades técnicas.',
 'logentry-newusers-newusers' => 'Se ha creado la cuenta de usuario $1',
 'logentry-newusers-create' => 'Se ha creado la cuenta de usuario $1',
 'logentry-newusers-create2' => '$1 ha creado la cuenta de usuario $3',
+'logentry-newusers-byemail' => '$1 creó la cuenta de usuario $3 y la contraseña se envió por correo electrónico',
 'logentry-newusers-autocreate' => 'La cuenta $1 fue creada automáticamente',
 'logentry-rights-rights' => '$1 modificó los grupos a los que pertenece $3: de $4 a $5',
 'logentry-rights-rights-legacy' => '$1 ha cambiado la pertenencia a grupos de $3',
index 34c3968..bce01b4 100644 (file)
@@ -800,9 +800,10 @@ Era berean, bidaltzen ari zaren edukia zuk zeuk idatzitakoa dela edo jabetza pub
 '''EZ BIDALI BAIMENIK GABEKO COPYRIGHTDUN EDUKIRIK!'''",
 'longpageerror' => "'''Errorea: Bidali duzun testuak {{PLURAL:$1|kilobyte 1eko|$1 kilobyteko}} luzera du, eta {{PLURAL:$2|kilobyte 1eko|$2 kilobyteko}} maximoa baino luzeagoa da.'''
 Ezin da gorde.",
-'readonlywarning' => "'''OHARRA: Datu-basea blokeatu egin da mantenu lanak burutzeko, beraz ezingo dituzu orain zure aldaketak gorde. Testua fitxategi baten kopiatu dezakezu, eta beranduago erabiltzeko gorde.
+'readonlywarning' => "'''Oharra: Datu-basea blokeatu egin da mantenu lanak burutzeko, beraz ezingo dituzu orain zure aldaketak gorde.'''
+Testua fitxategi baten kopiatu dezakezu, eta beranduago erabiltzeko gorde.
 
-Blokeatu zuen administratzaileak honako azalpena eman zuen: $1'''",
+Blokeatu zuen administratzaileak honako azalpena eman zuen: $1",
 'protectedpagewarning' => "'''Oharra:  Orri hau blokeatua dago administratzaileek soilik eraldatu ahal dezaten.'''
 Azken erregistroa ondoren ikusgai dago erreferentzia gisa:",
 'semiprotectedpagewarning' => "'''Oharra''': Orrialde hau erregistratutako erabiltzaileek bakarrik aldatzeko babestuta dago.
@@ -1863,7 +1864,7 @@ Baimendutako protokoloak: <code>$1</code> (protokoloa zehazten ez bada http:// h
 
 # Special:ActiveUsers
 'activeusers' => 'Lankide aktiboen zerrenda',
-'activeusers-count' => '{{PLURAL:$1|Aldaketa berri bat|$1 aldaketa berri}} azken {{PLURAL:$3|egunean|$3 egunetan}}',
+'activeusers-count' => '{{PLURAL:$1|Ekintza berri bat|$1 ekintza berri}} azken {{PLURAL:$3|egunean|$3 egunetan}}',
 'activeusers-from' => 'Bilatu honela hasten diren lankideak:',
 'activeusers-hidebots' => 'Ezkutatu bot-ak',
 'activeusers-hidesysops' => 'Ezkutatu administratzaileak',
@@ -1920,7 +1921,7 @@ Badago [[{{MediaWiki:Listgrouprights-helppage}}|informazio osagarria]] banakako
 'usermessage-editor' => 'Sistemako mezularia',
 
 # Watchlist
-'watchlist' => 'Nire jarraipen zerrenda',
+'watchlist' => 'Jarraipen zerrenda',
 'mywatchlist' => 'Jarraipen zerrenda',
 'watchlistfor2' => '$1 ($2)',
 'nowatchlist' => 'Zure jarraipen zerrenda hutsik dago.',
@@ -2349,7 +2350,6 @@ Konturatu zaitez orrialdea '''ez''' dela mugituko izenburu berria duen orrialde
 Horrek esan nahi du hanka sartzekotan orrialde baten jatorrizko izenburua berreskuratu daitekeela, baina ezin dela jada existitzen den orrialde baten gainean idatzi.
 
 '''Oharra!'''
-
 Aldaketa hau drastikoa eta ustekabekoa izan daiteke orrialde oso ezagunetan;
 mesedez, egiazta ezazu honen ondorioak ulertzen dituzula, jarraitu baino lehen.",
 'movepagetalktext' => "Dagokion eztabaida orrialdea berarekin batera mugitu da, honako kasu hauetan '''ezik:'''
@@ -3261,7 +3261,7 @@ Irudiak bereizmen handienean daude, bestelako fitxategi motak beraiei esleitutak
 'specialpages-group-highuse' => 'Erabilera handiko orrialdeak',
 'specialpages-group-pages' => 'Orrialdeen zerrendak',
 'specialpages-group-pagetools' => 'Orrialde tresnak',
-'specialpages-group-wiki' => 'Wiki datuak eta tresnak',
+'specialpages-group-wiki' => 'Datuak eta tresnak',
 'specialpages-group-redirects' => 'Berbideraketa-orri bereziak',
 'specialpages-group-spam' => 'Spam tresnak',
 
index 54cd83c..be3b215 100644 (file)
@@ -446,6 +446,7 @@ $messages = array(
 'newwindow' => '(avautuu uuteen ikkunaan)',
 'cancel' => 'Peruuta',
 'moredotdotdot' => 'Lisää...',
+'morenotlisted' => 'Lisää...',
 'mypage' => 'Käyttäjäsivu',
 'mytalk' => 'Keskustelusivu',
 'anontalk' => 'Keskustele tämän IP:n kanssa',
@@ -800,6 +801,7 @@ Odota ennen kuin yrität uudelleen.',
 # E-mail sending
 'php-mail-error-unknown' => 'Tuntematon virhe PHP:n mail()-funktiossa',
 'user-mail-no-addy' => 'Yritit lähettää sähköpostia ilman sähköpostiosoitetta.',
+'user-mail-no-body' => 'Sähköpostin sisältö ei ole tarpeeksi pitkä.',
 
 # Change password dialog
 'resetpass' => 'Muuta salasana',
@@ -1050,6 +1052,7 @@ Se on ilmeisesti poistettu.',
 'edit-already-exists' => 'Uuden sivun luominen ei onnistunut.
 Se on jo olemassa.',
 'defaultmessagetext' => 'Viestin oletusteksti',
+'content-failed-to-parse' => 'Sisältö tyypiltään $2 ei jäsenny tyypiksi $1: $3',
 'invalid-content-data' => 'Virheellinen sisältö',
 'content-not-allowed-here' => 'Sivun [[$2]] sisältö ei voi olla tyyppiä $1.',
 
@@ -1310,7 +1313,7 @@ $1 {{int:pipe-separator}} $2',
 'search-interwiki-default' => 'Tulokset osoitteesta $1:',
 'search-interwiki-more' => '(lisää)',
 'search-relatedarticle' => 'Hae samankaltaisia sivuja',
-'mwsuggest-disable' => 'Älä näytä ehdotuksia AJAXilla',
+'mwsuggest-disable' => 'Älä näytä hakuehdotuksia',
 'searcheverything-enable' => 'Hae kaikista nimiavaruuksista',
 'searchrelated' => 'samankaltainen',
 'searchall' => 'kaikki',
@@ -2417,7 +2420,7 @@ Viimeisimmän muokkauksen on tehnyt käyttäjä [[User:$3|$3]] ([[User talk:$3|k
 'protect-cascadeon' => 'Tämä sivu on suojauksen kohteena, koska se on sisällytetty alla {{PLURAL:$1|olevaan laajennetusti suojattuun sivuun|oleviin laajennetusti suojattuihin sivuihin}}. Voit muuttaa tämän sivun suojaustasoa, mutta se ei vaikuta laajennettuun suojaukseen.',
 'protect-default' => 'Salli kaikki käyttäjät',
 'protect-fallback' => 'Salli vain käyttäjät, joilla on oikeus $1',
-'protect-level-autoconfirmed' => 'Estä uudet ja kirjautumattomat käyttäjät',
+'protect-level-autoconfirmed' => 'Vain hyväksytyt käyttäjät',
 'protect-level-sysop' => 'Salli vain ylläpitäjät',
 'protect-summary-cascade' => 'laajennettu',
 'protect-expiring' => 'vanhentuu $1 (UTC)',
@@ -2708,7 +2711,7 @@ Voit päivittää sivuun viittaavat ohjaukset automaattisesti ohjaamaan uudelle
 Jos et halua tätä tehtävän automaattisesti, muista tehdä tarkistukset [[Special:DoubleRedirects|kaksinkertaisten]] tai [[Special:BrokenRedirects|rikkinäisten]] ohjausten varalta.
 Olet vastuussa siitä, että linkit osoittavat sinne, mihin niiden on tarkoituskin osoittaa.
 
-Huomaa, että sivua '''ei''' siirretä mikäli uusi otsikko on olemassa olevan sivun käytössä, paitsi milloin kyseessä on ohjaus, jolla ei ole muokkaushistoriaa.
+Huomaa, että sivua '''ei''' siirretä mikäli uusi otsikko on olemassa olevan sivun käytössä, paitsi jos jälkimmäinen on ohjaus, jolla ei ole muokkaushistoriaa.
 Tämä tarkoittaa sitä, että voit siirtää sivun takaisin vanhalle nimelleen mikäli teit virheen, mutta et voi kirjoittaa olemassa olevan sivun päälle.
 
 Tämä saattaa olla suuri ja odottamaton muutos suositulle sivulle. Varmista, että tiedät seuraukset ennen kuin siirrät sivun.",
@@ -2716,7 +2719,8 @@ Tämä saattaa olla suuri ja odottamaton muutos suositulle sivulle. Varmista, et
 
 Tarkasta sivuun viittaavat ohjaukset [[Special:DoubleRedirects|kaksinkertaisten]] tai [[Special:BrokenRedirects|rikkinäisten]] ohjausten varalta. Olet vastuussa siitä, että linkit osoittavat sinne, mihin niiden on tarkoituskin osoittaa.
 
-Huomaa, että sivua '''ei''' siirretä mikäli uusi otsikko on olemassa olevan sivun käytössä, paitsi milloin kyseessä on tyhjä sivu tai ohjaus, jolla ei ole muokkaushistoriaa. Tämä tarkoittaa sitä, että voit siirtää sivun takaisin vanhalle nimelleen mikäli teit virheen, mutta et voi kirjoittaa olemassa olevan sivun päälle.
+Huomaa, että sivua '''ei''' siirretä mikäli uusi otsikko on olemassa olevan sivun käytössä, paitsi jos jälkimmäinen on ohjaus, jolla ei ole muokkaushistoriaa.
+Tämä tarkoittaa sitä, että voit siirtää sivun takaisin vanhalle nimelleen mikäli teit virheen, mutta et voi kirjoittaa olemassa olevan sivun päälle.
 
 Tämä saattaa olla suuri ja odottamaton muutos suositulle sivulle. Varmista, että tiedät seuraukset ennen kuin siirrät sivun.",
 'movepagetalktext' => "Sivuun mahdollisesti kytketty keskustelusivu siirretään automaattisesti, '''paitsi jos''':
@@ -3909,8 +3913,10 @@ Kuvat näytetään täysikokoisina. Muut tiedostot avataan niille määritetyss
 'logentry-newusers-newusers' => 'Käyttäjätunnus $1 luotiin',
 'logentry-newusers-create' => 'Käyttäjätunnus $1 luotiin',
 'logentry-newusers-create2' => '$1 loi käyttäjätunnuksen $3',
+'logentry-newusers-byemail' => '$1 loi käyttäjätunnuksen $3 ja salasana lähetettiin sähköpostitse',
 'logentry-newusers-autocreate' => 'Käyttäjätunnus $1 luotiin automaattisesti',
 'logentry-rights-rights' => '$1 muutti käyttäjän $3 oikeudet ryhmistä $4 ryhmiin $5',
+'logentry-rights-rights-legacy' => '$1 muutti käyttäjän $3 jäsenyyttä ryhmässä',
 'logentry-rights-autopromote' => '$1 ylennettiin automaattisesti ryhmistä $4 ryhmiin $5',
 'rightsnone' => '(ei oikeuksia)',
 
index bba2eef..f2dd97f 100644 (file)
@@ -495,7 +495,7 @@ $messages = array(
 'dec' => 'déc',
 
 # Categories related messages
-'pagecategories' => 'Catégorie{{PLURAL:$1||s}}',
+'pagecategories' => '{{PLURAL:$1|Catégorie|Catégories}}',
 'category_header' => 'Pages dans la catégorie « $1 »',
 'subcategories' => 'Sous-catégories',
 'category-media-header' => 'Fichiers multimédias dans la catégorie « $1 »',
@@ -1408,7 +1408,7 @@ Vous pouvez trouver des détails dans le [{{fullurl:{{#Special:Log}}/delete|page
 'search-interwiki-default' => 'Résultats sur $1 :',
 'search-interwiki-more' => '(plus)',
 'search-relatedarticle' => 'Relaté',
-'mwsuggest-disable' => 'Désactiver les suggestions AJAX',
+'mwsuggest-disable' => 'Désactiver les suggestions de recherche',
 'searcheverything-enable' => 'Rechercher dans tous les espaces de noms',
 'searchrelated' => 'relaté',
 'searchall' => 'tout',
@@ -2851,7 +2851,7 @@ Pour bloquer ou débloquer la base de données, il doit être accessible par le
 'move-page-legend' => 'Renommer une page',
 'movepagetext' => "Utilisez le formulaire ci-dessous pour renommer une page, en déplaçant tout son historique vers le nouveau nom. L'ancien titre deviendra une page de redirection vers le nouveau titre. Vous pouvez mettre à jour automatiquement les redirections actuelles qui pointent vers le titre original. Si vous choisissez de ne pas le faire, assurez-vous de vérifier toute [[Special:DoubleRedirects|double redirection]] ou [[Special:BrokenRedirects|redirection cassée]]. Vous avez la responsabilité de vous assurer que les liens continuent de pointer vers leur destination supposée.
 
-Notez que la page ne sera '''pas''' renommée s'il existe déjà une page avec le nouveau titre, sauf si cette dernière a un historique de modifications vierge et est une simple redirection. Ceci permet de renommer une page vers sa position d'origine si le déplacement s'avère erroné.
+Notez que la page ne sera '''pas''' renommée s'il existe déjà une page avec le nouveau titre, sauf si cette dernière est une simple redirection avec un historique de modifications vierge. Ceci permet de renommer une page vers sa position d'origine si le déplacement s'avère erroné.
 
 '''Attention !'''
 Ceci peut provoquer un changement radical et imprévu pour une page souvent consultée ; assurez-vous d'en avoir compris les conséquences avant de continuer.",
@@ -3202,6 +3202,7 @@ Permet de rétablir la version précédente et d'ajouter un motif dans la boîte
 'pageinfo-robot-noindex' => 'Non indexable',
 'pageinfo-views' => 'Nombre de vues',
 'pageinfo-watchers' => 'Nombre de contributeurs ayant la page dans leur liste de suivi',
+'pageinfo-few-watchers' => 'Moins de $1 {{PLURAL:$1|observateur|observateurs}}',
 'pageinfo-redirects-name' => 'Redirections vers cette page',
 'pageinfo-subpages-name' => 'Sous-pages de cette page',
 'pageinfo-subpages-value' => '$1 ($2 {{PLURAL:$2|redirection|redirections}}; $3 {{PLURAL:$3|non-redirection|non-redirections}})',
index 07bed68..5c036d9 100644 (file)
@@ -323,7 +323,7 @@ $messages = array(
 'tog-editsectiononrightclick' => 'Activar lo changement de sèccions per clic drêt sur lors titros (il at fôta de JavaScript)',
 'tog-showtoc' => 'Montrar la trâbla de les matiéres (por les pâges qu’ont més de 3 sèccions)',
 'tog-rememberpassword' => 'Sè rapelar de mon contresegno sur ceti navigator (por lo més $1 jorn{{PLURAL:$1||s}})',
-'tog-watchcreations' => 'Apondre les pâges que fé et pués los fichiérs que tèlècharjo a ma lista de siuvu',
+'tog-watchcreations' => 'Apondre les pâges que fé et pués los fichiérs que tèlèchârjo a ma lista de siuvu',
 'tog-watchdefault' => 'Apondre les pâges et los fichiérs que chanjo a ma lista de siuvu',
 'tog-watchmoves' => 'Apondre les pâges et los fichiérs que dèplaço a ma lista de siuvu',
 'tog-watchdeletion' => 'Apondre les pâges et los fichiérs que suprimo a ma lista de siuvu',
@@ -342,7 +342,7 @@ $messages = array(
 'tog-externaldiff' => 'Empleyér per dèfôt un comparator de defôr (solament por los utilisators avanciês, il at fôta d’una configuracion spèciâla sur voutron ordenator. [//www.mediawiki.org/wiki/Manual:External_editors Més d’enformacions.])',
 'tog-showjumplinks' => 'Activar los lims d’accèssibilitât « {{int:jumpto}} »',
 'tog-uselivepreview' => 'Empleyér l’apèrçu rapido (il at fôta de JavaScript) (èxpèrimentâl)',
-'tog-forceeditsummary' => 'M’avèrtir quand j’é pas buchiê de rèsumâ de changement',
+'tog-forceeditsummary' => 'Mè balyér na semonce quand j’é pas buchiê de rèsumâ de changement',
 'tog-watchlisthideown' => 'Cachiér los mins changements dedens la lista de siuvu',
 'tog-watchlisthidebots' => 'Cachiér los changements fêts per des robots dedens la lista de siuvu',
 'tog-watchlisthideminor' => 'Cachiér los petiôts changements dedens la lista de siuvu',
@@ -529,12 +529,12 @@ $messages = array(
 'lastmodifiedat' => 'Dèrriér changement de ceta pâge lo $1 a $2.',
 'viewcount' => 'Ceta pâge est étâye vua {{PLURAL:$1|un côp|$1 côps}}.',
 'protectedpage' => 'Pâge protègiêe',
-'jumpto' => 'Alar a :',
+'jumpto' => 'Alar vers :',
 'jumptonavigation' => 'navigacion',
 'jumptosearch' => 'rechèrche',
 'view-pool-error' => 'Dèconsolâ, los sèrviors sont lapidâs d’ôvra cetos temps.
-Trop d’utilisators tâchont de vêre ceta pâge.
-Volyéd atendre un moment devant que tornar tâchiér d’arrevar a ceta pâge.
+Trop d’utilisators èprôvont de vêre ceta pâge.
+Se vos plét, atende un moment devant que tornar èprovar d’arrevar a ceta pâge.
 
 $1',
 'pool-timeout' => 'Dèlê dèpassâ pendent l’atenta du vèrroly',
@@ -548,8 +548,8 @@ $1',
 'copyrightpage' => '{{ns:project}}:Drêts d’ôtor',
 'currentevents' => 'Novèles',
 'currentevents-url' => 'Project:Novèles',
-'disclaimers' => 'Avèrtissements',
-'disclaimerpage' => 'Project:Avèrtissements g·ènèrals',
+'disclaimers' => 'Semonces',
+'disclaimerpage' => 'Project:Semonces g·ènèrales',
 'edithelp' => 'Éde',
 'edithelppage' => 'Help:Coment changiér na pâge',
 'helppage' => 'Help:Somèro',
@@ -571,14 +571,14 @@ Vêde la [[Special:Version|pâge de les vèrsions]].',
 
 'ok' => 'D’acôrd',
 'retrievedfrom' => 'Rècupèrâye de « $1 »',
-'youhavenewmessages' => 'Vos avéd de $1 ($2).',
+'youhavenewmessages' => 'Vos éd de $1 ($2).',
 'newmessageslink' => 'mèssâjos novéls',
 'newmessagesdifflink' => 'dèrriér changement',
-'youhavenewmessagesfromusers' => 'Vos avéd $1 {{PLURAL:$3|d’un ôtr’utilisator|de $3 ôtros utilisators}} ($2).',
-'youhavenewmessagesmanyusers' => 'Vos avéd $1 d’un mouél d’utilisators ($2).',
+'youhavenewmessagesfromusers' => 'Vos éd $1 {{PLURAL:$3|d’un ôtr’utilisator|de $3 ôtros utilisators}} ($2).',
+'youhavenewmessagesmanyusers' => 'Vos éd $1 d’un mouél d’utilisators ($2).',
 'newmessageslinkplural' => '{{PLURAL:$1|un mèssâjo novél|de mèssâjos novéls}}',
 'newmessagesdifflinkplural' => '{{PLURAL:$1|dèrriér changement|dèrriérs changements}}',
-'youhavenewmessagesmulti' => 'Vos avéd de mèssâjos novéls sur $1',
+'youhavenewmessagesmulti' => 'Vos éd de mèssâjos novéls sur $1',
 'editsection' => 'changiér',
 'editold' => 'changiér',
 'viewsourceold' => 'vêre lo tèxto sôrsa',
@@ -590,8 +590,8 @@ Vêde la [[Special:Version|pâge de les vèrsions]].',
 'hidetoc' => 'cachiér',
 'collapsible-collapse' => 'repleyér',
 'collapsible-expand' => 'dèpleyér',
-'thisisdeleted' => '’T-o que vos voléd vêre ou ben refâre $1 ?',
-'viewdeleted' => '’T-o que vos voléd vêre $1 ?',
+'thisisdeleted' => 'Est-o que vos voléd vêre ou ben refâre $1 ?',
+'viewdeleted' => 'Est-o que vos voléd vêre $1 ?',
 'restorelink' => '{{PLURAL:$1|un changement suprimâ|$1 changements suprimâs}}',
 'feedlinks' => 'Flux :',
 'feed-invalid' => 'Tipo d’abonement du flux pas justo.',
@@ -620,7 +620,7 @@ Vêde la [[Special:Version|pâge de les vèrsions]].',
 'nosuchaction' => 'Accion encognua',
 'nosuchactiontext' => 'L’accion spècifiâye dens l’URL est pas justa.
 Pôt-étre vos éd mâl-buchiê l’URL ou ben siuvu un lim fôx.
-Pôt asse-ben étre quèstion d’una cofierie dedens la programeria empleyêe per {{SITENAME}}.',
+Pôt asse-ben étre na cofierie dedens la programeria empleyêe per {{SITENAME}}.',
 'nosuchspecialpage' => 'Pâge spèciâla pas ègzistenta',
 'nospecialpagetext' => '<strong>Vos éd demandâ na pâge spèciâla qu’ègziste pas.</strong>
 
@@ -650,27 +650,27 @@ L’administrator que l’at vèrrolyê at balyê cet’èxplicacion : $1',
 
 En g·ènèral cen arreve en siuvent un lim d’una dif d’un historico dèpassâ(ye) de vers na pâge qu’est étâye suprimâye.
 
-S’o est pas lo câs, pôt étre quèstion d’una cofierie dedens la programeria.
-La volyéd signalar a un [[Special:ListUsers/sysop|administrator]] sen oubliar de lui endicar l’URL du lim.',
+S’o est pas lo câs, pôt étre na cofierie dedens la programeria.
+Se vos plét, signalâd-la a un [[Special:ListUsers/sysop|administrator]] sen oubliar de lui endicar l’URL du lim.',
 'missingarticle-rev' => '(numerô de vèrsion : $1)',
 'missingarticle-diff' => '(dif : $1, $2)',
 'readonly_lag' => 'La bâsa de donâs est étâye vèrrolyêe ôtomaticament pendent que los sèrviors secondèros ratrapont lor retârd sur lo sèrvior principâl.',
 'internalerror' => 'Fôta de dedens',
 'internalerror_info' => 'Fôta de dedens : $1',
-'fileappenderrorread' => 'Empossiblo de liére « $1 » pendent l’aponsa.',
-'fileappenderror' => 'Empossiblo d’apondre « $1 » a « $2 ».',
-'filecopyerror' => 'Empossiblo de copiyér lo fichiér « $1 » vers « $2 ».',
-'filerenameerror' => 'Empossiblo de renomar lo fichiér « $1 » en « $2 ».',
-'filedeleteerror' => 'Empossiblo de suprimar lo fichiér « $1 ».',
-'directorycreateerror' => 'Empossiblo de fâre lo dossiér « $1 ».',
-'filenotfound' => 'Empossiblo de trovar lo fichiér « $1 ».',
-'fileexistserror' => 'Empossiblo d’ècrire lo fichiér « $1 » : lo fichiér ègziste.',
+'fileappenderrorread' => 'Y at pas moyen de liére « $1 » pendent l’aponsa.',
+'fileappenderror' => 'Y at pas moyen d’apondre « $1 » a « $2 ».',
+'filecopyerror' => 'Y at pas moyen de copiyér lo fichiér « $1 » vers « $2 ».',
+'filerenameerror' => 'Y at pas moyen de renomar lo fichiér « $1 » en « $2 ».',
+'filedeleteerror' => 'Y at pas moyen de suprimar lo fichiér « $1 ».',
+'directorycreateerror' => 'Y at pas moyen de fâre lo rèpèrtouèro « $1 ».',
+'filenotfound' => 'Y at pas moyen de trovar lo fichiér « $1 ».',
+'fileexistserror' => 'Y at pas moyen d’ècrire lo fichiér « $1 » : lo fichiér ègziste.',
 'unexpected' => 'Valor emprèvua : « $1 » = « $2 ».',
-'formerror' => 'Fôta : empossiblo de mandar lo formulèro.',
+'formerror' => 'Fôta : y at pas moyen de mandar lo formulèro.',
 'badarticleerror' => 'Cel’accion pôt pas étre fêta sur ceta pâge.',
-'cannotdelete' => 'Empossiblo de suprimar la pâge lo fichiér « $1 ».
+'cannotdelete' => 'Y at pas moyen de suprimar la pâge lo fichiér « $1 ».
 Pôt-étre la suprèssion est ja étâye fêta per un ôtro.',
-'cannotdelete-title' => 'Empossiblo de suprimar la pâge « $1 »',
+'cannotdelete-title' => 'Y at pas moyen de suprimar la pâge « $1 »',
 'delete-hook-aborted' => 'Suprèssion anulâye per un grèfon.
 Nion’èxplicacion est étâye balyêe.',
 'badtitle' => 'Crouyo titro',
@@ -687,25 +687,25 @@ Demanda : $2',
 'viewsource-title' => 'Vêre lo tèxto sôrsa de $1',
 'actionthrottled' => 'Accion limitâye',
 'actionthrottledtext' => 'Por combatre lo spame, l’usâjo de cel’accion est limitâ a doux-três côps dens un moment prod côrt. S’acomplét que vos éd dèpassâ ceta limita.
-Volyéd tornar èprovar dens un tôrn.',
+Se vos plét, tornâd èprovar dens un tôrn.',
 'protectedpagetext' => 'Ceta pâge est étâye protègiêe por empachiér son changement ou ben d’ôtres accions.',
-'viewsourcetext' => 'Vos pouede vêre et pués copiyér lo tèxto sôrsa de ceta pâge :',
-'viewyourtext' => "Vos pouede vêre et pués copiyér lo tèxto sôrsa de '''voutros changements''' a ceta pâge :",
+'viewsourcetext' => 'Vos pouede vêre et copiyér lo tèxto sôrsa de ceta pâge :',
+'viewyourtext' => "Vos pouede vêre et copiyér lo tèxto sôrsa de '''voutros changements''' a ceta pâge :",
 'protectedinterface' => 'Cela pâge-que balye de tèxto d’entèrface por la programeria sur ceti vouiqui, et el est vêr protègiêe por èvitar los abus.
-Por apondre ou ben changiér des traduccions sur tôs los vouiquis, volyéd empleyér [//translatewiki.net/ translatewiki.net], lo projèt de localisacion de MediaWiki.',
+Por apondre ou ben changiér des traduccions sur tôs los vouiquis, se vos plét empleyéd [//translatewiki.net/ translatewiki.net], lo projèt de localisacion de MediaWiki.',
 'editinginterface' => "'''Atencion :''' vos éte aprés changiér na pâge empleyêe por fâre lo tèxto d’entèrface de la programeria.
 Los changements sè cognetront sur l’aparence de l’entèrface utilisator por los ôtros utilisators de ceti vouiqui.
-Por apondre ou ben changiér des traduccions sur tôs los vouiquis, volyéd empleyér [//translatewiki.net/ translatewiki.net], lo projèt de localisacion de MediaWiki.",
+Por apondre ou ben changiér des traduccions sur tôs los vouiquis, se vos plét empleyéd [//translatewiki.net/ translatewiki.net], lo projèt de localisacion de MediaWiki.",
 'sqlhidden' => '(Demanda SQL cachiêe)',
 'cascadeprotected' => 'Cela pâge-que est protègiêe, el est entrebetâye dedens {{PLURAL:$1|ceta pâge qu’est étâye protègiêe|cetes pâges que sont étâyes protègiêes}} avouéc lo chouèx « protèccion en cascâda » activâ :
 $2',
-'namespaceprotected' => "Vos avéd pas la pèrmission de changiér les pâges de l’èspâço de noms « '''$1''' ».",
-'customcssprotected' => 'Vos avéd pas la pèrmission de changiér cela pâge CSS, contint la configuracion a sè d’un ôtr’utilisator.',
-'customjsprotected' => 'Vos avéd pas la pèrmission de changiér cela pâge JavaScript, contint la configuracion a sè d’un ôtr’utilisator.',
+'namespaceprotected' => "Vos éd pas la pèrmission de changiér les pâges de l’èspâço de noms « '''$1''' ».",
+'customcssprotected' => 'Vos éd pas la pèrmission de changiér cela pâge CSS, contint la configuracion a sè d’un ôtr’utilisator.',
+'customjsprotected' => 'Vos éd pas la pèrmission de changiér cela pâge JavaScript, contint la configuracion a sè d’un ôtr’utilisator.',
 'ns-specialprotected' => 'Les pâges spèciâles pôvont pas étre changiêes.',
 'titleprotected' => "Cél titro est étâ protègiê a la crèacion per [[User:$1|$1]].
 La rêson balyêe est « ''$2'' ».",
-'filereadonlyerror' => 'Empossiblo de changiér lo fichiér « $1 » perce que lo dèpôt de fichiérs « $2 » est justo en lèctura.
+'filereadonlyerror' => 'Y at pas moyen de changiér lo fichiér « $1 » perce que lo dèpôt de fichiérs « $2 » est justo en lèctura.
 
 L’administrator que l’at vèrrolyê at balyê cet’èxplicacion : « $3 ».',
 'invalidtitle-knownnamespace' => 'Titro pas justo avouéc l’èspâço de noms « $2 » et lo tèxto « $3 »',
@@ -742,24 +742,24 @@ Oubliâd pas de changiér voutres [[Special:Preferences|prèferences dessus {{SI
 'logout' => 'Sè dèbranchiér',
 'userlogout' => 'Dèbranchement',
 'notloggedin' => 'Pas branchiê',
-'nologin' => "Vos avéd p’oncor un compto ? '''$1.'''",
+'nologin' => "Vos éd p’oncor un compto ? '''$1.'''",
 'nologinlink' => 'Féte un compto',
 'createaccount' => 'Fâre un compto',
-'gotaccount' => "Vos avéd ja un compto ? '''$1.'''",
+'gotaccount' => "Vos éd ja un compto ? '''$1.'''",
 'gotaccountlink' => 'Branchiéd-vos',
 'userlogin-resetlink' => 'Vos éd oubliâ voutros dètalys de branchement ?',
-'createaccountmail' => 'Empleyér un contresegno temporèro fêt per hasârd et pués lo mandar a l’adrèce èlèctronica spècifiâye ce-desot',
+'createaccountmail' => 'Empleyér un contresegno temporèro fêt per hasârd et lo mandar a l’adrèce èlèctronica spècifiâye ce-desot',
 'createaccountreason' => 'Rêson :',
 'badretype' => 'Los contresegnos que vos éd buchiês sont pas pariérs.',
 'userexists' => 'Lo nom d’utilisator buchiê est ja empleyê.
-Nen volyéd chouèsir un ôtro.',
+Se vos plét, chouèsésséd-nen un ôtro.',
 'loginerror' => 'Fôta de branchement',
-'createaccounterror' => 'Empossiblo de fâre lo compto : $1',
+'createaccounterror' => 'Y at pas moyen de fâre lo compto : $1',
 'nocookiesnew' => "Lo compto utilisator est étâ fêt, mas vos éte pas branchiê{{GENDER:||e|(e)}}.
 {{SITENAME}} emplèye des tèmouens (''cookies'') por lo branchement mas vos los éd dèsactivâs.
-Los volyéd activar et pués vos tornar branchiér avouéc lo mémo nom et lo mémo contresegno.",
+Se vos plét, activâd-los et pués tornâd-vos branchiér avouéc voutron novél nom d’utilisator et voutron contresegno.",
 'nocookieslogin' => "{{SITENAME}} emplèye des tèmouens (''cookies'') por lo branchement mas vos los éd dèsactivâs.
-Los volyéd activar et pués tornar èprovar.",
+Se vos plét, activâd-los et pués tornâd èprovar.",
 'nocookiesfornew' => "Lo compto utilisator est pas étâ fêt, nos ens pas possu confirmar la sina sôrsa.
 Controlâd que vos éd activâ los tèmouens (''cookies''), rechargiéd la pâge et pués tornâd èprovar.",
 'noname' => 'Vos éd pas spècifiâ un nom d’utilisator justo.',
@@ -769,14 +769,14 @@ Controlâd que vos éd activâ los tèmouens (''cookies''), rechargiéd la pâge
 Los noms d’utilisator sont sensiblos a la câssa.
 Controlâd l’ortografia ou ben [[Special:UserLogin/signup|féte un compto novél]].',
 'nosuchusershort' => 'Y at pas un utilisator avouéc lo nom « $1 ».
-Volyéd controlar l’ortografia.',
+Se vos plét, controlâd l’ortografia.',
 'nouserspecified' => 'Vos dête spècifiar un nom d’utilisator.',
 'login-userblocked' => 'Cet’utilisator est blocâ. Branchement pas ôtorisâ.',
 'wrongpassword' => 'Lo contresegno buchiê est fôx.
-Volyéd tornar èprovar.',
+Se vos plét, tornâd èprovar.',
 'wrongpasswordempty' => 'Vos éd pas buchiê de contresegno.
-Volyéd tornar èprovar.',
-'passwordtooshort' => 'Voutron contresegno dêt contegnir u muens $1 caractèro{{PLURAL:$1||s}}.',
+Se vos plét, tornâd èprovar.',
+'passwordtooshort' => 'Voutron contresegno dêt contegnir por lo muens $1 caractèro{{PLURAL:$1||s}}.',
 'password-name-match' => 'Voutron contresegno dêt étre difèrent de voutron nom d’utilisator.',
 'password-login-forbidden' => 'L’usâjo de cél nom d’utilisator et de cél contresegno est étâ dèfendu.',
 'mailmypassword' => 'Recêvre un contresegno novél per mèssageria èlèctronica',
@@ -793,22 +793,22 @@ pouede ignorar ceti mèssâjo et continuar a empleyér voutron viely contresegno
 'noemail' => 'Nion’adrèce èlèctronica est étâye encartâye por l’utilisator « $1 ».',
 'noemailcreate' => 'Vos dête balyér n’adrèce èlèctronica justa',
 'passwordsent' => 'Un contresegno novél est étâ mandâ a l’adrèce èlèctronica de l’utilisator « $1 ».
-Vos volyéd tornar branchiér aprés l’avêr reçu.',
+Se vos plét, tornâd-vos branchiér aprés l’avêr reçu.',
 'blocked-mailpassword' => 'Voutron adrèce IP est blocâye en ècritura, la fonccion de sovegnence du contresegno est vêr dèsactivâye por èvitar los abus.',
 'eauthentsent' => 'Un mèssâjo de confirmacion est étâ mandâ a l’adrèce èlèctronica endicâye.
 Devant qu’un ôtro mèssâjo seye mandâ a ceti compto, vos devréd siuvre les enstruccions du mèssâjo et pués confirmar que lo compto est franc lo voutro.',
 'throttled-mailpassword' => 'Un mèssâjo de sovegnence de voutron contresegno est ja étâ mandâ pendent {{PLURAL:$1|l’hora passâye|les $1 hores passâyes}}.
 Por èvitar los abus, ren que yon serat mandâ per {{PLURAL:$1|hora|entèrvalo de $1 hores}}.',
 'mailerror' => 'Fôta pendent l’èxpèdicion du mèssâjo : $1',
-'acct_creation_throttle_hit' => 'Yon qu’emplèye voutron adrèce IP at fêt {{PLURAL:$1|un compto|$1 comptos}} pendent les 24 hores passâyes, cen qu’est la limita ôtorisâye dens ceti temps.
-Du côp la crèacion de compto est étâye dèsactivâye temporèrament por cel’adrèce IP.',
+'acct_creation_throttle_hit' => 'Des visitors de cél vouiqui-que qu’emplèyont voutron adrèce IP ont fêt $1 compto{{PLURAL:$1||s}} pendent lo jorn passâ, cen qu’est lo més ôtorisâ dens ceti temps.
+Du côp los visitors qu’emplèyont cel’adrèce IP pôvont fâre gins de compto por lo moment.',
 'emailauthenticated' => 'Voutron adrèce èlèctronica est étâye ôtentifiâye lo $2 a $3.',
 'emailnotauthenticated' => 'Voutron adrèce èlèctronica est p’oncor ôtentifiâye.
 Nion mèssâjo serat mandâ por châcuna de cetes fonccionalitâts.',
 'noemailprefs' => 'Spècifiâd n’adrèce èlèctronica dens voutres prèferences por empleyér cetes fonccionalitâts.',
 'emailconfirmlink' => 'Confirmâd voutron adrèce èlèctronica',
 'invalidemailaddress' => 'Cet’adrèce èlèctronica pôt pas étre accèptâye, semble avêr un format pas justo.
-Volyéd buchiér n’adrèce bien formatâye ou ben lèssiér cél champ vouedo.',
+Se vos plét, buchiéd n’adrèce bien formatâye ou ben lèssiéd cél champ vouedo.',
 'cannotchangeemail' => 'Les adrèces èlèctroniques des comptos pôvont pas étre changiêes sur ceti vouiqui.',
 'emaildisabled' => 'Ceti seto pôt pas mandar des mèssâjos.',
 'accountcreated' => 'Compto fêt',
@@ -820,15 +820,15 @@ Vos vos devriâd branchiér et pués changiér dês ora voutron contresegno.
 Ignorâd ceti mèssâjo se cél compto est étâ fêt per fôta.',
 'usernamehasherror' => 'Lo nom d’utilisator pôt pas contegnir des caractèros de chaplâjo',
 'login-throttled' => 'Dês pou vos éd èprovâ un mouél de branchements.
-Volyéd atendre devant que tornar èprovar.',
+Se vos plét, atende devant que tornar èprovar.',
 'login-abort-generic' => 'Voutra tentativa de branchement at pas reussi - Anulâye',
 'loginlanguagelabel' => 'Lengoua : $1',
 'suspicious-userlogout' => 'Voutra demanda de dèbranchement est étâye refusâye, semble qu’el est étâye mandâye per un navigator câsso ou ben la misa en cacho d’un proxi.',
 
 # E-mail sending
 'php-mail-error-unknown' => 'Fôta encognua dens la fonccion mail() de PHP.',
-'user-mail-no-addy' => 'Il at tâchiê de mandar un mèssâjo sen adrèce èlèctronica.',
-'user-mail-no-body' => 'Il at tâchiê de mandar un mèssâjo avouéc un côrp vouedo ou ben dèrêsonâblament côrt.',
+'user-mail-no-addy' => 'Il at èprovâ de mandar un mèssâjo sen adrèce èlèctronica.',
+'user-mail-no-body' => 'Il at èprovâ de mandar un mèssâjo avouéc un côrp vouedo ou ben dèrêsonâblament côrt.',
 
 # Change password dialog
 'resetpass' => 'Changiér lo contresegno',
@@ -841,7 +841,7 @@ Por chavonar lo branchement, vos dête buchiér un contresegno novél ique :',
 'retypenew' => 'Confirmar lo contresegno novél :',
 'resetpass_submit' => 'Changiér lo contresegno et pués sè branchiér',
 'resetpass_success' => 'Voutron contresegno est étâ changiê avouéc reusséta !
-Branchement en cors...',
+Branchement en côrs...',
 'resetpass_forbidden' => 'Los contresegnos pôvont pas étre changiês',
 'resetpass-no-info' => 'Vos dête étre branchiê por arrevar tot drêt a cela pâge.',
 'resetpass-submit-loggedin' => 'Changiér lo contresegno',
@@ -858,7 +858,7 @@ Pôt-étre vos éd ja changiê voutron contresegno avouéc reusséta ou ben dema
 'passwordreset-pretext' => '{{PLURAL:$1||Buchiéd yona de les piéces de donâs ce-desot}}',
 'passwordreset-username' => 'Nom d’utilisator :',
 'passwordreset-domain' => 'Domêno :',
-'passwordreset-capture' => '’T-o que vos voléd vêre lo mèssâjo que rèsulte ?',
+'passwordreset-capture' => 'Est-o que vos voléd vêre lo mèssâjo que rèsulte ?',
 'passwordreset-capture-help' => 'Se vos pouentâd cela câsa, lo mèssâjo (avouéc lo contresegno temporèro) vos serat montrâ quand serat mandâ a l’utilisator.',
 'passwordreset-email' => 'Adrèce èlèctronica :',
 'passwordreset-emailtitle' => 'Dètalys du compto dessus {{SITENAME}}',
@@ -917,7 +917,7 @@ Contresegno temporèro : $2',
 'image_tip' => 'Fichiér apondu',
 'media_sample' => 'Ègzemplo.ogg',
 'media_tip' => 'Lim de vers un fichiér',
-'sig_tip' => 'Voutra signatura avouéc la dâta et hora',
+'sig_tip' => 'Voutra signatura avouéc l’horodatâjo',
 'hr_tip' => 'Legne plana (pas nen abusar)',
 
 # Edit pages
@@ -935,7 +935,7 @@ Voutron adrèce IP serat encartâye dedens l’historico des changements de ceta
 'anonpreviewwarning' => "''Vos éte pas branchiê(e). Sôvar encarterat voutron adrèce IP dedens l’historico des changements de ceta pâge.''",
 'missingsummary' => "'''Sovegnence :''' vos éd balyê gins de rèsumâ de changement.
 Se vos tornâd clicar sur lo boton « {{int:savearticle}} », voutron changement serat encartâ sen rèsumâ.",
-'missingcommenttext' => 'Volyéd buchiér un comentèro ce-desot.',
+'missingcommenttext' => 'Se vos plét, buchiéd un comentèro ce-desot.',
 'missingcommentheader' => "'''Sovegnence :''' vos éd balyê gins de chousa / titro a ceti comentèro.
 Se vos tornâd clicar sur lo boton « {{int:savearticle}} », voutron changement serat encartâ sen chousa / titro.",
 'summary-preview' => 'Apèrçu du rèsumâ :',
@@ -951,9 +951,9 @@ La rêson balyêe est ''$2''.
 * Compto blocâ : $7
 
 Vos vos pouede veriér vers $1 ou ben un ôtr’[[{{MediaWiki:Grouppage-sysop}}|administrator]] por nen discutar.
-Vos pouede pas empleyér la fonccionalitât « Lui mandar un mèssâjo » a muens qu’un’adrèce èlèctronica justa est spècifiâye dens voutres [[Special:Preferences|prèferences]] et que vos éte pas étâ blocâ de l’empleyér.
+Vos pouede pas empleyér la fonccionalitât « Lui mandar un mèssâjo » du muens qu’un’adrèce èlèctronica justa seye spècifiâye dens voutres [[Special:Preferences|prèferences]] et que vos seyâd pas étâ blocâ de l’empleyér.
 Voutron adrèce IP d’ora est $3, et l’identifient de blocâjo est $5.
-Volyéd entrebetar tôs los dètalys ce-dessus dedens na sé-quinta demanda que vos faréd.",
+Se vos plét, entrebetâd tôs los dètalys ce-dessus dedens na demanda la quinta que seye que vos faréd.",
 'autoblockedtext' => "Voutron adrèce IP est étâye blocâye ôtomaticament, el est étâye empleyêe per un ôtr’utilisator, lui-mémo blocâ per $1.
 La rêson balyêe est :
 
@@ -965,16 +965,16 @@ La rêson balyêe est :
 
 Vos vos pouede veriér vers $1 ou ben yon des ôtros [[{{MediaWiki:Grouppage-sysop}}|administrators]] por nen discutar.
 
-Notâd que vos porréd pas empleyér la fonccionalitât « Lui mandar un mèssâjo » a muens que vos avéd n’adrèce èlèctronica justa encartâye dens voutres [[Special:Preferences|prèferences]] et que vos éte pas étâ blocâ de l’empleyér.
+Notâd que vos porréd pas empleyér la fonccionalitât « Lui mandar un mèssâjo » du muens que vos èyâd n’adrèce èlèctronica justa encartâye dens voutres [[Special:Preferences|prèferences]] et que vos seyâd pas étâ blocâ de l’empleyér.
 
 Voutron adrèce IP d’ora est $3, et l’identifient de blocâjo est $5.
-Volyéd entrebetar tôs los dètalys ce-dessus dedens na sé-quinta demanda que vos faréd.",
+Se vos plét, entrebetâd tôs los dètalys ce-dessus dedens na demanda la quinta que seye que vos faréd.",
 'blockednoreason' => 'niona rêson balyêe',
 'whitelistedittext' => 'Vos vos dête $1 por povêr changiér les pâges.',
 'confirmedittext' => 'Vos dête confirmar voutron adrèce èlèctronica devant que changiér les pâges.
-Volyéd buchiér et pués validar voutron adrèce èlèctronica dens voutres [[Special:Preferences|prèferences]].',
-'nosuchsectiontitle' => 'Empossiblo de trovar la sèccion',
-'nosuchsectiontext' => 'Vos éd tâchiê de changiér na sèccion qu’ègziste pas.
+Se vos plét, buchiéd et pués validâd voutron adrèce èlèctronica dens voutres [[Special:Preferences|prèferences]].',
+'nosuchsectiontitle' => 'Y at pas moyen de trovar la sèccion',
+'nosuchsectiontext' => 'Vos éd èprovâ de changiér na sèccion qu’ègziste pas.
 Pôt-étre el est étâye dèplaciêe ou ben ôtâye dês que vos éd liesu cela pâge.',
 'loginreqtitle' => 'Branchement nècèssèro',
 'loginreqlink' => 'branchiér',
@@ -988,21 +988,21 @@ Lo contresegno por cél compto novél pôt étre changiê sur la pâge de ''[[Sp
 Por fâre cela pâge, buchiéd voutron tèxto dedens la bouèta ce-desot (vêde la [[{{MediaWiki:Helppage}}|pâge d’éde]] por més d’enformacions).
 Se vos éte arrevâ{{GENDER:||ye|(ye)}} ice per fôta, clicâd sur lo boton '''Devant''' de voutron navigator.",
 'anontalkpagetext' => "----''O est la pâge de discussion d’un utilisator anonimo qu’at p’oncor fêt un compto ou ben que nen emplèye pas.
-Por cen nos devens empleyér la sin’adrèce IP numerica por l’identifiar.
-N’adrèce IP pôt étre partagiêe per un mouél d’utilisators.
-Se vos éte {{GENDER:|un utilisator|n’utilisatrice|un utilisator}} anonim{{GENDER:|o|a|o}} et pués se vos constatâd que des comentèros que vos regârdont pas vos sont étâs adrèciês, volyéd [[Special:UserLogin/signup|fâre un compto]] ou ben [[Special:UserLogin|vos branchiér]] por èvitar tota confusion a vegnir avouéc d’ôtros utilisators anonimos.''",
+Por cen nos devens empleyér la sin’adrèce IP numerica por lo recognetre.
+N’adrèce IP d’ense pôt étre partagiêe per un mouél d’utilisators.
+Se vos éte {{GENDER:|un utilisator|n’utilisatrice|un utilisator}} anonim{{GENDER:|o|a|o}} et pués se vos constatâd que des comentèros que vos regârdont pas vos sont étâs adrèciês, se vos plét [[Special:UserLogin/signup|féte un compto]] ou ben [[Special:UserLogin|branchiéd-vos]] por èvitar tota confusion a vegnir avouéc d’ôtros utilisators anonimos.''",
 'noarticletext' => 'Ora y at gins de tèxto dedens cela pâge.
 Vos pouede [[Special:Search/{{PAGENAME}}|fâre na rechèrche sur cél titro]] dedens les ôtres pâges,
 <span class="plainlinks">[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} rechèrchiér dedens los jornals liyês]
 ou ben [{{fullurl:{{FULLPAGENAME}}|action=edit}} fâre cela pâge]</span>.',
 'noarticletext-nopermission' => 'Ora y at gins de tèxto dedens cela pâge.
-Vos pouede [[Special:Search/{{PAGENAME}}|fâre na rechèrche sur cél titro]] dedens les ôtres pâges ou ben <span class="plainlinks">[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} rechèrchiér dedens los jornals liyês]</span>, mas vos avéd pas la pèrmission de fâre cela pâge.',
+Vos pouede [[Special:Search/{{PAGENAME}}|fâre na rechèrche sur cél titro]] dedens les ôtres pâges ou ben <span class="plainlinks">[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} rechèrchiér dedens los jornals liyês]</span>, mas vos éd pas la pèrmission de fâre cela pâge.',
 'missing-revision' => 'La vèrsion numerô $1 de la pâge apelâye « {{PAGENAME}} » ègziste pas.
 
 En g·ènèral cen arreve en siuvent un lim d’un historico dèpassâ de vers na pâge qu’est étâye suprimâye.
 Vos pouede trovar més de dètalys dedens lo [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} jornal de les suprèssions].',
 'userpage-userdoesnotexist' => 'Lo compto utilisator « $1 » est pas encartâ.
-Volyéd controlar que vos voléd fâre ou ben changiér cela pâge.',
+Se vos plét, controlâd que vos voléd fâre / changiér cela pâge.',
 'userpage-userdoesnotexist-view' => 'Lo compto utilisator « $1 » est pas encartâ.',
 'blocked-notice-logextract' => '{{GENDER:$1|Cél utilisator|Cel’utilisatrice|Cél utilisator}} est ora blocâ{{GENDER:$1||ye|}}.
 La dèrriére entrâ du jornal des blocâjos est disponibla ce-desot :',
@@ -1027,17 +1027,17 @@ Rapelâd-vos que les pâges a sè avouéc èxtensions .css et .js emplèyont des
 'note' => "'''Nota :'''",
 'previewnote' => "'''Rapelâd-vos qu’o est ren qu’un apèrçu.'''
 Voutros changements sont p’oncor étâs encartâs !",
-'continue-editing' => 'Alar a la zona de changement',
+'continue-editing' => 'Alar vers la zona de changement',
 'previewconflict' => 'Cet’apèrçu fât vêre lo tèxto de la zona de changement de d’amont coment aparêtrat se vos chouèsésséd de l’encartar.',
 'session_fail_preview' => "'''Dèconsolâ ! Nos povens pas encartar voutron changement a côsa d’una pèrta d’enformacions sur voutra sèance.'''
-Volyéd tornar èprovar.
-Se cen tôrne pas reussir, vos volyéd [[Special:UserLogout|dèbranchiér]] et pués vos tornar branchiér.",
+Se vos plét, tornâd èprovar.
+Se cen tôrne pas reussir, [[Special:UserLogout|dèbranchiéd-vos]] et pués tornâd-vos branchiér.",
 'session_fail_preview_html' => "'''Dèconsolâ ! Nos povens pas encartar voutron changement a côsa d’una pèrta d’enformacions sur voutra sèance.'''
 
 ''Perce que {{SITENAME}} at activâ l’HTML bruto, l’apèrçu est étâ cachiê por prèvegnir les ataques per JavaScript.''
 
-'''Se la tentativa de changement ére lèg·itima, volyéd tornar èprovar.'''
-Se cen tôrne pas reussir, vos volyéd [[Special:UserLogout|dèbranchiér]] et pués vos tornar branchiér.",
+'''Se la tentativa de changement ére lèg·itima, se vos plét tornâd èprovar.'''
+Se cen tôrne pas reussir, [[Special:UserLogout|dèbranchiéd-vos]] et pués tornâd-vos branchiér.",
 'token_suffix_mismatch' => "'''Voutron changement est pas étâ accèptâ, voutron cliant at mècllâ los caractèros de ponctuacion dedens lo jeton de changement.'''
 Lo changement est étâ refusâ por empachiér la corrupcion du tèxto de la pâge.
 Des côps ceti problèmo arreve quand vos empleyéd un sèrviço de proxi Vouèbe anonimo qu’est pas de sûr.",
@@ -1059,12 +1059,12 @@ Na solucion de rechanjo est étâye trovâye por vos pèrmetre de changiér en t
 'editingold' => "'''Atencion : vos éte aprés changiér na vèrsion dèpassâye de cela pâge.'''
 Se vos l’encartâd, tôs los changements fêts dês ceta vèrsion seront pèrdus.",
 'yourdiff' => 'Difèrences',
-'copyrightwarning' => "Volyéd notar que totes les contribucions a {{SITENAME}} sont considèrâyes coment publeyêes desot los tèrmos de la $2 (vêde $1 por més de dètalys).
-Se vos voléd pas que voutros ècrits seyont changiês sen pouent de rèstriccion et pués rebalyês a volontât, adonc los volyéd pas mandar ique.<br />
+'copyrightwarning' => "Se vos plét, notâd que totes les contribucions a {{SITENAME}} sont considèrâyes coment publeyêes desot los tèrmos de la $2 (vêde $1 por més de dètalys).
+Se vos voléd pas que voutros ècrits seyont changiês sen pouent de rèstriccion et rebalyês a volontât, adonc mandâd-los pas ique.<br />
 Vos nos assurâd asse-ben que vos éd cen ècrit vos-mémo ou ben que vos l’éd copiyê d’una sôrsa que vint du domêno publico ou d’un’ôtra ressôrsa libra.
 '''Empleyéd gins d’ôvra desot drêt d’ôtor sen pèrmission èxprèssa !'''",
-'copyrightwarning2' => "Volyéd notar que totes les contribucions a {{SITENAME}} pôvont étre changiêes ou ben enlevâyes per d’ôtros contributors.
-Se vos voléd pas que voutros ècrits seyont changiês sen pouent de rèstriccion, adonc los volyéd pas mandar ique.<br />
+'copyrightwarning2' => "Se vos plét, notâd que totes les contribucions a {{SITENAME}} pôvont étre changiêes ou ben enlevâyes per d’ôtros contributors.
+Se vos voléd pas que voutros ècrits seyont changiês sen pouent de rèstriccion, adonc mandâd-los pas ique.<br />
 Vos nos assurâd asse-ben que vos éd cen ècrit vos-mémo ou ben que vos l’éd copiyê d’una sôrsa que vint du domêno publico ou d’un’ôtra ressôrsa libra (vêde $1 por més de dètalys).
 '''Empleyéd gins d’ôvra desot drêt d’ôtor sen pèrmission èxprèssa !'''",
 'longpageerror' => "'''Fôta : lo tèxto que vos éd mandâ fât {{PLURAL:$1|un Kio|$1 Kio}}, cen que dèpâsse la limita fixâye a {{PLURAL:$2|un Kio|$2 Kio}}.'''
@@ -1089,12 +1089,12 @@ Por refèrence, la dèrriére entrâ du jornal est balyêe ce-desot :",
 'edittools' => '<!-- Tot tèxto buchiê ique serat montrâ desot les bouètes d’èdicion ou ben los formulèros de tèlèchargement de fichiér. -->',
 'nocreatetext' => '{{SITENAME}} at rètrent la possibilitât de fâre de pâges novèles.
 Vos pouede tornar arriér et pués changiér na pâge ègzistenta ou ben [[Special:UserLogin|vos branchiér ou fâre un compto]].',
-'nocreate-loggedin' => 'Vos avéd pas la pèrmission de fâre de pâges novèles.',
+'nocreate-loggedin' => 'Vos éd pas la pèrmission de fâre de pâges novèles.',
 'sectioneditnotsupported-title' => 'Changement de sèccion pas recognu',
 'sectioneditnotsupported-text' => 'Lo changement d’una sèccion est pas recognu dens cela pâge.',
 'permissionserrors' => 'Fôta de pèrmissions',
-'permissionserrorstext' => 'Vos avéd pas la pèrmission de fâre l’accion demandâye por {{PLURAL:$1|ceta rêson|cetes rêsons}} :',
-'permissionserrorstext-withaction' => 'Vos avéd pas la pèrmission de $2 por {{PLURAL:$1|ceta rêson|cetes rêsons}} :',
+'permissionserrorstext' => 'Vos éd pas la pèrmission de fâre l’accion demandâye por {{PLURAL:$1|ceta rêson|cetes rêsons}} :',
+'permissionserrorstext-withaction' => 'Vos éd pas la pèrmission de $2 por {{PLURAL:$1|ceta rêson|cetes rêsons}} :',
 'recreate-moveddeleted-warn' => "'''Atencion : vos éte aprés refâre na pâge qu’est étâye suprimâye dês devant.'''
 
 Demandâd-vos se fôt franc continuar son changement.
@@ -1104,11 +1104,11 @@ Por refèrence, lo jornal de les suprèssions et des dèplacements de cela pâge
 'log-fulllog' => 'Vêre lo jornal complèt',
 'edit-hook-aborted' => 'Changement anulâ per un grèfon.
 Nion’èxplicacion est étâye balyêe.',
-'edit-gone-missing' => 'Empossiblo de betar a jorn la pâge.
+'edit-gone-missing' => 'Y at pas moyen de betar a jorn la pâge.
 Semble que seye étâye suprimâye.',
 'edit-conflict' => 'Conflit de changement.',
 'edit-no-change' => 'Voutron changement est étâ ignorâ, nion changement est étâ fêt u tèxto.',
-'edit-already-exists' => 'Empossiblo de fâre na pâge novèla.
+'edit-already-exists' => 'Y at pas moyen de fâre na pâge novèla.
 Ègziste ja.',
 'defaultmessagetext' => 'Mèssâjo per dèfôt',
 'content-failed-to-parse' => 'Falyita de l’analisa du contegnu de $2 por lo modèlo $1 : $3',
@@ -1129,7 +1129,7 @@ Y devrêt avêr muens de $2 apèl{{PLURAL:$2||s}}, pendent qu’y en at ora $1."
 'post-expand-template-inclusion-warning' => "'''Atencion :''' la talye des modèlos entrebetâs est trop grôssa.
 Quârques modèlos seront pas entrebetâs.",
 'post-expand-template-inclusion-category' => 'Pâges yô que la talye des modèlos entrebetâs est dèpassâye',
-'post-expand-template-argument-warning' => "'''Atencion :''' cela pâge contint u muens un argument de modèlo qu’at na talye d’èxpension trop grôssa.
+'post-expand-template-argument-warning' => "'''Atencion :''' cela pâge contint por lo muens un argument de modèlo qu’at na talye d’èxpension trop grôssa.
 Celos arguments sont pas étâs betâs.",
 'post-expand-template-argument-category' => 'Pâges que contegnont des arguments de modèlo pas betâs',
 'parser-template-loop-warning' => 'Modèlo en boclla dècelâ : [[$1]]',
@@ -1145,13 +1145,13 @@ Celos arguments sont pas étâs betâs.",
 
 # "Undo" feature
 'undo-success' => 'Lo changement pôt étre dèfêt.
-Volyéd controlar la comparèson ce-desot por vos assurar qu’o est franc cen que vos voléd fâre et pués encartar los changements ce-desot por chavonar la sina dèfêta.',
+Se vos plét, controlâd la comparèson ce-desot por vos assurar qu’o est franc cen que vos voléd fâre et pués encartâd los changements ce-desot por chavonar la sina dèfêta.',
 'undo-failure' => 'Lo changement at pas possu étre dèfêt a côsa d’un conflit avouéc des changements entèrmèdièros.',
 'undo-norev' => 'Lo changement at pas possu étre dèfêt perce qu’il est pas ègzistent ou ben qu’il est étâ suprimâ.',
 'undo-summary' => 'Dèfêta du changement $1 de [[Special:Contributions/$2|$2]] ([[User talk:$2|discutar]])',
 
 # Account creation failure
-'cantcreateaccounttitle' => 'Empossiblo de fâre lo compto',
+'cantcreateaccounttitle' => 'Y at pas moyen de fâre lo compto',
 'cantcreateaccount-text' => "La crèacion de compto dês cet’adrèce IP ('''$1''') est étâye blocâye per [[User:$3|$3]].
 
 La rêson balyêe per $3 ére ''$2''.",
@@ -1186,7 +1186,7 @@ Lègenda : '''({{int:cur}})''' = difèrence avouéc la vèrsion d’ora, '''({{i
 'history-feed-item-nocomment' => '$1 lo $3 a $4',
 'history-feed-empty' => 'La pâge demandâye ègziste pas.
 Pôt-étre el est étâye suprimâye du vouiqui ou ben renomâye.
-Tâchiéd de [[Special:Search|rechèrchiér sur lo vouiqui]] por trovar des pâges novèles que vont avouéc.',
+Èprovâd de [[Special:Search|rechèrchiér sur lo vouiqui]] por trovar des pâges novèles que vont avouéc.',
 
 # Revision deletion
 'rev-deleted-comment' => '(rèsumâ de changement enlevâ)',
@@ -1223,23 +1223,23 @@ Vos pouede vêre ceta dif ; y pôt avêr més de dètalys dedens lo [{{fullurl:{
 'revisiondelete' => 'Suprimar / refâre des vèrsions',
 'revdelete-nooldid-title' => 'Vèrsion ciba pas justa',
 'revdelete-nooldid-text' => 'Vos éd pas spècifiâ na vèrsion ciba (des vèrsions cibes) por fâre cela
-fonccion, la vèrsion spècifiâye ègziste pas ou ben vos tâchiéd de cachiér la vèrsion d’ora.',
+fonccion, la vèrsion spècifiâye ègziste pas ou ben vos èprovâd de cachiér la vèrsion d’ora.',
 'revdelete-nologtype-title' => 'Nion tipo de jornal balyê',
 'revdelete-nologtype-text' => 'Vos éd pas spècifiâ un tipo de jornal por fâre cel’accion.',
 'revdelete-nologid-title' => 'Entrâ du jornal pas justa',
 'revdelete-nologid-text' => 'Ou ben vos éd pas spècifiâ un èvènement du jornal ciba por fâre cela fonccion ou ben l’entrâ spècifiâye ègziste pas.',
 'revdelete-no-file' => 'Lo fichiér spècifiâ ègziste pas.',
-'revdelete-show-file-confirm' => '’T-o que vos éte de sûr de volêr vêre na vèrsion suprimâye du fichiér « <nowiki>$1</nowiki> » du $2 a $3 ?',
+'revdelete-show-file-confirm' => 'Est-o que vos éte de sûr de volêr vêre na vèrsion suprimâye du fichiér « <nowiki>$1</nowiki> » du $2 a $3 ?',
 'revdelete-show-file-submit' => 'Ouè',
 'revdelete-selected' => "'''{{PLURAL:$2|Vèrsion chouèsia|Vèrsions chouèsies}} de [[:$1]] :'''",
 'logdelete-selected' => "'''{{PLURAL:$1|Èvènement du jornal chouèsi|Èvènements du jornal chouèsis}} :'''",
 'revdelete-text' => "'''Les vèrsions et los èvènements suprimâ(ye)s aparètront adés dedens l’historico de la pâge et pués dedens los jornals, mas quârques parties de lor contegnu seront inaccèssibles u publico.'''
-Los ôtros administrators de {{SITENAME}} porront tojorn arrevar u contegnu cachiê et lo refâre per cela mém’entèrface, a muens que des rèstriccions de ples seyont pas dèfenies.",
-'revdelete-confirm' => 'Volyéd confirmar qu’o est franc cen que vos voléd fâre, que vos en compregnéd les consèquences et pués que vos o féte en acôrd avouéc les [[{{MediaWiki:Policy-url}}|règlles de dedens]].',
+Los ôtros administrators de {{SITENAME}} porront tojorn arrevar u contegnu cachiê et lo refâre per cela mém’entèrface, du muens que des rèstriccions de ples seyont pas dèfenies.",
+'revdelete-confirm' => 'Se vos plét, confirmâd qu’o est franc cen que vos voléd fâre, que vos en compregnéd les consèquences et pués que vos o féte en acôrd avouéc les [[{{MediaWiki:Policy-url}}|règlles de dedens]].',
 'revdelete-suppress-text' => "La rèprèssion dêt étre empleyêe '''ren que''' dens cetos câs :
 * Enformacions que pôvont étre difamatouères
 * Enformacions a sè que vont pas avouéc
-*: ''adrèces et numerôs de tèlèfono, numerôs de sècuritât sociâla, ...''",
+*: ''adrèces et numerôs de tèlèfono, numerôs de sècuritât sociâla, et tot cen que vat avouéc''",
 'revdelete-legend' => 'Dèfenir des rèstriccions de visibilitât',
 'revdelete-hide-text' => 'Cachiér lo tèxto de la vèrsion',
 'revdelete-hide-image' => 'Cachiér lo contegnu du fichiér',
@@ -1268,13 +1268,13 @@ $1",
 'revdelete-hide-current' => 'Fôta en cachient la piéce datâye du $1 a $2 : o est la vèrsion d’ora.
 Pôt pas étre cachiêe.',
 'revdelete-show-no-access' => 'Fôta en montrent la piéce datâye du $1 a $2 : el est marcâye coment « rètrenta ».
-Vos y avéd pas accès.',
+Vos y éd pas accès.',
 'revdelete-modify-no-access' => 'Fôta en changient la piéce datâye du $1 a $2 : el est marcâye coment « rètrenta ».
-Vos y avéd pas accès.',
+Vos y éd pas accès.',
 'revdelete-modify-missing' => 'Fôta en changient la piéce avouéc l’identifient $1 : el est manquenta dedens la bâsa de donâs !',
 'revdelete-no-change' => "'''Atencion :''' la piéce datâye du $1 a $2 at ja la configuracion de visibilitât demandâye.",
-'revdelete-concurrent-change' => 'Fôta en changient la piéce datâye du $1 a $2 : lo sin statut semble étre étâ changiê per un ôtro justo que vos tâchiêvâd d’o changiér.
-Volyéd controlar los jornals.',
+'revdelete-concurrent-change' => 'Fôta en changient la piéce datâye du $1 a $2 : lo sin statut semble étre étâ changiê per un ôtro justo que vos èprovâvâd d’o changiér.
+Se vos plét, controlâd los jornals.',
 'revdelete-only-restricted' => 'Fôta en cachient la piéce datâye du $1 a $2 : vos pouede pas rèprimar celes piéces de la vua ux administrators sen chouèsir avouéc des ôtros chouèx de visibilitât.',
 'revdelete-reason-dropdown' => '*Rêsons corentes de suprèssion
 ** Violacion du drêt d’ôtor
@@ -1306,7 +1306,7 @@ Notâd que l’usâjo des lims de navigacion remetrat a zérô cela colona.',
 'mergehistory-submit' => 'Fusionar les vèrsions',
 'mergehistory-empty' => 'Niona vèrsion pôt étre fusionâye.',
 'mergehistory-success' => '$3 vèrsion{{PLURAL:$3||s}} de [[:$1]] fusionâye{{PLURAL:$3||s}} avouéc reusséta dedens [[:$2]].',
-'mergehistory-fail' => 'Empossiblo de fâre la fusion des historicos, volyéd tornar chouèsir la pâge et pués los paramètros de dâta.',
+'mergehistory-fail' => 'Y at pas moyen de fâre la fusion des historicos, se vos plét tornâd chouèsir la pâge et pués los paramètros de dâta.',
 'mergehistory-no-source' => 'La pâge d’origina $1 ègziste pas.',
 'mergehistory-no-destination' => 'La pâge de dèstinacion $1 ègziste pas.',
 'mergehistory-invalid-source' => 'La pâge d’origina dêt avêr un titro justo.',
@@ -1344,7 +1344,7 @@ Vos pouede trovar més de dètalys dedens lo [{{fullurl:{{#Special:Log}}/delete|
 'searchresulttext' => 'Por més d’enformacions sur la rechèrche dedens {{SITENAME}}, vêde [[{{MediaWiki:Helppage}}|{{int:help}}]].',
 'searchsubtitle' => "Vos éd rechèrchiê « '''[[:$1]]''' » ([[Special:Prefixindex/$1|totes les pâges que començont per « $1 »]]{{int:pipe-separator}}[[Special:WhatLinksHere/$1|totes les pâges qu’ont un lim de vers « $1 »]])",
 'searchsubtitleinvalid' => "Vos éd rechèrchiê « '''$1''' »",
-'toomanymatches' => 'Un mouél de corrèspondances est étâ retornâ, volyéd èprovar na rechèrche difèrenta.',
+'toomanymatches' => 'Un mouél de corrèspondances est étâ retornâ, se vos plét èprovâd na rechèrche difèrenta',
 'titlematches' => 'Corrèspondances dedens los titros de les pâges',
 'notitlematches' => 'Niona corrèspondance dedens los titros de les pâges',
 'textmatches' => 'Corrèspondances dedens lo tèxto de les pâges',
@@ -1380,7 +1380,7 @@ Vos pouede trovar més de dètalys dedens lo [{{fullurl:{{#Special:Log}}/delete|
 'search-interwiki-default' => 'Rèsultats dessus $1 :',
 'search-interwiki-more' => '(més)',
 'search-relatedarticle' => 'Aparentâ',
-'mwsuggest-disable' => 'Dèsactivar les idês AJAX',
+'mwsuggest-disable' => 'Dèsactivar les idês de rechèrche',
 'searcheverything-enable' => 'Rechèrchiér dedens tôs los èspâços de noms',
 'searchrelated' => 'aparentâ',
 'searchall' => 'tot',
@@ -1388,7 +1388,7 @@ Vos pouede trovar més de dètalys dedens lo [{{fullurl:{{#Special:Log}}/delete|
 'showingresultsnum' => "Vua de '''$3''' rèsultat{{PLURAL:$3||s}} dês lo numerô '''$2'''.",
 'showingresultsheader' => "{{PLURAL:$5|Rèsultat '''$1'''|Rèsultats '''$1 - $2'''}} de '''$3''' por '''$4'''",
 'nonefound' => "'''Nota :''' solament quârques èspâços de noms sont rechèrchiês per dèfôt.
-Èprovâd en empleyent lo prèfixo ''all:'' por rechèrchiér dedens tot lo contegnu (les pâges de discussion, los modèlos, ... avouéc) ou ben empleyéd l’èspâço de noms volu coment prèfixo.",
+Èprovâd en empleyent lo prèfixo ''all:'' por rechèrchiér dedens tot lo contegnu (les pâges de discussion, los modèlos, et tot cen que vat avouéc) ou ben empleyéd l’èspâço de noms volu coment prèfixo.",
 'search-nonefound' => 'Y at gins de rèsultat que corrèspond a la rechèrche.',
 'powersearch' => 'Rechèrche avanciêe',
 'powersearch-legend' => 'Rechèrche avanciêe',
@@ -1396,8 +1396,8 @@ Vos pouede trovar més de dètalys dedens lo [{{fullurl:{{#Special:Log}}/delete|
 'powersearch-redir' => 'Listar les redirèccions',
 'powersearch-field' => 'Rechèrchiér',
 'powersearch-togglelabel' => 'Chouèsir :',
-'powersearch-toggleall' => 'Tot',
-'powersearch-togglenone' => 'Nion',
+'powersearch-toggleall' => 'Tôs',
+'powersearch-togglenone' => 'Pas yon',
 'search-external' => 'Rechèrche de defôr',
 'searchdisabled' => 'La rechèrche dessus {{SITENAME}} est dèsactivâye.
 Pendent cél temps, vos pouede fâre na rechèrche avouéc Google.
@@ -1454,7 +1454,7 @@ Notâd que lor endèxacion du contegnu de {{SITENAME}} pôt pas étre a jorn.',
 'recentchangesdays' => 'Nombro de jorns a montrar dedens los dèrriérs changements :',
 'recentchangesdays-max' => 'Por lo més $1 jorn{{PLURAL:$1||s}}',
 'recentchangescount' => 'Nombro de changements a montrar per dèfôt :',
-'prefs-help-recentchangescount' => 'Los dèrriérs changements, los historicos de pâges et pués los jornals avouéc.',
+'prefs-help-recentchangescount' => 'Los dèrriérs changements, los historicos de pâges et los jornals avouéc.',
 'prefs-help-watchlist-token' => 'Rempléd ceti champ avouéc na cllâf secrèta et pués un flux RSS serat fêt por voutra lista de siuvu.
 Tôs celos que cognessont cela cllâf porront liére voutra lista de siuvu, chouèsésséd vêr na valor sècurisâye.
 Vê-que na valor fêta per hasârd que vos pouede empleyér : $1',
@@ -1499,7 +1499,7 @@ Cen pôt pas étre dèfêt.',
 'yourvariant' => 'Varianta de la lengoua du contegnu :',
 'prefs-help-variant' => 'Voutra varianta voutron ortografia prèferâye por fâre vêre les pâges de contegnu de ceti vouiqui.',
 'yournick' => 'Signatura novèla :',
-'prefs-help-signature' => 'Los comentèros sur les pâges de discussion dêvont étre signês avouéc « <nowiki>~~~~</nowiki> » que serat convèrti per voutra signatura avouéc la dâta et hora.',
+'prefs-help-signature' => 'Los comentèros sur les pâges de discussion dêvont étre signês avouéc « <nowiki>~~~~</nowiki> » que serat convèrti per voutra signatura et un horodatâjo.',
 'badsig' => 'Signatura bruta pas justa.
 Controlâd les balises HTML.',
 'badsiglength' => 'Voutra signatura est trop longe.
@@ -1546,10 +1546,10 @@ Cel’enformacion serat publica.',
 'userrights-groupsmember-auto' => '{{GENDER:$2|Membro tacito|Membra tacita}} de :',
 'userrights-groups-help' => 'Vos pouede changiér les tropes a lesquintes est cet’utilisat{{GENDER:$1|or|rice}} :
 * Na câsa pouentâye vôt dére que l’utilisat{{GENDER:$1|or|rice}} sè trôve dedens cela tropa.
-* Na câsa pas pouentâye vôt dére que s’y trôve pas.
+* Na câsa pas pouentâye vôt dére qu’y sè trôve pas.
 * Na petiôt’ètêla (*) endique que vos pouede pas enlevar cela tropa setout que vos l’éd apondua ou ben l’una l’ôtra.',
 'userrights-reason' => 'Rêson :',
-'userrights-no-interwiki' => 'Vos avéd pas la pèrmission de changiér des drêts d’utilisator dessus d’ôtros vouiquis.',
+'userrights-no-interwiki' => 'Vos éd pas la pèrmission de changiér des drêts d’utilisator dessus d’ôtros vouiquis.',
 'userrights-nodatabase' => 'La bâsa de donâs « $1 » ègziste pas ou ben el est pas locala.',
 'userrights-nologin' => 'Vos vos dête [[Special:UserLogin|branchiér]] avouéc un compto d’administrator por balyér des drêts d’utilisator.',
 'userrights-notallowed' => 'Voutron compto at pas la pèrmission de balyér ou ben enlevar des drêts d’utilisator.',
@@ -1608,7 +1608,7 @@ Cel’enformacion serat publica.',
 'right-deletelogentry' => 'Suprimar et refâre n’entrâ spècifica du jornal',
 'right-deleterevision' => 'Suprimar et refâre na vèrsion spècifica d’una pâge',
 'right-deletedhistory' => 'Vêre les entrâs suprimâyes de l’historico sen lor tèxto',
-'right-deletedtext' => 'Vêre lo tèxto suprimâ et pués los changements entre les vèrsions suprimâyes',
+'right-deletedtext' => 'Vêre lo tèxto suprimâ et los changements entre les vèrsions suprimâyes',
 'right-browsearchive' => 'Rechèrchiér des pâges suprimâyes',
 'right-undelete' => 'Refâre na pâge',
 'right-suppressrevision' => 'Revêre et refâre les vèrsions cachiêes ux administrators',
@@ -1616,7 +1616,7 @@ Cel’enformacion serat publica.',
 'right-block' => 'Blocar en ècritura d’ôtros utilisators',
 'right-blockemail' => 'Empachiér un utilisator de mandar des mèssâjos',
 'right-hideuser' => 'Blocar un utilisator en cachient son nom u publico',
-'right-ipblock-exempt' => 'Èvitar los blocâjos d’adrèces IP, los blocâjos ôtomaticos et pués los blocâjos de plages d’adrèces IP',
+'right-ipblock-exempt' => 'Èvitar los blocâjos d’adrèces IP, los blocâjos ôtomaticos et los blocâjos de plages d’adrèces IP',
 'right-proxyunbannable' => 'Èvitar los blocâjos ôtomaticos de proxis',
 'right-unblockself' => 'Sè dèblocar lor-mémos',
 'right-protect' => 'Changiér lo nivél de protèccion et pués changiér les pâges protègiêes',
@@ -1741,14 +1741,14 @@ Les pâges de voutra [[Special:Watchlist|lista de siuvu]] sont en '''grâs'''.",
 'upload-tryagain' => 'Mandar la dèscripcion du fichiér changiê',
 'uploadnologin' => 'Pas branchiê(ye)',
 'uploadnologintext' => 'Vos dête étre [[Special:UserLogin|branchiê(ye)]] por tèlèchargiér des fichiérs.',
-'upload_directory_missing' => 'Lo rèpèrtouèro de tèlèchargement ($1) est manquent et pués il at pas possu étre fêt per lo sèrvior Vouèbe.',
+'upload_directory_missing' => 'Lo rèpèrtouèro de tèlèchargement ($1) est manquent et il at pas possu étre fêt per lo sèrvior Vouèbe.',
 'upload_directory_read_only' => 'Lo rèpèrtouèro de tèlèchargement ($1) est pas accèssiblo en ècritura dês lo sèrvior Vouèbe.',
 'uploaderror' => 'Fôta pendent lo tèlèchargement',
 'upload-recreate-warning' => "'''Atencion : un fichiér avouéc cél nom est étâ suprimâ ou ben dèplaciê.'''
 
 Por comoditât, lo jornal de les suprèssions et des dèplacements de cela pâge est balyê ce-desot :",
 'uploadtext' => "Empleyéd lo formulèro ce-desot por tèlèchargiér des fichiérs.
-Por vêre ou ben rechèrchiér des fichiérs tèlèchargiês dês devant, vêde la [[Special:FileList|lista des fichiérs tèlèchargiês]]. Los (re-)tèlèchargements sont asse-ben encartâs dedens lo [[Special:Log/upload|jornal des tèlèchargements]], et pués les suprèssions dedens lo [[Special:Log/delete|jornal de les suprèssions]].
+Por vêre ou ben rechèrchiér des fichiérs tèlèchargiês dês devant, vêde la [[Special:FileList|lista des fichiérs tèlèchargiês]]. Los (re-)tèlèchargements sont asse-ben encartâs dedens lo [[Special:Log/upload|jornal des tèlèchargements]], et les suprèssions dedens lo [[Special:Log/delete|jornal de les suprèssions]].
 
 Por entrebetar un fichiér dedens na pâge, empleyéd un lim de yona de cetes fôrmes :
 * '''<code><nowiki>[[</nowiki>{{ns:file}}<nowiki>:Fichiér.jpg]]</nowiki></code>''' por empleyér la vèrsion en plêna largior du fichiér
@@ -1768,93 +1768,93 @@ Vêde la [[Special:NewFiles|galerie des novéls fichiérs]] por un apèrçu ples
 'filestatus' => 'Statut du drêt d’ôtor :',
 'filesource' => 'Sôrsa :',
 'uploadedfiles' => 'Fichiérs tèlèchargiês',
-'ignorewarning' => 'Ignorar l’avèrtissement et pués encartar lo fichiér quand mémo',
-'ignorewarnings' => 'Ignorar tôs los avèrtissements',
-'minlength1' => 'Los noms de fichiér dêvont comprendre u muens yona lètra.',
-'illegalfilename' => 'Lo nom de fichiér « $1 » contint des caractèros dèfendus dens los titros de pâges.
-Lo volyéd renomar et pués lo tornar tèlèchargiér.',
-'filename-toolong' => 'Lo nom du fichiér pôt pas dèpassar 240 octèts.',
-'badfilename' => 'Lo fichiér at étâ renomâ en « $1 ».',
+'ignorewarning' => 'Ignorar la semonce et pués encartar lo fichiér dens tôs los câs',
+'ignorewarnings' => 'Ignorar totes les semonces',
+'minlength1' => 'Los noms de fichiérs dêvont contegnir por lo muens na lètra.',
+'illegalfilename' => 'Lo nom de fichiér « $1 » contint des caractèros dèfendus dedens los titros de pâges.
+Se vos plét, renomâd-lo et pués tornâd-lo tèlèchargiér.',
+'filename-toolong' => 'Los noms de fichiérs pôvont pas dèpassar 240 octèts.',
+'badfilename' => 'Lo nom du fichiér est étâ changiê en « $1 ».',
 'filetype-mime-mismatch' => 'L’èxtension du fichiér « .$1 » corrèspond pas u tipo MIME dècelâ du fichiér ($2).',
 'filetype-badmime' => 'Los fichiérs du tipo MIME « $1 » pôvont pas étre tèlèchargiês.',
-'filetype-bad-ie-mime' => 'Lo fichiér pôt pas étre tèlèchargiê perce que serêt dècelâ coment « $1 » per Internet Explorer, cen que corrèspond a un tipo de fichiér dèfendu perce que pôt-étre dangerox.',
-'filetype-unwanted-type' => "'''« .$1 »''' est un format de fichiér pas dèsirâ.
-{{PLURAL:$3|Lo tipo de fichiérs recomandâ est|Los tipos de fichiérs recomandâs sont}} $2.",
-'filetype-banned-type' => "'''« .$1 »''' {{PLURAL:$4|est pas un tipo de fichiérs ôtorisâ|sont pas des tipos de fichiérs ôtorisâs}}.
-{{PLURAL:$3|Lo tipo de fichiérs accèptâ est|Los tipos de fichiérs accèptâs sont}} $2.",
+'filetype-bad-ie-mime' => 'Lo fichiér pôt pas étre tèlèchargiê perce que serêt dècelâ coment « $1 » per Internet Explorer, cen que corrèspond a un tipo de fichiér dèfendu et pués pôt-étre dangerox.',
+'filetype-unwanted-type' => "'''« .$1 »''' est un tipo de fichiér pas volu.
+{{PLURAL:$3|Lo tipo de fichiér prèferâ est|Los tipos de fichiérs prèferâs sont}} $2.",
+'filetype-banned-type' => "'''« .$1 »''' {{PLURAL:$4|est pas un tipo de fichiér ôtorisâ|sont pas des tipos de fichiérs ôtorisâs}}.
+{{PLURAL:$3|Lo tipo de fichiér ôtorisâ est|Los tipos de fichiérs ôtorisâs sont}} $2.",
 'filetype-missing' => 'Lo fichiér at gins d’èxtension (coment « .jpg » per ègzemplo).',
-'empty-file' => 'Lo fichiér que vos éd somês ére vouedo.',
-'file-too-large' => 'Lo fichiér que vos éd somês ére trop grant.',
+'empty-file' => 'Lo fichiér que vos éd mandâ ére vouedo.',
+'file-too-large' => 'Lo fichiér que vos éd mandâ ére trop grôs.',
 'filename-tooshort' => 'Lo nom du fichiér est trop côrt.',
 'filetype-banned' => 'Cél tipo de fichiér est dèfendu.',
 'verification-error' => 'Cél fichiér pâsse pas lo contrôlo des fichiérs.',
-'hookaborted' => 'Lo changement que vos éd tâchiê de fâre at étâ arrètâ per un grèfon d’una èxtension.',
+'hookaborted' => 'Lo changement que vos éd èprovâ de fâre est étâ anulâ per n’èxtension.',
 'illegal-filename' => 'Lo nom du fichiér est pas ôtorisâ.',
 'overwrite' => 'Ècllafar un fichiér ègzistent est pas ôtorisâ.',
-'unknown-error' => 'Una èrror encognua est arrevâ.',
-'tmp-create-error' => 'Empossiblo de fâre lo fichiér temporèro.',
-'tmp-write-error' => 'Èrror d’ècritura du fichiér temporèro.',
-'large-file' => 'Los fichiérs tèlèchargiês devriant pas étre ples grant que $1 ;
+'unknown-error' => 'Na fôta encognua est arrevâ.',
+'tmp-create-error' => 'Y at pas moyen de fâre lo fichiér temporèro.',
+'tmp-write-error' => 'Fôta d’ècritura du fichiér temporèro.',
+'large-file' => 'O est recomandâ que los fichiérs seyont pas ples grôs que $1 ;
 cél fichiér fât $2.',
-'largefileserver' => 'La talye de cél fichiér est d’amont lo nivél lo ples hôt ôtorisâ.',
-'emptyfile' => 'Lo fichiér que vos voléd tèlèchargiér semble vouedo.
-Cen pôt étre diu a una èrror dedens lo nom du fichiér.
-Volyéd controlar que vos voléd franc tèlèchargiér cél fichiér.',
+'largefileserver' => 'Cél fichiér est ples grôs que lo sèrvior est configurâ por l’ôtorisar.',
+'emptyfile' => 'Lo fichiér que vos éd tèlèchargiê semble étre vouedo.
+Cen pôt étre diu a na fôta dedens lo nom du fichiér.
+Se vos plét, controlâd que vos voléd franc tèlèchargiér cél fichiér.',
 'windows-nonascii-filename' => 'Ceti vouiqui recognêt pas los noms de fichiérs avouéc des caractèros spèciâls.',
-'fileexists' => 'Un fichiér avouéc cél nom ègziste ja.
-Volyéd controlar <strong>[[:$1]]</strong>.
-Éte-vos de sûr de lo volêr changiér ? [[$1|thumb]]',
-'filepageexists' => 'La pâge de dèscripcion por cél fichiér at ja étâ fêta ique <strong>[[:$1]]</strong>, mas nion fichiér de cél nom ègziste ora.
+'fileexists' => 'Un fichiér avouéc cél nom ègziste ja, se vos plét controlâd <strong>[[:$1]]</strong> se vos éte pas de sûr de lo volêr changiér.
+[[$1|thumb]]',
+'filepageexists' => 'La pâge de dèscripcion por cél fichiér est ja étâye fêta ique <strong>[[:$1]]</strong>, mas nion fichiér avouéc cél nom ègziste ora.
 Lo rèsumâ que vos voléd buchiér aparêtrat pas sur la pâge de dèscripcion.
-Por cen fâre vos devréd changiér la pâge a la man.
+Por o fâre, vos la devréd changiér a la man.
 [[$1|thumb]]',
 'fileexists-extension' => 'Un fichiér avouéc un nom d’ense ègziste ja : [[$2|thumb]]
 * Nom du fichiér a tèlèchargiér : <strong>[[:$1]]</strong>
 * Nom du fichiér ègzistent : <strong>[[:$2]]</strong>
-Volyéd chouèsir un ôtro nom.',
-'fileexists-thumbnail-yes' => "Lo fichiér semble étre una émâge en talye rèduita ''(figura)''.
+Se vos plét, chouèsésséd-nen un ôtro.',
+'fileexists-thumbnail-yes' => "Lo fichiér semble étre n’émâge en talye rèduita ''(figura)''.
 [[$1|thumb]]
-Volyéd controlar lo fichiér <strong>[[:$1]]</strong>.
-Se lo fichiér controlâ est la méma émâge avouéc la talye originèla, y at pas fôta de tèlèchargiér una vèrsion rèduita.",
+Se vos plét, controlâd lo fichiér <strong>[[:$1]]</strong>.
+Se lo fichiér controlâ est la mém’émâge avouéc la talye originâla, y at pas fôta de tèlèchargiér na figura.",
 'file-thumbnail-no' => "Lo nom du fichiér comence per <strong>$1</strong>.
-O est possiblo que seye una vèrsion rèduita ''(figura)''.
-Se vos avéd lo fichiér en rèsolucion ples hôta, tèlèchargiéd-lo, ôtrament volyéd changiér son nom.",
+Semble étre n’émâge en talye rèduita ''(figura)''.
+Se vos éd cel’émâge en plêna rèsolucion, tèlèchargiéd-la, ôtrament changiéd lo sin nom, se vos plét.",
 'fileexists-forbidden' => 'Un fichiér avouéc cél nom ègziste ja et pôt pas étre ècllafâ.
-Se vos voléd adés tèlèchargiér voutron fichiér, volyéd tornar arriér et pués utilisar un novél nom.
+Se vos voléd adés tèlèchargiér voutron fichiér, se vos plét tornâd arriér et pués empleyéd un novél nom.
 [[File:$1|thumb|center|$1]]',
-'fileexists-shared-forbidden' => 'Un fichiér avouéc cél nom ègziste ja dens lo dèpôt de fichiérs partagiê.
-Se vos voléd adés tèlèchargiér voutron fichiér, volyéd tornar arriér et pués utilisar un novél nom.
+'fileexists-shared-forbidden' => 'Un fichiér avouéc cél nom ègziste ja dedens lo dèpôt de fichiérs partagiê.
+Se vos voléd adés tèlèchargiér voutron fichiér, se vos plét tornâd arriér et pués empleyéd un novél nom.
 [[File:$1|thumb|center|$1]]',
 'file-exists-duplicate' => 'Cél fichiér est un doblo {{PLURAL:$1|de ceti fichiér|de cetos fichiérs}} :',
-'file-deleted-duplicate' => 'Un fichiér pariér a ceti ([[:$1]]) at ja étâ suprimâ.
+'file-deleted-duplicate' => 'Un fichiér pariér a ceti ([[:$1]]) est ja étâ suprimâ.
 Vos devriâd controlar lo jornal de les suprèssions de cél fichiér devant que lo tornar tèlèchargiér.',
-'uploadwarning' => 'Atencion !',
-'uploadwarning-text' => 'Changiéd la dèscripcion du fichiér et pués tornâd èprovar.',
-'savefile' => 'Sôvar lo fichiér',
+'uploadwarning' => 'Semonce pendent lo tèlèchargement',
+'uploadwarning-text' => 'Se vos plét, changiéd la dèscripcion du fichiér ce-desot et pués tornâd èprovar.',
+'savefile' => 'Encartar lo fichiér',
 'uploadedimage' => 'at tèlèchargiê « [[$1]] »',
-'overwroteimage' => 'at tèlèchargiê una novèla vèrsion de « [[$1]] »',
-'uploaddisabled' => 'Tèlèchargements dèsactivâs',
-'copyuploaddisabled' => 'Tèlèchargement de fichiér per URL dèsactivâ.',
-'uploadfromurl-queued' => 'Voutron tèlèchargement at étâ betâ dens la fela d’atenta.',
-'uploaddisabledtext' => 'Lo tèlèchargement de fichiérs est dèsactivâ.',
-'php-uploaddisabledtext' => 'Lo tèlèchargement de fichiérs at étâ dèsactivâ dens PHP.
-Volyéd controlar lo chouèx de configuracion « file_uploads ».',
-'uploadscripted' => 'Cél fichiér contint de code HTML ou ben un scripte que porrêt étre entèrprètâ de façon fôssa per un navigator vouèbe.',
-'uploadvirus' => 'Cél fichiér contint un virus ! Por més de dètalys, vêde : $1',
-'uploadjava' => 'O est un fichiér ZIP que contint un fichiér Java .class.
-Lo tèlèchargement de fichiérs Java est pas ôtorisâ, perce que pôvont entrênar des rèstriccions de sècuritât.',
+'overwroteimage' => 'at tèlèchargiê na novèla vèrsion de « [[$1]] »',
+'uploaddisabled' => 'Tèlèchargements dèsactivâs.',
+'copyuploaddisabled' => 'Tèlèchargement per URL dèsactivâ.',
+'uploadfromurl-queued' => 'Voutron tèlèchargement est étâ betâ dedens la renche d’atenta.',
+'uploaddisabledtext' => 'Los tèlèchargements de fichiérs sont dèsactivâs.',
+'php-uploaddisabledtext' => 'Los tèlèchargements de fichiérs sont dèsactivâs dedens PHP.
+Se vos plét, controlâd la configuracion de « file_uploads ».',
+'uploadscripted' => 'Cél fichiér contint de code HTML ou ben un scripte que porrêt étre entèrprètâ a tôrt per un navigator Vouèbe.',
+'uploadvirus' => 'Cél fichiér contint un virus !
+Dètalys : $1',
+'uploadjava' => 'O est un fichiér ZIP que contint un fichiér Java « .class ».
+Lo tèlèchargement de fichiérs Java est pas ôtorisâ, pôvont èvitar des rèstriccions de sècuritât.',
 'upload-source' => 'Fichiér sôrsa',
 'sourcefilename' => 'Nom du fichiér sôrsa :',
 'sourceurl' => 'URL sôrsa :',
 'destfilename' => 'Nom du fichiér de dèstinacion :',
-'upload-maxfilesize' => 'Talye la ples granta du fichiér : $1',
+'upload-maxfilesize' => 'Talye maximon du fichiér : $1',
 'upload-description' => 'Dèscripcion du fichiér',
 'upload-options' => 'Chouèx de tèlèchargement',
 'watchthisupload' => 'Siuvre ceti fichiér',
-'filewasdeleted' => 'Un fichiér avouéc cél nom at ja étâ tèlèchargiê, et pués suprimâ.
+'filewasdeleted' => 'Un fichiér avouéc cél nom est ja étâ tèlèchargiê et pués suprimâ.
 Vos devriâd controlar lo $1 devant que lo tornar tèlèchargiér.',
-'filename-bad-prefix' => "Lo nom du fichiér que vos tèlèchargiéd comence per '''« $1 »''' qu’est tipicament un nom balyê ôtomaticament per los aparèlys-fotô numericos.
-Volyéd chouèsir un nom de fichiér dèscriptif.",
+'filename-bad-prefix' => "Lo nom du fichiér que vos tèlèchargiéd comence per '''« $1 »''' qu’est en g·ènèral un nom pas dèscriptif balyê ôtomaticament per los aparèlys-fotô numericos.
+Se vos plét, chouèsésséd un nom ples dèscriptif por voutron fichiér.",
 'filename-prefix-blacklist' => ' #<!-- lèssiéd ceta legne justo d’ense --> <pre>
 # La sintaxa est ceta :
 #  * Tot tèxto que siut un « # » tant qu’a la fin de la legne est un comentèro.
@@ -1871,143 +1871,143 @@ PICT # de totes sôrtes
  #</pre> <!-- lèssiéd ceta legne justo d’ense -->',
 'upload-success-subj' => 'Tèlèchargement fêt avouéc reusséta',
 'upload-success-msg' => 'Voutron tèlèchargement dês [$2] at reussi. Il est disponiblo ique : [[:{{ns:file}}:$1]]',
-'upload-failure-subj' => 'Problèmo de tèlèchargement',
+'upload-failure-subj' => 'Problèmo pendent lo tèlèchargement',
 'upload-failure-msg' => 'Y at avu un problèmo avouéc voutron tèlèchargement dês [$2] :
 
 $1',
-'upload-warning-subj' => 'Avèrtissement pendent lo tèlèchargement',
-'upload-warning-msg' => 'Un problèmo est arrevâ pendent voutron tèlèchargement dês [$2]. Vos pouede tornar u [[Special:Upload/stash/$1|formulèro de tèlèchargement]] por trovar la solucion.',
+'upload-warning-subj' => 'Semonce pendent lo tèlèchargement',
+'upload-warning-msg' => 'Y at avu un problèmo avouéc voutron tèlèchargement dês [$2]. Vos pouede tornar u [[Special:Upload/stash/$1|formulèro de tèlèchargement]] por trovar la sina solucion.',
 
 'upload-proto-error' => 'Protocolo fôx',
-'upload-proto-error-text' => 'Lo tèlèchargement a distance at fôta des URLs que començont per <code>http://</code> ou ben <code>ftp://</code>.',
-'upload-file-error' => 'Èrror de dedens',
-'upload-file-error-text' => 'Una èrror de dedens est arrevâ en volent fâre un fichiér temporèro sur lo sèrvor.
-Vos volyéd veriér vers un [[Special:ListUsers/sysop|administrator]].',
-'upload-misc-error' => 'Èrror encognua pendent lo tèlèchargement',
-'upload-misc-error-text' => 'Una èrror encognua est arrevâ pendent lo tèlèchargement.
-Volyéd controlar que l’URL est valida et accèssibla, et pués tornâd èprovar.
+'upload-proto-error-text' => 'Lo tèlèchargement a distance at fôta dURLs que començont per <code>http://</code> ou ben <code>ftp://</code>.',
+'upload-file-error' => 'Fôta de dedens',
+'upload-file-error-text' => 'Na fôta de dedens est arrevâye en volent fâre un fichiér temporèro sur lo sèrvior.
+Se vos plét, veriéd-vos vers un [[Special:ListUsers/sysop|administrator]].',
+'upload-misc-error' => 'Fôta encognua pendent lo tèlèchargement',
+'upload-misc-error-text' => 'Na fôta encognua est arrevâye pendent lo tèlèchargement.
+Se vos plét, controlâd que l’URL est justa et accèssibla, et pués tornâd èprovar.
 Se lo problèmo continue, veriéd-vos vers un [[Special:ListUsers/sysop|administrator]].',
 'upload-too-many-redirects' => 'L’URL contint trop de redirèccions',
 'upload-unknown-size' => 'Talye encognua',
-'upload-http-error' => 'Una èrror HTTP est arrevâ : $1',
-'upload-copy-upload-invalid-domain' => 'La copia des tèlèchargements est pas disponibla dês ceti domêno.',
+'upload-http-error' => 'Na fôta HTTP est arrevâye : $1',
+'upload-copy-upload-invalid-domain' => 'Los tèlèchargements de copies sont pas disponiblos dês ceti domêno.',
 
 # File backend
-'backend-fail-stream' => 'Empossiblo de liére lo fichiér $1.',
-'backend-fail-backup' => 'Empossiblo de sôvar lo fichiér $1.',
+'backend-fail-stream' => 'Y at pas moyen de tramandar lo fichiér « $1 ».',
+'backend-fail-backup' => 'Y at pas moyen d’encartar lo fichiér « $1 ».',
 'backend-fail-notexists' => 'Lo fichiér $1 ègziste pas.',
-'backend-fail-hashes' => 'Empossiblo d’avêr los chaplâjos du fichiér por comparèson.',
-'backend-fail-notsame' => 'Un fichiér difèrent ègziste ja por $1 .',
-'backend-fail-invalidpath' => '$1 est pas un chemin de stocâjo valido.',
-'backend-fail-delete' => 'Empossiblo de suprimar lo fichiér $1.',
-'backend-fail-describe' => 'Empossiblo de changiér les mètadonâs du fichiér « $1 ».',
-'backend-fail-alreadyexists' => 'Lo fichiér $1 ègziste ja.',
-'backend-fail-store' => 'Empossiblo de stocar lo fichiér $1 en $2.',
-'backend-fail-copy' => 'Empossiblo de copiyér lo fichiér $1 vers $2.',
-'backend-fail-move' => 'Empossiblo de dèplaciér lo fichiér $1 vers $2.',
-'backend-fail-opentemp' => 'Empossiblo d’uvrir lo fichiér temporèro.',
-'backend-fail-writetemp' => 'Empossiblo d’ècrire dedens lo fichiér temporèro.',
-'backend-fail-closetemp' => 'Empossiblo de cllôre lo fichiér temporèro.',
-'backend-fail-read' => 'Empossiblo de liére lo fichiér $1.',
-'backend-fail-create' => 'Empossiblo d’ècrire lo fichiér $1.',
-'backend-fail-maxsize' => 'Empossiblo d’ècrire lo fichiér « $1 » perce qu’il est ples grant que {{PLURAL:$2|yon octèt|$2 octèts}}.',
-'backend-fail-readonly' => "Ora lo sistèmo de stocâjo « $1 » est en lèctura solèta. La rêson balyêye est : « ''$2'' »",
+'backend-fail-hashes' => 'Y at pas moyen d’avêr los chaplâjos du fichiér por comparèson.',
+'backend-fail-notsame' => 'Un fichiér pas pariér ègziste ja a « $1 ».',
+'backend-fail-invalidpath' => '« $1 » est pas un chemin de stocâjo justo.',
+'backend-fail-delete' => 'Y at pas moyen de suprimar lo fichiér « $1 ».',
+'backend-fail-describe' => 'Y at pas moyen de changiér les mètadonâs du fichiér « $1 ».',
+'backend-fail-alreadyexists' => 'Lo fichiér « $1 » ègziste ja.',
+'backend-fail-store' => 'Y at pas moyen de stocar lo fichiér « $1 » dedens « $2 ».',
+'backend-fail-copy' => 'Y at pas moyen de copiyér lo fichiér « $1 » vers « $2 ».',
+'backend-fail-move' => 'Y at pas moyen de dèplaciér lo fichiér « $1 » vers « $2 ».',
+'backend-fail-opentemp' => 'Y at pas moyen d’uvrir lo fichiér temporèro.',
+'backend-fail-writetemp' => 'Y at pas moyen d’ècrire dedens lo fichiér temporèro.',
+'backend-fail-closetemp' => 'Y at pas moyen de cllôre lo fichiér temporèro.',
+'backend-fail-read' => 'Y at pas moyen de liére lo fichiér « $1 ».',
+'backend-fail-create' => 'Y at pas moyen d’ècrire lo fichiér « $1 ».',
+'backend-fail-maxsize' => 'Y at pas moyen d’ècrire lo fichiér « $1 » perce qu’il est ples grôs {{PLURAL:$2|qu’un octèt|que $2 octèts}}.',
+'backend-fail-readonly' => "Ora lo sistèmo de stocâjo « $1 » est justo en lèctura. La rêson balyêe est : « ''$2'' »",
 'backend-fail-synced' => 'Lo fichiér « $1 » est dens un ètat dèsordonâ dedens los sistèmos de stocâjo de dedens',
-'backend-fail-connect' => 'Empossiblo de sè branchiér u sistèmo de stocâjo « $1 ».',
+'backend-fail-connect' => 'Y at pas moyen de sè branchiér u sistèmo de stocâjo « $1 ».',
 'backend-fail-internal' => 'Na fôta encognua est arrevâye dedens lo sistèmo de stocâjo « $1 ».',
-'backend-fail-contenttype' => 'Empossiblo de dètèrmenar lo tipo de contegnu du fichiér a stocar en « $1 ».',
+'backend-fail-contenttype' => 'Y at pas moyen de dètèrmenar lo tipo de contegnu du fichiér a stocar dedens « $1 ».',
 'backend-fail-batchsize' => 'Lo sistèmo de stocâjo at balyê na pârt de $1 {{PLURAL:$1|opèracion|opèracions}} de fichiér ; la limita est $2 {{PLURAL:$2|opèracion|opèracions}}.',
-'backend-fail-usable' => 'Empossiblo de liére ou ben d’ècrire lo fichiér « $1 » a côsa de pèrmissions ensufisentes ou ben de rèpèrtouèros / conteniors manquents.',
+'backend-fail-usable' => 'Y at pas moyen de liére d’ècrire lo fichiér « $1 » a côsa de pèrmissions ensufisentes ou ben de rèpèrtouèros / conteniors manquents.',
 
 # File journal errors
-'filejournal-fail-dbconnect' => 'Empossiblo de sè branchiér a la bâsa de donâs du jornal por lo sistèmo de stocâjo « $1 ».',
-'filejournal-fail-dbquery' => 'Empossiblo de betar a jorn la bâsa de donâs du jornal por lo sistèmo de stocâjo « $1 ».',
+'filejournal-fail-dbconnect' => 'Y at pas moyen de sè branchiér a la bâsa de donâs du jornal por lo sistèmo de stocâjo « $1 ».',
+'filejournal-fail-dbquery' => 'Y at pas moyen de betar a jorn la bâsa de donâs du jornal por lo sistèmo de stocâjo « $1 ».',
 
 # Lock manager
-'lockmanager-notlocked' => 'Empossiblo de dèvèrrolyér « $1 » ; el est pas vèrrolyê.',
-'lockmanager-fail-closelock' => 'Empossiblo de cllôre lo fichiér de vèrroly por « $1 ».',
-'lockmanager-fail-deletelock' => 'Empossiblo de suprimar lo fichiér de vèrroly por « $1 ».',
-'lockmanager-fail-acquirelock' => 'Empossiblo d’avêr lo vèrroly por « $1 ».',
-'lockmanager-fail-openlock' => 'Empossiblo d’uvrir lo fichiér de vèrroly por « $1 ».',
-'lockmanager-fail-releaselock' => 'Empossiblo de relâchiér lo vèrroly por « $1 ».',
-'lockmanager-fail-db-bucket' => 'Empossiblo de sè veriér vers prod de bâses de balyês de vèrrolyâjo dedens lo godèt $1.',
-'lockmanager-fail-db-release' => 'Empossiblo de relâchiér los vèrrolys sur la bâsa de balyês $1.',
-'lockmanager-fail-svr-acquire' => 'Empossiblo d’avêr des vèrrolys sur lo sèrvior $1.',
-'lockmanager-fail-svr-release' => 'Empossiblo de relâchiér los vèrrolys sur lo sèrvior $1.',
+'lockmanager-notlocked' => 'Y at pas moyen de dèvèrrolyér « $1 » ; il est pas vèrrolyê.',
+'lockmanager-fail-closelock' => 'Y at pas moyen de cllôre lo fichiér de vèrroly por « $1 ».',
+'lockmanager-fail-deletelock' => 'Y at pas moyen de suprimar lo fichiér de vèrroly por « $1 ».',
+'lockmanager-fail-acquirelock' => 'Y at pas moyen d’avêr lo vèrroly por « $1 ».',
+'lockmanager-fail-openlock' => 'Y at pas moyen d’uvrir lo fichiér de vèrroly por « $1 ».',
+'lockmanager-fail-releaselock' => 'Y at pas moyen de relâchiér lo vèrroly por « $1 ».',
+'lockmanager-fail-db-bucket' => 'Y at pas moyen de sè veriér vers prod de bâses de donâs de vèrroly dedens la sèlye $1.',
+'lockmanager-fail-db-release' => 'Y at pas moyen de relâchiér los vèrrolys sur la bâsa de donâs $1.',
+'lockmanager-fail-svr-acquire' => 'Y at pas moyen d’avêr des vèrrolys sur lo sèrvior $1.',
+'lockmanager-fail-svr-release' => 'Y at pas moyen de relâchiér los vèrrolys sur lo sèrvior $1.',
 
 # ZipDirectoryReader
-'zip-file-open-error' => 'Una èrror est arrevâ pendent l’uvèrtura du fichiér ZIP por contrôlo.',
-'zip-wrong-format' => 'Lo fichiér spècefiâ est pas un fichiér ZIP.',
-'zip-bad' => 'Lo fichiér est un fichiér ZIP corrompu ou ben iliésiblo.
-Pôt pas étre controlâ tot drêt por la sècuritât.',
-'zip-unsupported' => 'Lo fichiér est un fichiér ZIP qu’utilise ZIP pas recognues per MediaWiki.
-Pôt pas étre controlâ tot drêt por la sècuritât.',
+'zip-file-open-error' => 'Na fôta est arrevâye pendent l’uvèrtura du fichiér por los contrôlos ZIP.',
+'zip-wrong-format' => 'Lo fichiér spècifiâ est pas un fichiér ZIP.',
+'zip-bad' => 'Lo fichiér est un fichiér ZIP corrompu ou ben ôtrament iliésiblo.
+Pôt pas étre controlâ coment fôt por la sècuritât.',
+'zip-unsupported' => 'Lo fichiér est un fichiér ZIP qu’emplèye des fonccionalitâts ZIP pas recognues per MediaWiki.
+Pôt pas étre controlâ coment fôt por la sècuritât.',
 
 # Special:UploadStash
-'uploadstash' => 'Cache d’importacion',
-'uploadstash-summary' => 'Ceta pâge balye accès ux fichiérs que sont importâs (ou ben en cors d’importacion), mas sont p’oncor publeyês dens lo vouiqui. Celos fichiérs sont p’oncor visiblos, solament por l’usanciér que los at importâs.',
-'uploadstash-clear' => 'Èfaciér los fichiérs en cache d’importacion',
-'uploadstash-nofiles' => 'Vos avéd gins de fichiér en cache d’importacion.',
-'uploadstash-badtoken' => 'L’ègzécucion de cela accion at pas reussia, pôt-étre perce que voutres enformacions de branchement ont èxpirâs. Tornâd èprovar.',
+'uploadstash' => 'Cacho de tèlèchargement',
+'uploadstash-summary' => 'Ceta pâge balye accès ux fichiérs que sont tèlèchargiês ou ben en côrs de tèlèchargement, mas sont p’oncor publeyês dedens lo vouiqui. Celos fichiérs sont p’oncor visiblos, solament por l’utilisator que los at tèlèchargiês.',
+'uploadstash-clear' => 'Èfaciér los fichiérs en cacho',
+'uploadstash-nofiles' => 'Vos éd gins de fichiér en cacho.',
+'uploadstash-badtoken' => 'L’ègzécucion de cel’accion at pas reussi, pôt-étre perce que voutros identifients de changement ont èxpirâ. Tornâd èprovar.',
 'uploadstash-errclear' => 'L’èfacement des fichiérs at pas reussi.',
 'uploadstash-refresh' => 'Rafrèchir la lista des fichiérs',
-'invalid-chunk-offset' => 'Comencement de bocon envalido',
+'invalid-chunk-offset' => 'Dèplacement de bocon pas justo',
 
 # img_auth script messages
 'img-auth-accessdenied' => 'Accès refusâ',
-'img-auth-nopathinfo' => 'PATH_INFO manquent.
-Voutron sèrvor est pas dèfeni por passar cela enformacion.
-Fonccione pôt-étre en CGI et pués recognêt pas img_auth.
+'img-auth-nopathinfo' => 'PATH_INFO manquenta.
+Voutron sèrvior est pas configurâ por passar cel’enformacion.
+Pôt étre bâsâye sur CGI et vêr pas recognetre « img_auth ».
 Vêde https://www.mediawiki.org/wiki/Manual:Image_Authorization.',
 'img-auth-notindir' => 'Lo chemin demandâ est pas lo rèpèrtouèro de tèlèchargement configurâ.',
-'img-auth-badtitle' => 'Empossiblo de construire un titro valido dês « $1 ».',
-'img-auth-nologinnWL' => 'Vos éte pas branchiê et pués « $1 » est pas dens la lista blanche.',
+'img-auth-badtitle' => 'Y at pas moyen de construire un titro justo dês « $1 ».',
+'img-auth-nologinnWL' => 'Vos éte pas branchiê et pués « $1 » est pas dedens la lista blanche.',
 'img-auth-nofile' => 'Lo fichiér « $1 » ègziste pas.',
-'img-auth-isdir' => 'Vos tâchiéd d’arrevar u rèpèrtouèro « $1 ».
+'img-auth-isdir' => 'Vos èprovâd d’arrevar u rèpèrtouèro « $1 ».
 Solament l’accès ux fichiérs est pèrmês.',
 'img-auth-streaming' => 'Lèctura en continu de « $1 ».',
-'img-auth-public' => 'La fonccion de img_auth.php est de fâre vêre des fichiérs d’un vouiqui privâ.
+'img-auth-public' => 'La fonccion de img_auth.php est de sortir des fichiérs d’un vouiqui privâ.
 Ceti vouiqui est configurâ coment un vouiqui publico.
-Por una sècuritât parfèta, img_auth.php est dèsactivâ.',
-'img-auth-noread' => 'L’usanciér at pas lo drêt en lèctura dessus « $1 ».',
-'img-auth-bad-query-string' => 'L’URL at una chêna de requéta envalida.',
+Por na sècuritât pèrfèta, img_auth.php est dèsactivâ.',
+'img-auth-noread' => 'L’utilisator at pas accès a la lèctura de « $1 ».',
+'img-auth-bad-query-string' => 'L’URL at na chêna de demanda pas justa.',
 
 # HTTP errors
-'http-invalid-url' => 'URL fôssa : $1',
+'http-invalid-url' => 'URL pas justa : $1',
 'http-invalid-scheme' => 'Les URLs avouéc lo plan « $1 » sont pas recognues.',
-'http-request-error' => 'Èrror encognua pendent l’èxpèdicion de la requéta.',
-'http-read-error' => 'Èrror de lèctura HTTP.',
-'http-timed-out' => 'La requéta HTTP at èxpirâ.',
-'http-curl-error' => 'Èrror pendent la rècupèracion de l’URL : $1',
-'http-host-unreachable' => 'URL pas juentâbla.',
-'http-bad-status' => 'Y at avu un problèmo pendent la requéta HTTP : $1 $2',
+'http-request-error' => 'La demanda HTTP at pas reussi a côsa d’una fôta encognua.',
+'http-read-error' => 'Fôta de lèctura HTTP.',
+'http-timed-out' => 'La demanda HTTP at èxpirâ.',
+'http-curl-error' => 'Fôta pendent la rècupèracion de l’URL : $1',
+'http-host-unreachable' => 'Y at pas moyen d’avengiér l’URL.',
+'http-bad-status' => 'Y at avu un problèmo pendent la demanda HTTP : $1 $2',
 
 # Some likely curl errors. More could be added from <http://curl.haxx.se/libcurl/c/libcurl-errors.html>
-'upload-curl-error6' => 'URL pas juentâbla',
-'upload-curl-error6-text' => 'L’URL balyê pôt pas étre juenta.
-Volyéd controlar que l’URL est justa et que lo seto est en legne.',
-'upload-curl-error28' => 'Dèpassement du dèlê pendent lo tèlèchargement',
-'upload-curl-error28-text' => 'Lo seto at betâ trop grant-temps a rèpondre.
-Volyéd controlar que lo seto est en legne, atendre un pou et pués tornar èprovar.
-Vos pouede asse-ben tornar èprovar a una hora de muendra afluence.',
+'upload-curl-error6' => 'Y at pas moyen d’avengiér l’URL',
+'upload-curl-error6-text' => 'L’URL balyêe pôt pas étre avengiêe.
+Se vos plét, tornâd controlar que l’URL est justa et pués que lo seto est en legne.',
+'upload-curl-error28' => 'Dèlê dèpassâ pendent lo tèlèchargement',
+'upload-curl-error28-text' => 'Lo seto at tardâ bien a rèpondre.
+Se vos plét, controlâd que lo seto est en legne, atende un pou et pués tornâd èprovar.
+Vos pouede asse-ben èprovar a n’hora de muendra afluence.',
 
 'license' => 'Licence :',
 'license-header' => 'Licence',
-'nolicense' => 'Gins de licence chouèsia',
-'license-nopreview' => '(Prèvisualisacion pas disponibla)',
-'upload_source_url' => '  (una URL valida et accèssibla publicament)',
-'upload_source_file' => '  (un fichiér sur voutron ordenator)',
+'nolicense' => 'Pas yona chouèsia',
+'license-nopreview' => '(Apèrçu pas disponiblo)',
+'upload_source_url' => ' (n’URL justa et accèssibla publicament)',
+'upload_source_file' => ' (un fichiér sur voutron ordenator)',
 
 # Special:ListFiles
 'listfiles-summary' => 'Ceta pâge spèciâla montre tôs los fichiérs tèlèchargiês.
-Quand el est filtrâ per usanciér, solament los fichiérs que la vèrsion la ples novèla at étâ importâ per cél usanciér sont montrâs.',
-'listfiles_search_for' => 'Rechèrchiér un nom de mèdia :',
+Quand el est filtrâye per utilisator, solament los fichiérs que la vèrsion la ples novèla est étâye tèlèchargiêe per cél utilisator sont montrâs.',
+'listfiles_search_for' => 'Rechèrchiér un nom de fichiér mèdia :',
 'imgfile' => 'fichiér',
-'listfiles' => 'Lista des fichiérs',
+'listfiles' => 'Lista de fichiérs',
 'listfiles_thumb' => 'Figura',
 'listfiles_date' => 'Dâta',
 'listfiles_name' => 'Nom',
-'listfiles_user' => 'Usanciér',
+'listfiles_user' => 'Utilisator',
 'listfiles_size' => 'Talye',
 'listfiles_description' => 'Dèscripcion',
 'listfiles_count' => 'Vèrsions',
@@ -2015,77 +2015,82 @@ Quand el est filtrâ per usanciér, solament los fichiérs que la vèrsion la pl
 # File description page
 'file-anchor-link' => 'Fichiér',
 'filehist' => 'Historico du fichiér',
-'filehist-help' => 'Clicar sur na dâta et hora por vêre lo fichiér coment il ére a cél moment.',
+'filehist-help' => 'Clicar sur na dâta / hora por vêre lo fichiér coment il ére a cél moment.',
 'filehist-deleteall' => 'suprimar tot',
 'filehist-deleteone' => 'suprimar',
-'filehist-revert' => 'rètablir',
-'filehist-current' => 'ora',
-'filehist-datetime' => 'Dâta et hora',
+'filehist-revert' => 'rèvocar',
+'filehist-current' => 'd’ora',
+'filehist-datetime' => 'Dâta / hora',
 'filehist-thumb' => 'Figura',
-'filehist-thumbtext' => 'Figura por la vèrsion du $1',
-'filehist-nothumb' => 'Gins de figura',
-'filehist-user' => 'Usanciér',
+'filehist-thumbtext' => 'Figura por la vèrsion du $2 a $3',
+'filehist-nothumb' => 'Niona figura',
+'filehist-user' => 'Utilisator',
 'filehist-dimensions' => 'Dimensions',
 'filehist-filesize' => 'Talye du fichiér',
 'filehist-comment' => 'Comentèro',
 'filehist-missing' => 'Fichiér manquent',
 'imagelinks' => 'Usâjo du fichiér',
-'linkstoimage' => '{{PLURAL:$1|Ceta pâge utilise|Cetes $1 pâges utilisont}} ceti fichiér :',
-'linkstoimage-more' => 'Més de {{PLURAL:$1|yona pâge utilise|$1 pâges utilisont}} ceti fichiér.
-Ceta lista montre ren que {{PLURAL:$1|la premiére pâge qu’utilise|les $1 premiéres pâges qu’utilisont}} ceti fichiér.
-Una [[Special:WhatLinksHere/$2|lista complèta]] est disponibla.',
-'nolinkstoimage' => 'Niona pâge utilise ceti fichiér.',
+'linkstoimage' => '{{PLURAL:$1|Cela pâge-que emplèye|Celes $1 pâges-que emplèyont}} ceti fichiér :',
+'linkstoimage-more' => 'Més {{PLURAL:$1|d’una pâge emplèye|de $1 pâges emplèyont}} ceti fichiér.
+Ceta lista montre ren que {{PLURAL:$1|la premiére pâge qu’emplèye|les $1 premiéres pâges qu’emplèyont}} ceti fichiér.
+Na [[Special:WhatLinksHere/$2|lista complèta]] est disponibla.',
+'nolinkstoimage' => 'Niona pâge emplèye ceti fichiér.',
 'morelinkstoimage' => 'Vêde [[Special:WhatLinksHere/$1|més de lims]] de vers ceti fichiér.',
 'linkstoimage-redirect' => '$1 (redirèccion de fichiér) $2',
-'duplicatesoffile' => '{{PLURAL:$1|Ceti fichiér est un doblo|Cetos fichiérs sont des doblos}} de ceti ([[Special:FileDuplicateSearch/$2|més de dètalys]]) :',
-'sharedupload' => 'Ceti fichiér vint de $1 et pôt étre utilisâ per d’ôtros projèts.',
-'sharedupload-desc-there' => 'Ceti fichiér vint de $1 et pôt étre utilisâ per d’ôtros projèts.
-Vêde sa [$2 pâge de dèscripcion] por més d’enformacions.',
-'sharedupload-desc-here' => 'Ceti fichiér vint de $1 et pôt étre utilisâ per d’ôtros projèts.
-La dèscripcion de sa [$2 pâge de dèscripcion] est montrâ ce-desot.',
+'duplicatesoffile' => '{{PLURAL:$1|Cél fichiér-que est un doblo|Celos $1 fichiérs-que sont des doblos}} de ceti ([[Special:FileDuplicateSearch/$2|més de dètalys]]) :',
+'sharedupload' => 'Ceti fichiér vint de $1 et pôt étre empleyê per d’ôtros projèts.',
+'sharedupload-desc-there' => 'Ceti fichiér vint de $1 et pôt étre empleyê per d’ôtros projèts.
+Se vos plét, vêde la sina [$2 pâge de dèscripcion] por més d’enformacions.',
+'sharedupload-desc-here' => 'Ceti fichiér vint de $1 et pôt étre empleyê per d’ôtros projèts.
+La dèscripcion de la sina [$2 pâge de dèscripcion] est montrâye ce-desot.',
+'sharedupload-desc-edit' => 'Ceti fichiér vint de $1 et pôt étre empleyê per d’ôtros projèts.
+Pôt-étre vos voléd changiér la dèscripcion sur la sina [$2 pâge de dèscripcion].',
+'sharedupload-desc-create' => 'Ceti fichiér vint de $1 et pôt étre empleyê per d’ôtros projèts.
+Pôt-étre vos voléd changiér la dèscripcion sur la sina [$2 pâge de dèscripcion].',
 'filepage-nofile' => 'Nion fichiér de cél nom ègziste.',
 'filepage-nofile-link' => 'Nion fichiér de cél nom ègziste, mas vos en pouede [$1 tèlèchargiér yon].',
-'uploadnewversion-linktext' => 'Tèlèchargiér una novèla vèrsion de ceti fichiér',
-'shared-repo-from' => 'de $1',
+'uploadnewversion-linktext' => 'Tèlèchargiér na novèla vèrsion de ceti fichiér',
+'shared-repo-from' => 'de $1',
 'shared-repo' => 'un dèpôt partagiê',
 'filepage.css' => '/* Lo code CSS betâ ique est encllu dens la pâge de dèscripcion du fichiér, et pués dens los vouiquis cliants ètrangiérs. */',
+'upload-disallowed-here' => 'Vos pouede pas ècllafar ceti fichiér.',
 
 # File reversion
-'filerevert' => 'Rètablir $1',
-'filerevert-legend' => 'Rètablir lo fichiér',
-'filerevert-intro' => "Vos éte prèst a rètablir lo fichiér '''[[Media:$1|$1]]''' a la [$4 vèrsion du $2 a $3].",
+'filerevert' => 'Rèvocar $1',
+'filerevert-legend' => 'Rèvocar lo fichiér',
+'filerevert-intro' => "Vos éte prèst a rèvocar lo fichiér '''[[Media:$1|$1]]''' a la [$4 vèrsion du $2 a $3].",
 'filerevert-comment' => 'Rêson :',
-'filerevert-defaultcomment' => 'Vèrsion du $1 a $2 rètablia',
-'filerevert-submit' => 'Rètablir',
-'filerevert-success' => "'''[[Media:$1|$1]]''' at étâ rètabli a la [$4 vèrsion du $2 a $3].",
-'filerevert-badversion' => 'Y at gins de vèrsion ples vielye du fichiér avouéc la dâta balyê.',
+'filerevert-defaultcomment' => 'Rèvocâ a la vèrsion du $1 a $2',
+'filerevert-submit' => 'Rèvocar',
+'filerevert-success' => "'''[[Media:$1|$1]]''' est étâ rèvocâ a la [$4 vèrsion du $2 a $3].",
+'filerevert-badversion' => 'Y at gins de vèrsion locala devant de cél fichiér avouéc l’horodatâjo balyê.',
 
 # File deletion
 'filedelete' => 'Suprimar $1',
 'filedelete-legend' => 'Suprimar lo fichiér',
-'filedelete-intro' => "Vos éte prèst a suprimar '''[[Media:$1|$1]]''' et pués tot son historico.",
+'filedelete-intro' => "Vos éte prèst a suprimar lo fichiér '''[[Media:$1|$1]]''' et pués tot lo sin historico.",
 'filedelete-intro-old' => "Vos éte aprés suprimar la vèrsion de '''[[Media:$1|$1]]''' du [$4 $2 a $3].",
 'filedelete-comment' => 'Rêson :',
 'filedelete-submit' => 'Suprimar',
-'filedelete-success' => "'''$1''' at étâ suprimâ.",
-'filedelete-success-old' => "La vèrsion de '''[[Media:$1|$1]]''' du $2 a $3 at étâ suprimâ.",
+'filedelete-success' => "'''$1''' est étâ suprimâ.",
+'filedelete-success-old' => "La vèrsion de '''[[Media:$1|$1]]''' du $2 a $3 est étâye suprimâye.",
 'filedelete-nofile' => "'''$1''' ègziste pas.",
-'filedelete-nofile-old' => "Ègziste gins de vèrsion arch·ivâ de '''$1''' avouéc los atributs spècefiâs.",
+'filedelete-nofile-old' => "Ègziste gins de vèrsion arch·ivâye de '''$1''' avouéc los atributs spècifiâs.",
 'filedelete-otherreason' => 'Ôtra rêson / rêson de ples :',
 'filedelete-reason-otherlist' => 'Ôtra rêson',
 'filedelete-reason-dropdown' => '*Rêsons corentes de suprèssion
 ** Violacion du drêt d’ôtor
 ** Fichiér en doblo',
 'filedelete-edit-reasonlist' => 'Changiér les rêsons de suprèssion',
-'filedelete-maintenance' => 'La suprèssion et la rèstoracion de fichiérs est dèsactivâ temporèrament pendent la mantegnence.',
-'filedelete-maintenance-title' => 'Empossiblo de suprimar lo fichiér',
+'filedelete-maintenance' => 'La suprèssion et la rèstoracion de fichiérs est dèsactivâye por un moment pendent la mantegnence.',
+'filedelete-maintenance-title' => 'Y at pas moyen de suprimar lo fichiér',
 
 # MIME search
-'mimesearch' => 'Rechèrche per tipo de contegnu MIME',
-'mimesearch-summary' => "Ceta pâge vos pèrmèt de listar los fichiérs accèssiblos per ceti vouiqui d’aprés lor tipo de contegnu MIME.
-Entrâ : ''tipo de contegnu''/''sot-tipo'', per ègzemplo <code>image/jpeg</code>.",
+'mimesearch' => 'Rechèrche per tipo MIME',
+'mimesearch-summary' => "Ceta pâge pèrmèt de filtrar los fichiérs per lor tipo MIME.
+Entrâ : ''tipodecontegnu''/''sot-tipo'', per ègzemplo <code>image/jpeg</code>.",
 'mimetype' => 'Tipo MIME :',
-'download' => 'Tèlèchargiér',
+'download' => 'tèlèchargiér',
 
 # Unwatched pages
 'unwatchedpages' => 'Pâges pas siuvues',
@@ -2094,51 +2099,52 @@ Entrâ : ''tipo de contegnu''/''sot-tipo'', per ègzemplo <code>image/jpeg</code
 'listredirects' => 'Lista de les redirèccions',
 
 # Unused templates
-'unusedtemplates' => 'Modèlos inutilisâs',
-'unusedtemplatestext' => 'Ceta pâge liste totes les pâges de l’èspâço de noms « {{ns:template}} » que sont pas entrebetâyes dedens nionôtra pâge.
+'unusedtemplates' => 'Modèlos pas empleyês',
+'unusedtemplatestext' => 'Ceta pâge liste totes les pâges de l’èspâço de noms « {{ns:template}} » que sont pas entrebetâyes dedens nionôtra pâge.
 Oubliâd pas de controlar s’y at gins d’ôtro lim de vers los modèlos devant que los suprimar.',
 'unusedtemplateswlh' => 'ôtros lims',
 
 # Random page
-'randompage' => 'Pâge a l’hasârd',
-'randompage-nopages' => 'Y at gins de pâge dens {{PLURAL:$2|ceti èspâço|cetos èspâços}} de noms : $1.',
+'randompage' => 'Pâge per hasârd',
+'randompage-nopages' => 'Y at gins de pâge dedens {{PLURAL:$2|cet’èspâço|cetos èspâços}} de noms : $1.',
 
 # Random redirect
-'randomredirect' => 'Pâge de redirèccion a l’hasârd',
-'randomredirect-nopages' => 'Y at gins de pâge de redirèccion dens l’èspâço de noms « $1 ».',
+'randomredirect' => 'Redirèccion per hasârd',
+'randomredirect-nopages' => 'Y at gins de pâge de redirèccion dedens l’èspâço de noms « $1 ».',
 
 # Statistics
 'statistics' => 'Statistiques',
 'statistics-header-pages' => 'Statistiques de les pâges',
 'statistics-header-edits' => 'Statistiques des changements',
-'statistics-header-views' => 'Statistiques de les visualisacions',
-'statistics-header-users' => 'Statistiques ux usanciérs',
+'statistics-header-views' => 'Statistiques de les vues',
+'statistics-header-users' => 'Statistiques des utilisators',
 'statistics-header-hooks' => 'Ôtres statistiques',
 'statistics-articles' => 'Pâges de contegnu',
 'statistics-pages' => 'Pâges',
-'statistics-pages-desc' => 'Totes les pâges du vouiqui, les pâges de discussion, les redirèccions, ... avouéc',
+'statistics-pages-desc' => 'Totes les pâges du vouiqui, les pâges de discussion, les redirèccions, et tot cen que vat avouéc',
 'statistics-files' => 'Fichiérs tèlèchargiês',
 'statistics-edits' => 'Changements de pâges dês l’enstalacion de {{SITENAME}}',
 'statistics-edits-average' => 'Nombro moyen de changements per pâge',
-'statistics-views-total' => 'Soma de les visualisacions',
-'statistics-views-total-desc' => 'Les visualisacions de les pâges pas ègzistentes et de les pâges spèciâles sont pas encllues',
-'statistics-views-peredit' => 'Visualisacions per changement',
-'statistics-users' => '[[Special:ListUsers|Usanciérs]] encartâs',
-'statistics-users-active' => 'Usanciérs actifs',
-'statistics-users-active-desc' => 'Usanciérs qu’ont fêt u muens una accion pendent {{PLURAL:$1|lo jorn passâ|los $1 jorns passâs}}',
+'statistics-views-total' => 'Soma de les vues',
+'statistics-views-total-desc' => 'Les vues de les pâges pas ègzistentes et de les pâges spèciâles sont pas avouéc',
+'statistics-views-peredit' => 'Vues per changement',
+'statistics-users' => '[[Special:ListUsers|Utilisators]] encartâs',
+'statistics-users-active' => 'Utilisators actifs',
+'statistics-users-active-desc' => 'Utilisators qu’ont fêt por lo muens n’accion pendent {{PLURAL:$1|lo jorn passâ|los $1 jorns passâs}}',
 'statistics-mostpopular' => 'Pâges les ples vues',
 
 'disambiguations' => 'Pâges qu’ont des lims de vers des pâges d’homonimia',
 'disambiguationspage' => 'Template:Homonimia',
-'disambiguations-text' => "Cetes pâges ont u muens yon lim de vers na '''pâge d’homonimia'''.
+'disambiguations-text' => "Cetes pâges ont por lo muens un lim de vers na '''pâge d’homonimia'''.
 Devriant pletout pouentar vers na pâge que vat avouéc.<br />
-Na pâge est trètâye coment na pâge d’homonimia s’empleye un modèlo liyê a [[MediaWiki:Disambiguationspage]].",
+Na pâge est trètâye coment na pâge d’homonimia s’emplèye un modèlo liyê a [[MediaWiki:Disambiguationspage]].",
 
 'doubleredirects' => 'Redirèccions dobles',
-'doubleredirectstext' => 'Vê-que la lista de les pâges que redirijont vers des pâges que sont lor-mémes des pâges de redirèccion.
-Châque entrâ contint des lims de vers la premiére et la seconda redirèccion, et pués la premiére legne de tèxto de la seconda pâge, cen que balye habituèlament la « veré » pâge ciba, de vers laquinta la premiére redirèccion devrêt redirigiér.
-Les entrâs <del>barrâs</del> ont étâ solucionâs.',
-'double-redirect-fixed-move' => 'Cela redirèccion, que la ciba [[$1]] at étâ renomâ, mène ora vers [[$2]].',
+'doubleredirectstext' => 'Ceta pâge liste les pâges que redirijont vers d’ôtres pâges de redirèccion.
+Châque renche contint des lims de vers la premiére et la seconda redirèccion, et pués la ciba de la seconda redirèccion, cen que balye habituèlament la « veré » pâge ciba, de vers laquinta la premiére redirèccion devrêt pouentar.
+Les entrâs <del>barrâyes</del> sont étâyes solucionâyes.',
+'double-redirect-fixed-move' => '[[$1]] est étâye dèplaciêe.
+Ora redirige vers [[$2]].',
 'double-redirect-fixed-maintenance' => 'Correge la redirèccion dobla de [[$1]] vers [[$2]].',
 'double-redirect-fixer' => 'Corrèctor de redirèccion',
 
@@ -2148,11 +2154,11 @@ Les entrâs <del>barrâs</del> ont étâ solucionâs.',
 'brokenredirects-delete' => 'suprimar',
 
 'withoutinterwiki' => 'Pâges sen lims entèrlengoues',
-'withoutinterwiki-summary' => 'Cetes pâges ont gins de lim de vers d’ôtres lengoues :',
+'withoutinterwiki-summary' => 'Cetes pâges ont gins de lim de vers d’ôtres lengoues.',
 'withoutinterwiki-legend' => 'Prèfixo',
 'withoutinterwiki-submit' => 'Montrar',
 
-'fewestrevisions' => 'Pâges les muens changiês',
+'fewestrevisions' => 'Pâges avouéc lo muens de vèrsions',
 
 # Miscellaneous special pages
 'nbytes' => '$1 octèt{{PLURAL:$1||s}}',
@@ -2161,80 +2167,80 @@ Les entrâs <del>barrâs</del> ont étâ solucionâs.',
 'nlinks' => '$1 lim{{PLURAL:$1||s}}',
 'nmembers' => '$1 membro{{PLURAL:$1||s}}',
 'nrevisions' => '$1 vèrsion{{PLURAL:$1||s}}',
-'nviews' => '$1 visualisacion{{PLURAL:$1||s}}',
-'nimagelinks' => 'Utilisâ dessus $1 pâge{{PLURAL:$1||s}}',
-'ntransclusions' => 'utilisâ dessus $1 pâge{{PLURAL:$1||s}}',
+'nviews' => '$1 vu{{PLURAL:$1|a|es}}',
+'nimagelinks' => 'Empleyê dessus $1 pâge{{PLURAL:$1||s}}',
+'ntransclusions' => 'empleyê dessus $1 pâge{{PLURAL:$1||s}}',
 'specialpage-empty' => 'Y at gins de rèsultat a fâre vêre.',
 'lonelypages' => 'Pâges orfenes',
-'lonelypagestext' => 'Cetes pâges sont pas liyês ou ben encllues dês d’ôtres pâges de {{SITENAME}}.',
-'uncategorizedpages' => 'Pâges sen catègorie',
-'uncategorizedcategories' => 'Catègories sen catègorie',
-'uncategorizedimages' => 'Fichiérs sen catègorie',
-'uncategorizedtemplates' => 'Modèlos sen catègorie',
-'unusedcategories' => 'Catègories inutilisâs',
-'unusedimages' => 'Fichiérs inutilisâs',
-'popularpages' => 'Pâges les ples vues',
-'wantedcategories' => 'Catègories les ples demandâs',
+'lonelypagestext' => 'Cetes pâges sont ni pouentâyes ni entrebetâyes per d’ôtres pâges de {{SITENAME}}.',
+'uncategorizedpages' => 'Pâges sen catègories',
+'uncategorizedcategories' => 'Catègories sen catègories',
+'uncategorizedimages' => 'Fichiérs sen catègories',
+'uncategorizedtemplates' => 'Modèlos sen catègories',
+'unusedcategories' => 'Catègories pas empleyêes',
+'unusedimages' => 'Fichiérs pas empleyês',
+'popularpages' => 'Pâges populères',
+'wantedcategories' => 'Catègories demandâyes',
 'wantedpages' => 'Pâges demandâyes',
-'wantedpages-badtitle' => 'Titro envalido dens los rèsultats : $1',
+'wantedpages-badtitle' => 'Titro pas justo dedens l’ensemblo de rèsultats : $1',
 'wantedfiles' => 'Fichiérs demandâs',
-'wantedfiletext-cat' => 'Cetos fichiérs sont utilisâs, mas ègzistont pas. Los fichiérs de dèpôts a distance pôvont étre listâs mâlgrât qu’ègzistont. Tot celos fôx positifs seront <del>traciês</del>. Pués, les pâges qu’apondont des fichiérs qu’ègzistont pas sont rèpèrtoriyês dedens [[:$1]].',
-'wantedfiletext-nocat' => 'Cetos fichiérs sont utilisâs, mas ègzistont pas. Los fichiérs de dèpôts a distance pôvont étre listâs mâlgrât qu’ègzistont. Tot celos fôx positifs seront <del>traciês</del>.',
-'wantedtemplates' => 'Modèlos los ples demandâs',
-'mostlinked' => 'Pâges les ples liyês',
-'mostlinkedcategories' => 'Catègories les ples utilisâs',
-'mostlinkedtemplates' => 'Modèlos los ples utilisâs',
-'mostcategories' => 'Pâges qu’utilisont lo més de catègories',
-'mostimages' => 'Fichiérs los ples utilisâs',
+'wantedfiletext-cat' => 'Cetos fichiérs sont empleyês, mas ègzistont pas. Los fichiérs de dèpôts de defôr pôvont étre listâs mémo s’ègzistont. Tôs celos fôx positifs seront <del>barrâs</del>. Et pués les pâges qu’apondont des fichiérs qu’ègzistont pas sont listâs dedens [[:$1]].',
+'wantedfiletext-nocat' => 'Cetos fichiérs sont empleyês, mas ègzistont pas. Los fichiérs de dèpôts de defôr pôvont étre listâs mémo s’ègzistont. Tôs celos fôx positifs seront <del>barrâs</del>.',
+'wantedtemplates' => 'Modèlos demandâs',
+'mostlinked' => 'Pâges les ples liyêes',
+'mostlinkedcategories' => 'Catègories les ples liyêes',
+'mostlinkedtemplates' => 'Modèlos los ples liyês',
+'mostcategories' => 'Pâges avouéc lo més de catègories',
+'mostimages' => 'Fichiérs los ples liyês',
 'mostinterwikis' => 'Pâges avouéc lo més de lims entèrvouiquis',
-'mostrevisions' => 'Pâges les ples changiês',
+'mostrevisions' => 'Pâges avouéc lo més de vèrsions',
 'prefixindex' => 'Totes les pâges que començont per...',
 'prefixindex-namespace' => 'Totes les pâges avouéc prèfixo (èspâço de noms $1)',
 'shortpages' => 'Pâges côrtes',
 'longpages' => 'Pâges longes',
 'deadendpages' => 'Pâges en cul-de-sac',
-'deadendpagestext' => 'Cetes pâges ont gins de lim de vers d’ôtres pâges de {{SITENAME}}.',
-'protectedpages' => 'Pâges protègiês',
-'protectedpages-indef' => 'Solament les protèccions sen fin',
-'protectedpages-cascade' => 'Solament les protèccions en cascâda',
-'protectedpagestext' => 'Cetes pâges sont protègiês contre los changements et/ou lo changement de nom :',
-'protectedpagesempty' => 'Ora, niona pâge est protègiê avouéc celos paramètres.',
+'deadendpagestext' => 'Cetes pâges contegnont gins de lim de vers d’ôtres pâges de {{SITENAME}}.',
+'protectedpages' => 'Pâges protègiêes',
+'protectedpages-indef' => 'Ren que les protèccions sen fin',
+'protectedpages-cascade' => 'Ren que les protèccions en cascâda',
+'protectedpagestext' => 'Cetes pâges sont protègiêes contre los dèplacements los changements',
+'protectedpagesempty' => 'Ora niona pâge est protègiêe avouéc celos paramètros.',
 'protectedtitles' => 'Titros protègiês',
-'protectedtitlestext' => 'Cetos titros sont protègiês a la crèacion :',
-'protectedtitlesempty' => 'Ora, nion titro est protègiê avouéc celos paramètres.',
-'listusers' => 'Lista ux usanciérs',
-'listusers-editsonly' => 'Fâre vêre ren que los usanciérs qu’ont u muens yona contribucion',
-'listusers-creationsort' => 'Triyér per dâta de crèacion',
+'protectedtitlestext' => 'Cetos titros sont protègiês a la crèacion',
+'protectedtitlesempty' => 'Ora nion titro est protègiê avouéc celos paramètros.',
+'listusers' => 'Lista des utilisators',
+'listusers-editsonly' => 'Montrar ren que los utilisators avouéc des contribucions',
+'listusers-creationsort' => 'Betar per dâta de crèacion',
 'usereditcount' => '$1 changement{{PLURAL:$1||s}}',
 'usercreated' => 'Fêt{{GENDER:$3||a}} lo $1 a $2',
 'newpages' => 'Pâges novèles',
 'newpages-username' => 'Nom d’utilisator :',
-'ancientpages' => 'Pâges les muens dèrriérement changiês',
-'move' => 'Renomar',
-'movethispage' => 'Renomar ceta pâge',
-'unusedimagestext' => 'Cetos fichiérs ègzistont, mas sont pas encllus dens niona pâge.
-Volyéd notar que d’ôtros setos pôvont avêr un lim drêt de vers un fichiér, et donc qu’un fichiér pôt étre listâ ique pendent qu’il est en rèalitât utilisâ sur celos setos.',
-'unusedcategoriestext' => 'Cetes catègories ègzistont mas gins de pâge ou ben de catègorie les utilise.',
-'notargettitle' => 'Gins de ciba',
-'notargettext' => 'Vos éd pas spècefiâ una pâge ou ben un usanciér ciba sur laquinta / loquint vos souhètâd fâre cela accion.',
-'nopagetitle' => 'Gins de pâge ciba',
-'nopagetext' => 'La pâge ciba que vos éd spècefiâ ègziste pas.',
+'ancientpages' => 'Pâges les ples vielyes',
+'move' => 'Dèplaciér',
+'movethispage' => 'Dèplaciér ceta pâge',
+'unusedimagestext' => 'Cetos fichiérs ègzistont, mas sont pas entrebetâs dedens niona pâge.
+Se vos plét, notâd que d’ôtros setos Vouèbe pôvont avêr un lim de vers un fichiér avouéc n’URL drêta, donc un fichiér pôt adés étre listâ ique pendent qu’il est en usâjo actif.',
+'unusedcategoriestext' => 'Cetes catègories ègzistont, mas nion’ôtra pâge niona catègorie les emplèye.',
+'notargettitle' => 'Niona ciba',
+'notargettext' => 'Vos éd pas spècifiâ na pâge un utilisator ciba sur laquinta / loquint vos souhètâd fâre cel’accion.',
+'nopagetitle' => 'Niona pâge ciba d’ense',
+'nopagetext' => 'La pâge ciba que vos éd spècifiâye ègziste pas.',
 'pager-newer-n' => '{{PLURAL:$1|ples novèla|$1 ples novèles}}',
 'pager-older-n' => '{{PLURAL:$1|ples vielye|$1 ples vielyes}}',
 'suppress' => 'Ôtar',
-'querypage-disabled' => 'Ceta pâge spèciâla est dèsactivâ por des rêsons de capacitât.',
+'querypage-disabled' => 'Ceta pâge spèciâla est dèsactivâye por des rêsons de capacitât.',
 
 # Book sources
 'booksources' => 'Ôvres de refèrence',
-'booksources-search-legend' => 'Rechèrchiér permié des ôvres de refèrence',
+'booksources-search-legend' => 'Rechèrchiér entre-mié les ôvres de refèrence',
 'booksources-isbn' => 'ISBN :',
 'booksources-go' => 'Listar',
-'booksources-text' => 'Vê-que la lista endicativa et pas èxcllusiva de lims de vers d’ôtros setos que vendont des lévros nôfs et d’ocasion et sur losquints vos troveréd pôt-étre des enformacions sur les ôvres que vos chèrchiéd :',
-'booksources-invalid-isbn' => 'L’ISBN balyê semble pas étre valido ; controlâd se vos éd fêt una èrror en copiyent la sôrsa originâla.',
+'booksources-text' => 'Vê-que na lista de lims de vers d’ôtros setos que vendont des lévros nôfs et d’ocasion, et pués pôvont avêr des enformacions de ples sur les ôvres que vos chèrchiéd :',
+'booksources-invalid-isbn' => 'L’ISBN balyê semble pas étre justo ; controlâd se vos éd fêt na fôta en copiyent la sôrsa originâla.',
 
 # Special:Log
 'specialloguserlabel' => 'Ôtor :',
-'speciallogtitlelabel' => 'Ciba (titro ou ben usanciér) :',
+'speciallogtitlelabel' => 'Ciba (titro ou ben utilisator) :',
 'log' => 'Jornals',
 'all-logs-page' => 'Tôs los jornals publicos',
 'alllogstext' => 'Visualisacion combinâ de tôs los jornals disponiblos dessus {{SITENAME}}.
index 48da258..4d0846f 100644 (file)
@@ -456,7 +456,7 @@ Ferjid det ei, an aachte üüb din [[Special:Preferences|{{SITENAME}} iinstelang
 'gotaccount' => "Dü hääst ål en brükerkonto? '''$1'''.",
 'gotaccountlink' => 'Önjmälde',
 'userlogin-resetlink' => 'Heest dü din login dooten ferjiden?',
-'createaccountmail' => 'ouer E-mail',
+'createaccountmail' => 'E-mail tu det adres oner fersjüür mä en tufelag paaswurd',
 'createaccountreason' => 'Grün:',
 'badretype' => 'Da biise pååsuurde stime ai oueriinj.',
 'userexists' => 'Dideer brükernoome as ål ferjääwen.
@@ -752,7 +752,7 @@ Wan dü heer wat iinskrafst, do beest dü diarmä iinferstenen an seekerst tu, d
 '''Auerdreeg nään frääm teksten an bilen saner ferloof!'''",
 'longpageerror' => "'''Error: Dan tekst as {{PLURAL:$1|ian kilobyte|$1 kilobytes}} lung, hi mut oober ei linger wees üs {{PLURAL:$2|ian kilobyte|$2 kilobytes}}.'''Hi koon ei ufspiikerd wurd.",
 'readonlywarning' => "'''PÅÅS AW: Jü dootenbånk wörd for unerhult spärd, sü dåt din änringe tutids ai spiikerd wårde koone.
-Wees sü gödj än sääkre di täkst lokool aw din kompjuuter än fersäk tu n lääsern tidpunkt, da änringe tu ouerdreegen.'''.
+Wees sü gödj än sääkre di täkst lokool aw din kompjuuter än fersäk tun lääsern tidpunkt, da änringe tu ouerdreegen.'''.
 
 Grün for jü späre: $1",
 'protectedpagewarning' => "'''Paase üüb: Detdiar sidj as speret wurden. Bluas administratooren kön det bewerke.'''
@@ -1229,14 +1229,14 @@ Do san jo ual iinstelangen wech.',
 'group-sysop' => 'Administratooren',
 'group-bureaucrat' => 'Bürokraaten',
 'group-suppress' => 'Oversighter',
-'group-all' => '(aaltumaal)',
+'group-all' => '(Aaltumaal)',
 
-'group-user-member' => '{{GENDER:$1|brüker}}',
-'group-autoconfirmed-member' => '{{GENDER:$1|registriaret brüker}}',
-'group-bot-member' => '{{GENDER:$1|bot}}',
-'group-sysop-member' => '{{GENDER:$1|administraator}}',
-'group-bureaucrat-member' => '{{GENDER:$1|bürokraat}}',
-'group-suppress-member' => '{{GENDER:$1|oversighter}}',
+'group-user-member' => '{{GENDER:$1|Brüker}}',
+'group-autoconfirmed-member' => '{{GENDER:$1|Registriaret brüker}}',
+'group-bot-member' => '{{GENDER:$1|Bot}}',
+'group-sysop-member' => '{{GENDER:$1|Administraator}}',
+'group-bureaucrat-member' => '{{GENDER:$1|Bürokraat}}',
+'group-suppress-member' => '{{GENDER:$1|Oversighter}}',
 
 'grouppage-user' => '{{ns:project}}:Brükern',
 'grouppage-autoconfirmed' => '{{ns:project}}:Registriaret brükern',
@@ -1452,7 +1452,7 @@ Det beskriiwang faan't [$2 beskriiwangssidj] woort oner uunwiset.",
 'emailuser' => 'E-mail tu dideere brüker',
 
 # Watchlist
-'watchlist' => 'Eefterkiikliste',
+'watchlist' => "Uun't uug behual",
 'mywatchlist' => "Uun't uug behual",
 'watchlistfor2' => 'Foon $1 $2',
 'addedwatchtext' => "Det sidj „[[:$1]]“ wel dü [[Special:Watchlist|uun't uug behual]].
index ba39b45..d0f4166 100644 (file)
@@ -496,6 +496,7 @@ Tabhair faoi deara go taispeáinfear roinnt leathanaigh mar atá tú logáilte i
 'createaccount' => 'Cruthaigh cuntas nua',
 'gotaccount' => "An bhfuil cuntas agat cheana féin? '''$1'''.",
 'gotaccountlink' => 'Logáil isteach',
+'userlogin-resetlink' => 'Sonraí logála isteach dearmadta agat?',
 'createaccountmail' => 'le ríomhphost',
 'createaccountreason' => 'Fáth:',
 'badretype' => "D'iontráil tú dhá fhocal faire difriúla.",
@@ -782,17 +783,22 @@ Treoir: (rth) = difríocht ón leagan reatha, (rmh) = difríocht ón leagan roim
 'notextmatches' => 'Ní bhfuarthas an téacs ar leathanach ar bith',
 'prevn' => 'na {{PLURAL:$1|$1}} cinn roimhe seo',
 'nextn' => 'an {{PLURAL:$1|$1}} i ndiadh',
+'shown-title' => 'Taispeáin $1 {{PLURAL:$1|thoradh|torthaí}} an leathanach',
 'viewprevnext' => 'Taispeáin ($1 {{int:pipe-separator}} $2) ($3).',
 'searchmenu-legend' => 'Sainroghanna cuardaithe',
 'searchmenu-new' => "'''Cruthaigh an leathanach \"[[:\$1]]\" ar an vicí seo!'''",
 'searchhelp-url' => 'Help:Clár_ábhair',
+'searchprofile-articles' => 'Leathanaigh ábhair',
 'searchprofile-project' => 'Leathanaigh thionscadail agus cabhair',
 'searchprofile-images' => 'Ilmheáin',
 'searchprofile-everything' => 'Gach rud',
+'searchprofile-advanced' => 'Casta',
 'searchprofile-articles-tooltip' => 'Cuardaigh i $1',
 'searchprofile-project-tooltip' => 'Cuardaigh i $1',
 'searchprofile-images-tooltip' => 'Cuardaigh le comhaid',
-'search-result-size' => '$1 ({{PLURAL:$2|focal amháin|$2 focail}})',
+'searchprofile-everything-tooltip' => 'Cuardaigh an t-ábhar ar fad (leathanaigh plé san áireamh)',
+'searchprofile-advanced-tooltip' => 'Cuardaigh in ainmspásanna saincheaptha',
+'search-result-size' => '$1 ({{PLURAL:$2|fhocal amháin|$2 focail}})',
 'search-redirect' => '(athsheoladh $1)',
 'search-section' => '(gearradh $1)',
 'search-suggest' => 'An raibh $1 á lorg agat?',
@@ -899,7 +905,7 @@ Beidh an t-eolas seo poiblí.',
 'email' => 'Ríomhphost',
 'prefs-help-realname' => '* <strong>Fíorainm</strong> (roghnach): má toghaíonn tú é sin a chur ar fáil, úsáidfear é chun
 do chuid dreachtaí a chur i leith tusa.',
-'prefs-help-email' => '<strong>Ríomhphost</strong> (roghnach): Leis an tréith seo is féidir teagmháil a dhéanamh leat tríd do leathanach úsáideora nó leathanach phlé gan do sheoladh ríomhphost a thaispeáint.',
+'prefs-help-email' => 'Is roghnach seoladh ríomhphoist a thabhairt, ach is riachtanach é chun focal faire a athshocrú, má dhéanann tú dearmad air.',
 'prefs-help-email-required' => 'Ní foláir seoladh ríomhpoist a thabhairt.',
 'prefs-info' => 'Buneolas',
 'prefs-i18n' => 'Logánú',
@@ -965,6 +971,7 @@ do chuid dreachtaí a chur i leith tusa.',
 'recentchanges-legend' => 'Roghanna do na hathruithe is déanaí',
 'recentchanges-summary' => 'Déan faire ar na hathruithe is déanaí sa vicí ar an leathanach seo.',
 'recentchanges-feed-description' => 'Rianaigh na n-athruite vicí is déanaí sa fotha seo.',
+'recentchanges-label-minor' => 'Mionathrú é seo',
 'recentchanges-label-bot' => 'Chomhlíon róbó an t-athrú seo',
 'rcnote' => "Is {{PLURAL:$1|é seo a leanas <strong>an t-athrú amháin</strong>|iad seo a leanas na <strong>$1</strong> athruithe is déanaí}} {{PLURAL:$2|ar feadh an lae dheireanaigh|ar feadh na '''$2''' lá deireanacha}}, as $5, $4.",
 'rcnotefrom' => 'Is iad seo a leanas na hathruithe ó <b>$2</b> (go dti <b>$1</b> taispeánaithe).',
@@ -1202,7 +1209,7 @@ chun an gníomh seo a dhéanamh ar.',
 # Special:Log
 'specialloguserlabel' => 'Úsáideoir:',
 'speciallogtitlelabel' => 'Teideal:',
-'log' => 'Loganna',
+'log' => 'Logaí',
 'all-logs-page' => 'Gach loga poiblí',
 'alllogstext' => 'Bailiúchán cuimsitheach de gach loga {{SITENAME}}.
 Is féidir leat an méid ar taispeáint a chúngú trí roghnú an saghas loga, an t-ainm úsáideora (cásíogair), nó an leathanach (cásíogair freisin) atá i gceist agat.',
@@ -1270,7 +1277,7 @@ Beidh do seoladh ríomhphoist a d\'iontráil tú i [[Special:Preferences|do chui
 'emailsenttext' => 'Seoladh do theachtaireacht ríomhphoist go ráthúil.',
 
 # Watchlist
-'watchlist' => 'Mo liosta faire',
+'watchlist' => 'Liosta faire',
 'mywatchlist' => 'Liosta faire',
 'watchlistfor2' => 'Do $1 ($2)',
 'nowatchlist' => 'Níl aon rud ar do liosta faire.',
@@ -1370,6 +1377,7 @@ Féach ar $2 chun cuntas na scriosiadh deireanacha a fháil.',
 'rollback' => 'Athruithe a rolladh siar',
 'rollback_short' => 'Roll siar',
 'rollbacklink' => 'roll siar',
+'rollbacklinkcount' => 'Roll siar $1 {{PLURAL:$1|athrú|athruithe}}',
 'rollbackfailed' => 'Theip an rolladh siar',
 'cantrollback' => 'Ní féidir an athrú a athúsáid; ba é údar an ailt an t-aon duine a rinne athrú dó.',
 'alreadyrolled' => "Ní féidir eagrán níos luaí an leathanaigh [[:$1]] le [[User:$2|$2]] ([[User talk:$2|Plé]]{{int:pipe-separator}}[[Special:Contributions/$2|{{int:contribslink}}]]) a athúsáid; d'athraigh duine eile é cheana fein, nó d'athúsáid duine eile eagrán níos luaí cheana féin.
@@ -1453,7 +1461,7 @@ Is an téacs as na leagan scriosta seo ar fáil do riarthóirí amháin.',
 'blanknamespace' => '(Gnáth)',
 
 # Contributions
-'contributions' => 'Dréachtaí úsáideora',
+'contributions' => 'Dréachtaí {{GENDER:$1|úsáideora}}',
 'contributions-title' => 'Dréachtaí úsáideora do $1',
 'mycontris' => 'Dréachtaí',
 'contribsub2' => 'Do $1 ($2)',
@@ -1467,6 +1475,8 @@ Is an téacs as na leagan scriosta seo ar fáil do riarthóirí amháin.',
 'sp-contributions-newbies-title' => 'Dréachtaí úsáideora do chuntasaí nua',
 'sp-contributions-blocklog' => 'Log coisc',
 'sp-contributions-deleted' => 'dréachtaí úsáideora scriosta',
+'sp-contributions-uploads' => 'uaslódálacha',
+'sp-contributions-logs' => 'logaí',
 'sp-contributions-talk' => 'plé',
 'sp-contributions-userrights' => 'bainistíocht cearta úsáideora',
 'sp-contributions-search' => 'Cuardaigh dréachtaí',
@@ -1713,7 +1723,7 @@ ní féidir uaslódála staire díreacha a dhéanamh faoi láthair.",
 'tooltip-n-mainpage-description' => 'Tabhair cuairt ar an bpríomhleathanach',
 'tooltip-n-portal' => 'Maidir leis an tionscadal, cad is féidir leat a dhéanamh, conas achmhainní a fháil',
 'tooltip-n-currentevents' => 'Faigh eolas cúlrach maidir le chursaí reatha',
-'tooltip-n-recentchanges' => 'Liosta de na hathruithe is déanaí sa vicí.',
+'tooltip-n-recentchanges' => 'Liosta de na hathruithe is déanaí sa vicí',
 'tooltip-n-randompage' => 'Lódáil leathanach fánach',
 'tooltip-n-help' => 'An áit chun cabhair a fháil.',
 'tooltip-t-whatlinkshere' => 'Liosta de gach leathanach sa vicí ina bhfuil nasc chuig an leathanach seo',
@@ -1742,7 +1752,9 @@ ní féidir uaslódála staire díreacha a dhéanamh faoi láthair.",
 'tooltip-diff' => 'Taispeáin na difríochtaí áirithe a rinne tú don téacs',
 'tooltip-compareselectedversions' => 'Féach na difríochtaí idir an dhá leagain roghnaithe den leathanach seo.',
 'tooltip-watch' => 'Cuir an leathanach seo le do liosta faire',
+'tooltip-rollback' => 'Fill ar leagan an leathanaigh seo roimh athruithe an eagarthóra dheireanaigh in aon chlic amháin',
 'tooltip-undo' => 'Cuirtear "Cealaigh" an t-athrú seo ar cheal agus osclaítear an fhoirm eagair i mód réamhamhairc. Is féidir cúis na hathruithe a chur san achoimre.',
+'tooltip-summary' => 'Cuir isteach achoimre ghearr',
 
 # Stylesheets
 'monobook.css' => '/* athraigh an comhad seo chun an craiceann MonoBook a athrú don suíomh ar fad */',
@@ -1820,11 +1832,11 @@ B'fheidir go gcuirfear do chóras i gcontúirt dá rithfeá é.",
 'sp-newimages-showfrom' => 'Taispeáin íomhánna nua as $2, $1',
 
 # Bad image list
-'bad_image_list' => 'An formáid ná a leanas:
+'bad_image_list' => 'Is é seo a leanas an formáid:
 
-Míreanna liosta amháin (líonta a tosú le *) atá eisithe.
-Tá ar an chead nasc ar líne, naiscthe le drochchomhad.
-Aon naisc a leanas ar an líne céanna atá eisithe mar eisceachtaí; leathanaigh ina tarlaigh an comhad inlíne.',
+Níl ach míreanna liosta amháin (línte ag tosú le *) san áireamh.
+Is riachtanach gur nasc do dhrochchomhad é an chéad nasc ar líne.
+Is eisceachtaí iad na naisc eile ar an líne céanna, .i. leathanaigh gur féidir an comhad a bheith orthu go hinlíne.',
 
 # Metadata
 'metadata' => 'Meiteasonraí',
@@ -1832,7 +1844,7 @@ Aon naisc a leanas ar an líne céanna atá eisithe mar eisceachtaí; leathanaig
 Má tá an comhad mionathraithe as an bunleagan, b'fhéidir nach mbeidh ceann de na sonraí fágtha sa comhad atá athruithe.",
 'metadata-expand' => 'Taispeáin sonraí síneadh',
 'metadata-collapse' => 'Folaigh sonraí síneadh',
-'metadata-fields' => 'Beidh meiteasonraí EXIF atá liosta sa teachtaireacht seo san áireamh ar an leathanach íomhá nuair ata an clár meiteasonraí ceilte.
+'metadata-fields' => 'Beidh na meiteasonraí EXIF seo a leanas dá dtaispeáint ar an leathanach íomhá nuair atá an clár meiteasonraí ceilte.
 Beidh na cinn eile ceilte de réir réamhshocraithe.
 * make
 * model
index d535b48..ce0e3da 100644 (file)
@@ -168,6 +168,7 @@ $messages = array(
 'newwindow' => "(a' fosgladh ann an uinneag ùr)",
 'cancel' => 'Sguir dheth',
 'moredotdotdot' => 'Barrachd...',
+'morenotlisted' => 'Barrachd nach eil air an liosta...',
 'mypage' => 'Duilleag',
 'mytalk' => 'Deasbaireachd',
 'anontalk' => 'Conaltradh airson an IP seo',
@@ -201,6 +202,7 @@ $messages = array(
 'namespaces' => 'Namespaces',
 'variants' => 'Tionndaidhean',
 
+'navigation-heading' => 'Clàr-taice na seòladaireachd',
 'errorpagetitle' => 'Mearachd',
 'returnto' => 'Till dhan duilleag a leanas: $1',
 'tagline' => 'O {{SITENAME}}',
@@ -444,6 +446,9 @@ Thug an rianaire a ghlais e seachad an t-adhbhar a leanas: "$3".',
 'logouttext' => "'''Chaidh do logadh a-mach.'''
 'S urrainn dhut leantainn air adhart a' cleachdadh {{SITENAME}} a chleachdadh gun urra no 's urrainn dhut <span class='plainlinks'>[$1 logadh a-steach a-rithist]</span> mar an dearbh-chleachdaiche no mar chleachdaiche eile.
 Thoir an aire gum bi coltas air cuide dhe na duilleagan mar gum biodh tu air logadh a-steach gus am falamhaich thu tasgadan a' bhrabhsair agad.",
+'welcomeuser' => 'Fàilte ort, $1',
+'welcomecreation-msg' => 'Chaidh an cunntas agad a chruthachadh.
+Na dìochuimhnich na [[Special:Preferences|roghainnean agad air {{SITENAME}}]] a ghleusadh dhut fhèin.',
 'yourname' => 'Ainm-cleachdaiche:',
 'yourpassword' => 'Am facal-faire agad',
 'yourpasswordagain' => 'Ath-sgrìobh facal-faire',
@@ -466,7 +471,7 @@ Thoir an aire gum bi coltas air cuide dhe na duilleagan mar gum biodh tu air log
 'gotaccount' => 'A bheil cunntas agad mu thràth? $1.',
 'gotaccountlink' => 'Log a-steach',
 'userlogin-resetlink' => "Na dhìochuimhnich thu d' ainm is facal-faire?",
-'createaccountmail' => 'Le post-d',
+'createaccountmail' => "Cleachd facal-faire sealach air thuaiream agus cuir e dhan phost-d a tha 'ga shònrachadh gu h-ìosal",
 'createaccountreason' => 'Adhbhar:',
 'badretype' => "Chan eil an dà fhacal-faire a chuir thu a-steach a' freagairt ri chèile.",
 'userexists' => "Tha an t-ainm-cleachdaiche a chuir thu a-steach 'ga chleachdadh mu thràth.
@@ -546,6 +551,7 @@ Fuirich ort mus feuch thu ris a-rithist.",
 # E-mail sending
 'php-mail-error-unknown' => 'Mearachd neo-aithichte san fheart mail() aig PHP.',
 'user-mail-no-addy' => 'Cha do ghabh am post-d a chur leis nach robh seòladh puist-d ann.',
+'user-mail-no-body' => 'Bha bodhaig na teachdaireachd bàn no air leth goirid.',
 
 # Change password dialog
 'resetpass' => 'Atharraich am facal-faire',
@@ -604,6 +610,7 @@ Facal-faire sealach: $2',
 'changeemail-oldemail' => 'An seòladh puist-d làithreach:',
 'changeemail-newemail' => 'An seòladh puist-d ùr:',
 'changeemail-none' => '(chan eil gin)',
+'changeemail-password' => 'Am facal-faire agad air {{SITENAME}}:',
 'changeemail-submit' => 'Atharraich am post-d',
 'changeemail-cancel' => 'Sguir dheth',
 
@@ -776,7 +783,7 @@ Ma dh'fhoilleachas tu rudeigin an seo, bidh tu a' dearbhadh gun do sgrìobh thu
 '''NA CLEACHDAIBH SAOTHAIR FO DHLIGHE-SGRÌOBHAIDH GUN CHEAD!'''",
 'longpageerror' => "'''Mearachd: Tha an teacsa a chur thu thugainn {{PLURAL:$1 kilobyte|$1 kilobyte|$1 kilobyte|$1 kilobyte|$1 kilobyte|$1 kilobyte|}} a dh'fhaid is tha sin nas fhaide na tha ceadaichte ({{PLURAL:$1 kilobyte|$2 kilobyte|$2 kilobyte|$2 kilobyte|$2 kilobyte|$2 kilobyte|}}).'''
 Cha ghabh a shàbhaladh.",
-'readonlywarning' => "'''Rabhadh: Chaidh an stòr-dàta a ghlasadh a chum obair-ghlèidhidh agus chan urrainn dhut na còraichean-deasachaidh agad a chur gu feum an-dràsta fhèin.'''
+'readonlywarning' => "'''Rabhadh: Chaidh an stòr-dàta a ghlasadh a chum obair-ghlèidhidh agus chan urrainn dhut na dheasaich thu a shàbhaladh an-dràsta fhèin.'''
 'S mathaid gum b' fheairrde dhut lethbhreac a dhèanamh dhen teacsa agus a shàbhaladh ann am faidhle ach an urrainn dhut a chleachdadh as a dhèidh seo.
 
 Seo am mìneachadh a thug an rianaire a ghlais e: $1",
@@ -817,6 +824,15 @@ Tha coltas gun deach a sguabadh às.",
 'edit-already-exists' => "Cha b' urrainn dhuinn an duilleag ùr a chruthachadh.
 Tha e ann mu thràth.",
 'defaultmessagetext' => 'Teacsa bunaiteach na teachdaireachd',
+'content-failed-to-parse' => "Dh'fhàillig parsadh susbaint $2 airson modail $1: $3",
+'invalid-content-data' => 'Dàta susbaint a tha mì-dhligheach',
+'content-not-allowed-here' => 'Chan eil susbaint "$1" ceadaichte air an duilleag [[$2]]',
+
+# Content models
+'content-model-wikitext' => 'wikitext',
+'content-model-text' => 'teacsa lom',
+'content-model-javascript' => 'JavaScript',
+'content-model-css' => 'CSS',
 
 # Parser/template warnings
 'expensive-parserfunction-warning' => "'''Rabhadh:''' Tha cus expensive parser function calls san duilleag seo.
@@ -856,7 +872,7 @@ Mìneachadh: '''({{int:cur}})''' = an diofar eadar e 's am mùthadh as ùire, ''
 'history-show-deleted' => 'Na chaidh sguabadh às a-mhàin',
 'histfirst' => 'As sine',
 'histlast' => 'As ùire',
-'historysize' => '({{PLURAL:$1|1 bhaidt|$1 bhaidht|$1 bhaidht|$1 bhaidht|$1 baidht|$1 baidht}})',
+'historysize' => '({{PLURAL:$1|1 bhaidt|$1 bhaidht|$1 bhaidht|$1 bhaidht|$1 baidhtichean|$1 baidht}})',
 'historyempty' => '(falamh)',
 
 # Revision feed
@@ -874,9 +890,11 @@ Feuch is [[Special:Search|lorg duilleagan ùra iomachaidh air an uici]]",
 'rev-delundel' => 'seall/falaich',
 'rev-showdeleted' => 'seall',
 'revdelete-hide-user' => 'Falaich ainm-cleachdaiche/seòladh IP an deasaiche',
+'revdelete-log' => 'Adhbhar:',
 'revdel-restore' => 'mùth follaiseachd',
 'revdel-restore-deleted' => 'mùthaidhean a chaidh a sguabadh às',
 'revdel-restore-visible' => 'mùthaidhean faicsinneach',
+'pagehist' => 'Eachdraidh na duilleige',
 'revdelete-otherreason' => 'Adhbhar eile/a bharrachd:',
 'revdelete-reasonotherlist' => 'Adhbhar eile',
 'revdelete-edit-reasonlist' => 'Deasaich adhbharan an sguabaidh às',
@@ -902,6 +920,8 @@ Feuch is [[Special:Search|lorg duilleagan ùra iomachaidh air an uici]]",
 'searchresulttext' => 'Airson barrachd fiosrachaidh mu rannsachadh {{SITENAME}}, cuir sùil air [[{{MediaWiki:Helppage}}|{{int:help}}]].',
 'searchsubtitle' => 'Lorg thu \'\'\'[[:$1]]\'\'\' ([[Special:Prefixindex/$1|gach duilleag a tha a\' tòiseachadh le "$1"]]{{int:pipe-separator}}[[Special:WhatLinksHere/$1|gach duilleag a tha a\' ceangal ri "$1"]])',
 'searchsubtitleinvalid' => "Lorg thu airson '''$1'''",
+'toomanymatches' => 'Fhuaras cus thoraidhean, feuch ceist eile',
+'titlematches' => "Tiotalan dhuilleagan a tha a' maidseadh",
 'notitlematches' => "Chan eil tiotal de dhuilleag sam bith a' freagairt ris",
 'notextmatches' => "Chan eil tiotal de dhuilleag sam bith a' freagairt ris",
 'prevn' => 'an {{PLURAL:$1|$1}} mu dheireadh',
@@ -925,6 +945,7 @@ Feuch is [[Special:Search|lorg duilleagan ùra iomachaidh air an uici]]",
 'searchprofile-advanced-tooltip' => 'Lorg am broinn ainm-spàsan gnàthaichte',
 'search-result-size' => '$1 ({{PLURAL:$2|1 fhacal|$2 fhacal|1 fhacal|$2 fhacal|$2 faclan|$2 facal}})',
 'search-result-category-size' => '{{PLURAL:$1|1 bhall|$1 bhall|$1 bhall|$1 bhall|$1 bhuill|$1 ball}} ({{PLURAL:$2|1 fho-roinn|$2 fho-roinn|$2 fho-roinn|$2 fho-roinn|$2 fo-roinnean|$2 fo-roinn}}, {{PLURAL:$3|1 fhaidhle|$3 fhaidhle|$3 fhaidhle|$3 fhaidhle|$3 faidhlichean|$3 faidhle}})',
+'search-result-score' => 'Buntainneas: $1%',
 'search-redirect' => '(ag ath-sheòladh $1)',
 'search-section' => '(earrann $1)',
 'search-suggest' => 'An e na leanas a bha fa-near dhut: $1',
@@ -1193,7 +1214,7 @@ Thoir sùil air na [[Special:WantedCategories|roinntean-seòrsa a thathar 'gan i
 'emailsend' => 'Cuir',
 
 # Watchlist
-'watchlist' => 'Mo chlàr-faire',
+'watchlist' => 'An clàr-faire',
 'mywatchlist' => 'An clàr-faire',
 'watchlistfor2' => 'Do $1 $2',
 'nowatchlist' => "Chan eil rud sam bith air a' chlàr-fhaire agad.",
index cee2df7..f34b8f2 100644 (file)
@@ -982,7 +982,7 @@ Isto pode acontecer porque estea a empregar un servizo de ''proxy'' anónimo def
 A área de texto superior contén o texto da páxina tal e como existe na actualidade.
 Os seus cambios móstranse na área inferior.
 Pode mesturar os seus cambios co texto existente.
-'''Só''' se gardará o texto na área superior cando prema \"{{int:savearticle}}\".",
+'''Só''' se gardará o texto na área superior cando prema en \"{{int:savearticle}}\".",
 'yourtext' => 'O seu texto',
 'storedversion' => 'Versión gardada',
 'nonunicodebrowser' => "'''Atención: O seu navegador non soporta o Unicode.'''
@@ -1306,7 +1306,7 @@ O [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} rexistro de borrad
 'search-interwiki-default' => 'Resultados en $1:',
 'search-interwiki-more' => '(máis)',
 'search-relatedarticle' => 'Relacionado',
-'mwsuggest-disable' => 'Deshabilitar as suxestións AJAX',
+'mwsuggest-disable' => 'Desactivar as suxestións de procura',
 'searcheverything-enable' => 'Procurar en todos os espazos de nomes',
 'searchrelated' => 'relacionado',
 'searchall' => 'todo',
@@ -1612,7 +1612,7 @@ Ha de ter menos {{PLURAL:$1|dun carácter|de $1 caracteres}}.',
 'action-sendemail' => 'enviar correos electrónicos',
 
 # Recent changes
-'nchanges' => '$1 {{PLURAL:$1|cambio|cambios}}',
+'nchanges' => '$1 {{PLURAL:$1|modificación|modificacións}}',
 'recentchanges' => 'Cambios recentes',
 'recentchanges-legend' => 'Opcións dos cambios',
 'recentchanges-summary' => 'Nesta páxina pode seguir as modificacións máis recentes feitas no wiki.',
@@ -2286,7 +2286,7 @@ O enderezo de correo electrónico que inseriu [[Special:Preferences|nas súas pr
 'usermessage-editor' => 'Editor das mensaxes do sistema',
 
 # Watchlist
-'watchlist' => 'A miña lista de vixilancia',
+'watchlist' => 'Lista de vixilancia',
 'mywatchlist' => 'Lista de vixilancia',
 'watchlistfor2' => 'De $1 $2',
 'nowatchlist' => 'Non ten elementos na súa lista de vixilancia.',
@@ -2442,7 +2442,7 @@ Vexa a [[Special:ProtectedPages|lista de páxinas protexidas]] se quere obter a
 'protect-legend' => 'Confirmar a protección',
 'protectcomment' => 'Motivo:',
 'protectexpiry' => 'Caducidade:',
-'protect_expiry_invalid' => 'O tempo de duración da protección non e válido.',
+'protect_expiry_invalid' => 'O tempo de duración da protección non é válido.',
 'protect_expiry_old' => 'O momento de remate da protección corresponde ao pasado.',
 'protect-unchain-permissions' => 'Desbloquear as opcións de protección adicionais',
 'protect-text' => "Aquí é onde pode ver e cambiar os niveis de protección da páxina chamada \"'''\$1'''\".",
@@ -2643,13 +2643,13 @@ Olle a [[Special:BlockList|lista de bloqueos]] para revisalo.',
 'ipb-blockingself' => 'Está a piques de se bloquear! Está seguro de querer facelo?',
 'ipb-confirmhideuser' => 'Está a piques de bloquear un usuario coa opción "agochar o usuario" activada. Isto suprime o nome de usuario de todas as listas e entradas de rexistro. Está seguro de querer facelo?',
 'ipb-edit-dropdown' => 'Editar os motivos de bloqueo',
-'ipb-unblock-addr' => 'Desbloquear a "$1"',
+'ipb-unblock-addr' => 'Desbloquear a $1',
 'ipb-unblock' => 'Desbloquear un usuario ou enderezo IP',
 'ipb-blocklist' => 'Ver os bloqueos vixentes',
-'ipb-blocklist-contribs' => 'Contribucións de "$1"',
-'unblockip' => 'Desbloquear o usuario',
+'ipb-blocklist-contribs' => 'Contribucións de $1',
+'unblockip' => 'Desbloquear un usuario',
 'unblockiptext' => 'Use o seguinte formulario para dar de novo acceso de escritura a un enderezo IP ou usuario que estea bloqueado.',
-'ipusubmit' => 'Retirar este bloqueo',
+'ipusubmit' => 'Retirar o bloqueo',
 'unblocked' => '[[User:$1|$1]] foi {{GENDER:$1|desbloqueado|desbloqueada}}',
 'unblocked-range' => '$1 foi desbloqueado',
 'unblocked-id' => 'O bloqueo $1 foi eliminado',
@@ -2693,7 +2693,7 @@ O motivo do bloqueo de $1 é: "$2"',
 'blocklogtext' => 'Este é o rexistro das accións de bloqueo e desbloqueo de usuarios.
 Non se listan os enderezos IP bloqueados automaticamente.
 Olle a [[Special:BlockList|lista de bloqueos]] para comprobar os bloqueos vixentes.',
-'unblocklogentry' => 'desbloqueou a "$1"',
+'unblocklogentry' => 'desbloqueou a $1',
 'block-log-flags-anononly' => 'só os usuarios anónimos',
 'block-log-flags-nocreate' => 'desactivada a creación de contas',
 'block-log-flags-noautoblock' => 'bloqueo automático deshabilitado',
@@ -2702,11 +2702,11 @@ Olle a [[Special:BlockList|lista de bloqueos]] para comprobar os bloqueos vixent
 'block-log-flags-angry-autoblock' => 'realzou o autobloqueo permitido',
 'block-log-flags-hiddenname' => 'nome de usuario agochado',
 'range_block_disabled' => 'A funcionalidade de administrador de crear rangos de bloqueos está deshabilitada.',
-'ipb_expiry_invalid' => 'Tempo de duración non válido.',
+'ipb_expiry_invalid' => 'O tempo de duración non é válido.',
 'ipb_expiry_temp' => 'Os bloqueos a nomes de usuario agochados deberían ser permanentes.',
-'ipb_hide_invalid' => 'Incapaz de suprimir esta conta; pode que teña moitas edicións.',
+'ipb_hide_invalid' => 'Non se pode suprimir esta conta; se cadra, ten moitas edicións.',
 'ipb_already_blocked' => '"$1" xa está bloqueado',
-'ipb-needreblock' => '"$1" xa está bloqueado. Quere cambiar as configuracións?',
+'ipb-needreblock' => '$1 xa está bloqueado. Quere cambiar as configuracións?',
 'ipb-otherblocks-header' => '{{PLURAL:$1|Outro bloqueo|Outros bloqueos}}',
 'unblock-hideuser' => 'Non pode desbloquear o usuario porque o seu nome foi agochado.',
 'ipb_cant_unblock' => 'Erro: Non se atopa o identificador do bloqueo $1. Posiblemente xa foi desbloqueado.',
@@ -2751,24 +2751,24 @@ Lembre [[Special:UnlockDB|eliminar o bloqueo]] unha vez completado o seu manteme
 # Move page
 'move-page' => 'Mover "$1"',
 'move-page-legend' => 'Mover páxina',
-'movepagetext' => "Ao usar o formulario de embaixo vai cambiar o nome da páxina, movendo todo o seu historial ao novo nome.
+'movepagetext' => "Ao usar o formulario inferior vai cambiar o nome da páxina, movendo todo o seu historial ao novo nome.
 O título vello vaise converter nunha páxina de redirección ao novo título.
 Pode actualizar automaticamente as redireccións que van dar ao título orixinal.
 Se escolle non facelo, asegúrese de verificar que non hai redireccións [[Special:DoubleRedirects|dobres]] ou [[Special:BrokenRedirects|crebadas]].
 Vostede é responsábel de asegurarse de que as ligazóns continúan a apuntar cara a onde se supón que deberían.
 
-Teña en conta que a páxina '''non''' será movida se xa existe unha páxina co novo título, a menos que sexa unha redirección e non teña historial de edicións.
+Teña en conta que a páxina '''non''' será trasladada se xa existe unha páxina co novo título, a menos que esta última sexa unha redirección e non teña historial de edicións.
 Isto significa que pode volver renomear unha páxina ao seu nome antigo se comete un erro, e que non pode sobrescribir unha páxina que xa existe.
 
 '''Atención!'''
 Este cambio nunha páxina popular pode ser drástico e inesperado;
 por favor, asegúrese de que entende as consecuencias disto antes de proseguir.",
-'movepagetext-noredirectfixer' => "Ao usar o formulario de embaixo vai cambiar o nome da páxina, movendo todo o seu historial ao novo nome.
+'movepagetext-noredirectfixer' => "Ao usar o formulario inferior vai cambiar o nome da páxina, movendo todo o seu historial ao novo nome.
 O título vello vaise converter nunha páxina de redirección ao novo título.
 Asegúrese de verificar que non hai redireccións [[Special:DoubleRedirects|dobres]] ou [[Special:BrokenRedirects|crebadas]].
 Vostede é responsábel de asegurarse de que as ligazóns continúan a apuntar cara a onde se supón que deberían.
 
-Teña en conta que a páxina '''non''' será movida se xa existe unha páxina co novo título, a menos que sexa unha redirección e non teña historial de edicións.
+Teña en conta que a páxina '''non''' será trasladada se xa existe unha páxina co novo título, a menos que esta última sexa unha redirección e non teña historial de edicións.
 Isto significa que pode volver renomear unha páxina ao seu nome antigo se comete un erro, e que non pode sobrescribir unha páxina que xa existe.
 
 '''Atención!'''
@@ -2920,7 +2920,7 @@ Gárdeo no seu disco duro e cárgueo aquí.',
 'importbadinterwiki' => 'Ligazón interwiki incorrecta',
 'importnotext' => 'Baleiro ou sen texto',
 'importsuccess' => 'A importación rematou!',
-'importhistoryconflict' => 'Existe un conflito no historial de revisións (por ter importado esta páxina antes)',
+'importhistoryconflict' => 'Existe un conflito no historial de revisións (se cadra, xa se importou esta páxina anteriormente)',
 'importnosources' => 'Non se defininiu ningunha fonte de importación transwiki e os envíos directos dos historiais están desactivados.',
 'importnofile' => 'Non se enviou ningún ficheiro de importación.',
 'importuploaderrorsize' => 'Fallou o envío do ficheiro de importación. O ficheiro é máis grande que o tamaño de envío permitido.',
@@ -3108,6 +3108,7 @@ Isto, probabelmente, se debe a unha ligazón cara a un sitio externo que está n
 'pageinfo-robot-noindex' => 'Non indexable',
 'pageinfo-views' => 'Número de visitas',
 'pageinfo-watchers' => 'Número de vixiantes da páxina',
+'pageinfo-few-watchers' => 'Menos de $1 {{PLURAL:$1|vixiante|vixiantes}}',
 'pageinfo-redirects-name' => 'Redireccións cara a esta páxina',
 'pageinfo-subpages-name' => 'Subpáxinas desta páxina',
 'pageinfo-subpages-value' => '$1 ($2 {{PLURAL:$2|redirección|redireccións}}; $3 {{PLURAL:$3|non-redirección|non-redireccións}})',
@@ -3918,7 +3919,7 @@ As imaxes móstranse na súa resolución completa; outros tipos de ficheiros in
 'tags-description-header' => 'Descrición completa do significado',
 'tags-hitcount-header' => 'Edicións etiquetadas',
 'tags-edit' => 'editar',
-'tags-hitcount' => '$1 {{PLURAL:$1|cambio|cambios}}',
+'tags-hitcount' => '$1 {{PLURAL:$1|modificación|modificacións}}',
 
 # Special:ComparePages
 'comparepages' => 'Comparar páxinas',
index 2f1ab98..a62ba4f 100644 (file)
@@ -1401,7 +1401,7 @@ $1",
 'search-interwiki-default' => 'תוצאות ב{{GRAMMAR:תחילית|$1}}:',
 'search-interwiki-more' => '(עוד)',
 'search-relatedarticle' => 'קשור',
-'mwsuggest-disable' => 'ביטול הצעות AJAX',
+'mwsuggest-disable' => 'ביטול הצעות חיפוש',
 'searcheverything-enable' => 'חיפוש בכל מרחבי השם',
 'searchrelated' => 'קשור',
 'searchall' => 'הכול',
@@ -2846,7 +2846,7 @@ $1',
 אם תבחרו לא לעשות זאת, אנא ודאו שאין [[Special:DoubleRedirects|הפניות כפולות]] או [[Special:BrokenRedirects|שבורות]].
 אתם אחראים לוודא שכל הקישורים ימשיכו להצביע למקום שאליו הם אמורים להצביע.
 
-ש×\99×\9e×\95 ×\9c×\91: ×\94×\93×£ '''×\9c×\90''' ×\99×\95×¢×\91ר ×\90×\9d ×\9b×\91ר ×\99ש ×\93×£ ×ª×\97ת ×\94ש×\9d ×\94×\97×\93ש, ×\90×\9c×\90 ×\90×\9d ×\94×\93×£ ×\94×\96×\94 הוא הפניה ואין לו היסטוריית עריכות קודמות.
+ש×\99×\9e×\95 ×\9c×\91: ×\94×\93×£ '''×\9c×\90''' ×\99×\95×¢×\91ר ×\90×\9d ×\9b×\91ר ×\99ש ×\93×£ ×ª×\97ת ×\94ש×\9d ×\94×\97×\93ש, ×\90×\9c×\90 ×\90×\9d ×\94×\93×£ ×\94שנ×\99 הוא הפניה ואין לו היסטוריית עריכות קודמות.
 פירוש הדבר שאפשר לשנות חזרה את שמו של דף לשם המקורי אם נעשתה טעות, ושלא ניתן לדרוס דף קיים.
 
 '''אזהרה!'''
@@ -3198,6 +3198,7 @@ $1',
 'pageinfo-robot-noindex' => 'לא יכול להיאסף למפתחות חיפוש',
 'pageinfo-views' => 'מספר הצפיות',
 'pageinfo-watchers' => 'מספר העוקבים אחר הדף',
+'pageinfo-few-watchers' => 'פחות מ{{PLURAL:$1|עוקב אחד|־$1 עוקבים}}',
 'pageinfo-redirects-name' => 'הפניות לדף זה',
 'pageinfo-subpages-name' => 'דפי־משנה של דף זה',
 'pageinfo-subpages-value' => '$1 ({{PLURAL:$2|הפניה אחת|$2 הפניות}}; {{PLURAL:$3|דף רגיל אחד|$3 דפים רגילים}})',
index 884fd10..e5884e0 100644 (file)
@@ -585,7 +585,7 @@ Njezabudź swoje [[Special:Preferences|nastajenja za {{GRAMMAR:akuzatiw|{{SITENA
 'gotaccount' => 'Maš hižo wužiwarske konto? $1.',
 'gotaccountlink' => 'Přizjewić',
 'userlogin-resetlink' => 'Přizjewjenske daty zabył?',
-'createaccountmail' => 'z mejlku',
+'createaccountmail' => 'Nachwilne přidatne hesło wužiwać a jo na slědowacu e-mejlowu adresu pósłać',
 'createaccountreason' => 'Přičina:',
 'badretype' => 'Hesle, kotrejž sy zapodał, so njekryjetej.',
 'userexists' => 'Wužiwarske mjeno, kotrež sy zapodał, so hižo wužiwa.
@@ -860,7 +860,8 @@ Lubiš nam tež, zo sy jón sam napisał abo ze zjawneje domejny abo z podobneho
 
 '''NJESKŁADUJ PŘINOŠKI Z COPYRIGHTOM BJEZ DOWOLNOSĆE!'''",
 'longpageerror' => "'''ZMYLK: Tekst, kotryž pospytuješ składować, je {{PLURAL:$1| jedyn kilobajt|$1 kilobajtaj|$1 kilobajty|$1 kilobajtow}} dołho, maksimalna wulkosć pak je {{PLURAL:$2|jedyn kilobajt|$1 kilobajtaj|$1 kilobajty|$1 kilobajtow}}.''' Njehodźi so składować.",
-'readonlywarning' => "'''KEDŹBU: Datowa banka bu wothladanja dla zawrjena, tohodla njemóžeš swoje změny nětko składować. Móžeš tekst do tekstoweje dataje přesunyć a jón za pozdźišo składować.'''
+'readonlywarning' => "'''KEDŹBU: Datowa banka bu wothladowanja dla zawrjena, tohodla njemóžeš swoje změny nětko składować.'''
+Móžeš tekst do tekstoweje dataje kopěrować a jón za pozdźišo składować.
 
 Administrator, kiž je ju zawrjena, je tutu přičinu podał: $1",
 'protectedpagewarning' => "'''KEDŹBU: Tuta strona bu zawrjena, tak zo jenož wužiwarjo z prawami administratora móža ju wobdźěłać.'''
@@ -946,7 +947,7 @@ Přičina za blokowanje, podata wot $3, je: ''$2''",
 'nohistory' => 'Njeje žanych staršich wersijow strony.',
 'currentrev' => 'Aktualna wersija',
 'currentrev-asof' => 'Aktualna wersija wot $1',
-'revisionasof' => 'Wersija z $1',
+'revisionasof' => 'Wersija wot $1',
 'revision-info' => 'Wersija wot $1 wužiwarja $2',
 'previousrevision' => '← Starša wersija',
 'nextrevision' => 'Nowša wersija →',
@@ -1104,7 +1105,7 @@ Zawěsć, zo tuta změna stawiznisku kontinuitu strony wobchowuje.',
 
 # Diffs
 'history-title' => '$1: Wersijowe stawizny',
-'difference-title' => '$1: Rozdźěl mjez wersijemi',
+'difference-title' => '$1: Rozdźěl mjez wersijomaj',
 'difference-title-multipage' => '$1 a $2: Rozdźěl mjez stronami',
 'difference-multipage' => '(Rozdźěl mjez stronami)',
 'lineno' => 'Rjadka $1:',
@@ -2055,7 +2056,7 @@ Znajmjeńša hłowna domena je trěbna, na přikład "*.org".<br />
 # Special:ActiveUsers
 'activeusers' => 'Lisćina aktiwnych wužiwarjow',
 'activeusers-intro' => 'To je lisćina wužiwarjow, kotřiž běchu aktiwni za {{PLURAL:$1|posledni dźeń|poslednjej $1 dnjej|poslednje $1 dny|poslednich $1 dnjow}}:',
-'activeusers-count' => '$1 {{PLURAL:$1|změna|změnje|změny|změnow}} w {{PLURAL:$3|zańdźenej dnju|zańdźenymaj $3 dnjomaj|zańdźenych $3 dnjach|zańdźenych $3 dnjach}}',
+'activeusers-count' => '$1 {{PLURAL:$1|akcija|akciji|akcije|akcijow}} w {{PLURAL:$3|zańdźenej dnju|zańdźenymaj $3 dnjomaj|zańdźenych $3 dnjach}}',
 'activeusers-from' => 'Wužiwarjow zwobraznić, započinajo z:',
 'activeusers-hidebots' => 'Boćiki schować',
 'activeusers-hidesysops' => 'Administratorow schować',
@@ -2117,7 +2118,7 @@ E-mejlowa adresa, kotruž sy w [[Special:Preferences|swojich wužiwarskich nasta
 'usermessage-editor' => 'Systemowy powěstnik',
 
 # Watchlist
-'watchlist' => 'wobkedźbowanki',
+'watchlist' => 'Wobkedźbowanki',
 'mywatchlist' => 'Wobkedźbowanki',
 'watchlistfor2' => 'Za wužiwarja $1 $2',
 'nowatchlist' => 'Nimaš žane strony w swojich wobkedźbowankach.',
@@ -2563,11 +2564,11 @@ Hlej [[Special:BlockList|lisćinu blokowanjow]], zo by zablokowanjow pruwował.'
 # Move page
 'move-page' => '$1 přesunyć',
 'move-page-legend' => 'Stronu přesunyć',
-'movepagetext' => 'Wužiwanje formulara deleka budźe stronu přemjenować, suwajo jeje cyłe stawizny pod nowe mjeno. Stary titl budźe daleposrědkowanje na nowy titl. Wotkazy na stary titl so njezměnja. Pruwuj za dwójnymi abo skóncowanymi daleposrědkowanjemi. Dyrbiš zaručić, zo wotkazy na stronu pokazuja, na kotruž dyrbja dowjesć.
+'movepagetext' => "Wužiwanje formulara deleka budźe stronu přemjenować, suwajo jeje cyłe stawizny pod nowe mjeno. Stary titl budźe daleposrědkowanje na nowy titl.  Móžeš dalesposrědkowanja, kotrež na prěnjotny titl pokazać, awtomatisce aktualizować. Pruwuj za [[Special:DoubleRedirects|dwójnymi]] abo [[Special:BrokenRedirects|skóncowanymi daleposrědkowanjemi]]. Dyrbiš zaručić, zo wotkazy na stronu pokazuja, na kotruž dyrbja dowjesć.
 
-Wobkedźbuj, zo strona so <b>nje</b> přesunje, jeli strona z nowym titlom hizo eksistuje, chibazo wona je prózdna abo dalesposrědkowanje a nima zašłe stawizny. To woznamjenja, zo móžeš stronu tam wróćo přemjenować, hdźež bu runje přemjenowana, jeli zmylk činiš a njemóžeš wobstejacu stronu přepisować.
+Wobkedźbuj, zo strona so '''nje'''přesunje, jeli strona z nowym titlom hizo eksistuje, chibazo poslednja je dalesposrědkowanje a nima zašłe stawizny. To woznamjenja, zo móžeš stronu tam wróćo přemjenować, hdźež bu runje přemjenowana, jeli zmylk činiš a njemóžeš wobstejacu stronu přepisować.
 
-<b>KEDŹBU!</b> Móže to drastiska a njewočakowana změna za woblubowanu stronu być; prošu budź sej wěsty, zo sćěwki rozumiš, prjedy hač pokročuješ.',
+'''Kedźbu!''' Móže to drastiska a njewočakowana změna za woblubowanu stronu być; prošu budź sej wěsty, zo sćěwki rozumiš, prjedy hač pokročuješ.",
 'movepagetext-noredirectfixer' => "Wužiwajo slědowacy formular, móžeš stronu přemjenować a wšě jich daty do stawiznow noweho titula přesunyć.
 Stary titul budźe dalesposrědkowanska strona k nowemu titulej.
 Skontroluj za [[Special:DoubleRedirects|dwójnymi]] abo [[Special:BrokenRedirects|wobškodźenymi dalesposrědkowanjemi]].
@@ -3642,7 +3643,7 @@ Wobrazy so połnym rozeznaću pokazuja, druhe datajowe typy so ze zwjazanym prog
 'specialpages-group-highuse' => 'Často wužiwane strony',
 'specialpages-group-pages' => 'Lisćiny stronow',
 'specialpages-group-pagetools' => 'Nastroje stronow',
-'specialpages-group-wiki' => 'Wikijowe daty a nastroje',
+'specialpages-group-wiki' => 'Daty a nastroje',
 'specialpages-group-redirects' => 'Daleposrědkowace specialne strony',
 'specialpages-group-spam' => 'Spamowe nastroje',
 
@@ -3739,6 +3740,7 @@ Wobrazy so połnym rozeznaću pokazuja, druhe datajowe typy so ze zwjazanym prog
 'logentry-newusers-newusers' => 'Wužiwarske konto $1 je so załožiło',
 'logentry-newusers-create' => 'Wužiwarske konto $1 je so załožiło',
 'logentry-newusers-create2' => '$1 załoži wužiwarske konto $3',
+'logentry-newusers-byemail' => 'Wužiwarske konto $3 je so wot $1 załožiło a hesło je so přez e-mejl pósłało.',
 'logentry-newusers-autocreate' => 'Konto $1 je so awtomatisce załožiło',
 'logentry-rights-rights' => '$1 změni skupinske čłonstwo za $3 z $4 do $5',
 'logentry-rights-rights-legacy' => '$1 změni skupinske čłonstwo za $3',
@@ -3797,6 +3799,7 @@ Hewak móžeš slědowacy jednory formular wužiwać. Twój komentar přida so s
 'api-error-ok-but-empty' => 'Nutřkowny zmylk: žana wotmołwa wot serwera.',
 'api-error-overwrite' => 'Přepisowanje eksistowaceje dataje njeje dowolene.',
 'api-error-stashfailed' => 'Nutřkowny zmylk: Serwer njemóžeše nachwilnu dataju składować.',
+'api-error-publishfailed' => 'Nutřkowny zmylk: Serwer njemóžeše nachwilnu dataju wozjewić.',
 'api-error-timeout' => 'Serwer njeje znutřka wočakowaneho časa wotmołwił.',
 'api-error-unclassified' => 'Njeznaty zmylk je wustupił.',
 'api-error-unknown-code' => 'Njeznaty zmylk: "$1"',
index 75aab89..c07fa9a 100644 (file)
@@ -320,7 +320,7 @@ $messages = array(
 'tog-hidepatrolled' => 'Az ellenőrzött szerkesztések elrejtése a friss változtatások lapon',
 'tog-newpageshidepatrolled' => 'Ellenőrzött lapok elrejtése az új lapok listájáról',
 'tog-extendwatchlist' => 'A figyelőlistán az összes változtatás látszódjon, ne csak az utolsó',
-'tog-usenewrc' => 'Fejlettebb friss változások használata (JavaScript-alapú)',
+'tog-usenewrc' => 'Szerkesztések csoportosítása oldal szerint a friss változtatásokban és a figyelőlistán (JavaScript-alapú)',
 'tog-numberheadings' => 'Fejezetcímek automatikus számozása',
 'tog-showtoolbar' => 'Szerkesztőeszközsor megjelenítése (JavaScript-alapú)',
 'tog-editondblclick' => 'A lapok szerkesztése dupla kattintásra (JavaScript-alapú)',
@@ -1334,7 +1334,7 @@ Ezt általában egy elavult, törölt oldalra mutató laptörténeti hivatkozás
 'search-interwiki-default' => '$1 találat',
 'search-interwiki-more' => '(több)',
 'search-relatedarticle' => 'Kapcsolódó',
-'mwsuggest-disable' => 'AJAX-alapú keresési javaslatok letiltása',
+'mwsuggest-disable' => 'Keresési javaslatok letiltása',
 'searcheverything-enable' => 'Keresés az összes névtérben',
 'searchrelated' => 'kapcsolódó',
 'searchall' => 'mind',
index 53fa533..aafbd4c 100644 (file)
@@ -276,6 +276,7 @@ $messages = array(
 'newwindow' => '(se aperi in un nove fenestra)',
 'cancel' => 'Cancellar',
 'moredotdotdot' => 'Plus...',
+'morenotlisted' => 'Alteres non listate…',
 'mypage' => 'Pagina',
 'mytalk' => 'Discussion',
 'anontalk' => 'Discussion pro iste adresse IP',
@@ -520,7 +521,7 @@ Consulta: $2',
 'actionthrottled' => 'Action limitate',
 'actionthrottledtext' => 'Como mesura anti-spam, tu es limitate de executar iste action troppo de vices durante un curte periodo de tempore, e tu ha excedite iste limite.
 Per favor reprova post alcun minutas.',
-'protectedpagetext' => 'Iste pagina ha essite protegite contra modificationes.',
+'protectedpagetext' => 'Iste pagina ha essite protegite pro impedir le modification o altere actiones.',
 'viewsourcetext' => 'Tu pote vider e copiar le codice-fonte de iste pagina:',
 'viewyourtext' => "Tu pote vider e copiar le fonte de '''tu modificationes''' de iste pagina:",
 'protectedinterface' => 'Iste pagina contine texto pro le interfacie del software de iste wiki, e es protegite pro impedir le abuso. Pro adder o modificar traductiones pro tote le wikis, per favor usa [//translatewiki.net/ translatewiki.net], le projecto de traduction de MediaWiki.',
@@ -579,7 +580,7 @@ Non oblida personalisar tu [[Special:Preferences|preferentias in {{SITENAME}}]].
 'gotaccount' => "Tu jam ha un conto? '''$1'''.",
 'gotaccountlink' => 'Aperir session',
 'userlogin-resetlink' => 'Datos de authentication oblidate?',
-'createaccountmail' => 'per e-mail',
+'createaccountmail' => 'Usar un contrasigno aleatori temporari e inviar lo al adresse de e-mail specificate hic infra',
 'createaccountreason' => 'Motivo:',
 'badretype' => 'Le duo contrasignos que tu scribeva non es identic.',
 'userexists' => 'Iste nomine de usator es jam in uso.
@@ -660,6 +661,7 @@ Per favor attende ante de probar lo novemente.',
 # E-mail sending
 'php-mail-error-unknown' => 'Error incognite in le function mail() de PHP',
 'user-mail-no-addy' => 'Tentava inviar e-mail sin adresse de e-mail.',
+'user-mail-no-body' => 'Tentava inviar e-mail con texto vacue o multo curte.',
 
 # Change password dialog
 'resetpass' => 'Cambiar contrasigno',
@@ -727,6 +729,7 @@ Contrasigno temporari: $2',
 'changeemail-oldemail' => 'Adresse de e-mail actual:',
 'changeemail-newemail' => 'Adresse de e-mail nove:',
 'changeemail-none' => '(nulle)',
+'changeemail-password' => 'Contrasigno de {{SITENAME}}:',
 'changeemail-submit' => 'Cambiar e-mail',
 'changeemail-cancel' => 'Cancellar',
 
@@ -901,10 +904,10 @@ In addition, tu nos garanti que tu es le autor de isto, o que tu lo ha copiate d
 '''Non submitte material subjecte a copyright sin autorisation expresse!'''",
 'longpageerror' => "'''Error: Le texto que tu submitteva occupa {{PLURAL:$1|un kilobyte|$1 kilobytes}}, excedente le maximo de {{PLURAL:$2|un kilobyte|$2 kilobytes}}.'''
 Illo non pote esser salveguardate.",
-'readonlywarning' => "'''Attention: Le base de datos ha essite blocate pro mantenentia, ergo tu non pote salveguardar tu modificationes in iste momento.'''
-Nos recommenda copiar-e-collar le texto in un file de texto e salveguardar lo pro plus tarde.
+'readonlywarning' => "'''Attention: Le base de datos ha essite blocate pro mantenentia. Tu non pote salveguardar tu modificationes in iste momento.'''
+Nos recommenda copiar-e-collar le texto in un file e salveguardar lo pro plus tarde.
 
-Le administrator qui lo blocava dava iste explication: $1",
+Le administrator qui ha blocate le base de datos ha fornite iste explication: $1",
 'protectedpagewarning' => "'''Attention:  Iste pagina ha essite protegite de sorta que solmente usatores con privilegios de administrator pote modificar lo.''' Le ultime entrata del registro es fornite hic infra pro referentia:",
 'semiprotectedpagewarning' => "'''Nota:''' Iste pagina ha essite protegite de maniera que solmente usatores registrate pote modificar lo. Le ultime entrata del registro es fornite hic infra pro referentia:",
 'cascadeprotectedwarning' => "'''Attention:''' Iste pagina ha essite protegite de maniera que solmente administratores pote modificar lo, proque illo es includite in le protection in cascada del sequente {{PLURAL:$1|pagina|paginas}}:",
@@ -1320,9 +1323,9 @@ Le operation non pote esser disfacite.',
 'prefs-emailconfirm-label' => 'Confirmation del e-mail:',
 'prefs-textboxsize' => 'Dimension del fenestra de modification',
 'youremail' => 'E-mail:',
-'username' => 'Nomine de usator:',
-'uid' => 'ID del usator:',
-'prefs-memberingroups' => 'Membro de {{PLURAL:$1|gruppo|gruppos}}:',
+'username' => '{{GENDER:$1|Nomine de usator}}:',
+'uid' => 'ID del {{GENDER:$1|usator}}:',
+'prefs-memberingroups' => '{{GENDER:$2|Membro}} de {{PLURAL:$1|gruppo|gruppos}}:',
 'prefs-registration' => 'Data de registration:',
 'yourrealname' => 'Nomine real:',
 'yourlanguage' => 'Lingua:',
@@ -2117,7 +2120,7 @@ Vide etiam le [[Special:WantedCategories|categorias desirate]].',
 'linksearch-ok' => 'Cercar',
 'linksearch-text' => 'Es possibile usar metacharacteres como in "*.wikipedia.org".
 Isto necessita specificar al minus le dominio de nivello superior, per exemplo "*.org".<br />
-Protocollos supportate: <code>$1</code> (http:// es assumite si nulle protocollo es specificate).',
+{{PLURAL:$2|Le protocollo|Protocollos}} supportate: <code>$1</code> (http:// es assumite si nulle protocollo es specificate).',
 'linksearch-line' => '$1 ligate ab $2',
 'linksearch-error' => 'Le metacharacteres pote apparer solmente al initio del nomine de host.',
 
@@ -2130,7 +2133,7 @@ Protocollos supportate: <code>$1</code> (http:// es assumite si nulle protocollo
 # Special:ActiveUsers
 'activeusers' => 'Lista de usatores active',
 'activeusers-intro' => 'Isto es un lista de usatores que habeva alcun typo de activitate intra le ultime $1 {{PLURAL:$1|die|dies}}.',
-'activeusers-count' => '$1 {{PLURAL:$1|modification|modificationes}} in le ultime {{PLURAL:$3|die|$3 dies}}',
+'activeusers-count' => '$1 {{PLURAL:$1|action|actiones}} in le ultime {{PLURAL:$3|die|$3 dies}}',
 'activeusers-from' => 'Presentar usatores a partir de:',
 'activeusers-hidebots' => 'Celar bots',
 'activeusers-hidesysops' => 'Celar administratores',
@@ -2196,7 +2199,7 @@ como le adresse del expeditor, de sorta que le destinatario potera responder te
 'usermessage-editor' => 'Messagero del systema',
 
 # Watchlist
-'watchlist' => 'Mi observatorio',
+'watchlist' => 'Observatorio',
 'mywatchlist' => 'Observatorio',
 'watchlistfor2' => 'De $1 $2',
 'nowatchlist' => 'Tu non ha paginas sub observation.',
@@ -2204,10 +2207,8 @@ como le adresse del expeditor, de sorta que le destinatario potera responder te
 'watchnologin' => 'Tu non ha aperite un session',
 'watchnologintext' => 'Tu debe [[Special:UserLogin|aperir un session]] pro modificar tu observatorio.',
 'addwatch' => 'Adder al observatorio',
-'addedwatchtext' => "Le pagina \"[[:\$1]]\" ha essite addite a tu [[Special:Watchlist|observatorio]].
-Le modificationes futur in iste pagina e in su pagina de discussion essera listate ibi,
-e le pagina apparera '''in litteras grasse''' in le [[Special:RecentChanges|lista de modificationes recente]] pro
-render lo plus facile de deteger.",
+'addedwatchtext' => 'Le pagina "[[:$1]]" ha essite addite a tu [[Special:Watchlist|observatorio]].
+Le modificationes futur in iste pagina e in le pagina de discussion associate essera listate in illo.',
 'removewatch' => 'Remover del observatorio',
 'removedwatchtext' => 'Le pagina "[[:$1]]" ha essite removite de [[Special:Watchlist|tu observatorio]].',
 'watch' => 'Observar',
@@ -2236,6 +2237,11 @@ render lo plus facile de deteger.",
 'enotif_mailer' => 'Systema de notification via e-mail de {{SITENAME}}',
 'enotif_reset' => 'Marcar tote le paginas como visitate',
 'enotif_impersonal_salutation' => 'Usator de {{SITENAME}}',
+'enotif_subject_deleted' => 'Le pagina $1 de {{SITENAME}} ha essite {{GENDER:$2|delite}} per $2',
+'enotif_subject_created' => 'Le pagina $1 de {{SITENAME}} ha essite {{GENDER:$2|create}} per $2',
+'enotif_subject_moved' => 'Le pagina $1 de {{SITENAME}} ha essite {{GENDER:$2|renominate}} per $2',
+'enotif_subject_restored' => 'Le pagina $1 de {{SITENAME}} ha essite {{GENDER:$2|restaurate}} per $2',
+'enotif_subject_changed' => 'Le pagina $1 de {{SITENAME}} ha essite {{GENDER:$2|modificate}} per $2',
 'enotif_lastvisited' => 'Vide $1 pro tote le modificationes depost tu ultime visita.',
 'enotif_lastdiff' => 'Vide $1 pro revider iste modification.',
 'enotif_anon_editor' => 'usator anonyme $1',
@@ -2361,9 +2367,9 @@ Ecce le configurationes actual del pagina '''$1''':",
 'protect-cascadeon' => 'Iste pagina es actualmente protegite proque illo es includite in le sequente {{PLURAL:$1|pagina, le qual|paginas, le quales}} ha activate le protection in cascada.
 Tu pote cambiar le nivello de protection de iste pagina, ma isto non cambiara le effecto del protection in cascada.',
 'protect-default' => 'Permitter tote le usatores',
-'protect-fallback' => 'Requirer permission de "$1"',
-'protect-level-autoconfirmed' => 'Blocar usatores nove e non registrate',
-'protect-level-sysop' => 'Administratores solmente',
+'protect-fallback' => 'Permitter solmente usatores con le permission de "$1"',
+'protect-level-autoconfirmed' => 'Permitter solmente usatores autoconfirmate',
+'protect-level-sysop' => 'Permitter solmente administratores',
 'protect-summary-cascade' => 'in cascada',
 'protect-expiring' => 'expira le $1 (UTC)',
 'protect-expiring-local' => 'expira le $1',
@@ -2464,7 +2470,7 @@ $1',
 'blanknamespace' => '(Principal)',
 
 # Contributions
-'contributions' => 'Contributiones del usator',
+'contributions' => 'Contributiones del {{GENDER:$1|usator}}',
 'contributions-title' => 'Contributiones del usator $1',
 'mycontris' => 'Contributiones',
 'contribsub2' => 'Pro $1 ($2)',
@@ -2671,16 +2677,16 @@ Pro blocar o disblocar le base de datos, le servitor web debe poter scriber a is
 # Move page
 'move-page' => 'Renominar $1',
 'move-page-legend' => 'Renominar pagina',
-'movepagetext' => "Per medio del formulario infra tu pote renominar un pagina, transferente tote su historia al nove nomine.
+'movepagetext' => "Per medio del formulario hic infra tu pote renominar un pagina, transferente tote su historia al nove nomine.
 Le titulo anterior devenira un pagina de redirection verso le nove titulo.
 Tu pote actualisar automaticamente le redirectiones que puncta verso le titulo original.
-Si tu prefere non facer isto, assecura te de reparar omne redirectiones [[Special:DoubleRedirects|duple]] o [[Special:BrokenRedirects|rupte]].
+Si tu prefere non facer isto, non oblida de reparar omne redirectiones [[Special:DoubleRedirects|duple]] o [[Special:BrokenRedirects|rupte]].
 Tu ha le responsabilitate de assecurar que le ligamines continua a punctar verso le paginas correcte.
 
-Nota que le pagina '''non''' essera renominate si existe ja un pagina sub le nove titulo, salvo si illo es vacue o un redirection e non ha un historia de modificationes passate.
-Isto vole dicer que tu pote renominar un pagina retro a su titulo original si tu ha committite un error, ben que tu non pote superscriber un pagina existente.
+Nota que le pagina '''non''' essera renominate si existe jam un pagina sub le nove titulo, excepte si iste es un redirection sin historia de modificationes passate.
+Isto te lassa le possibilitate de restaurar le titulo original de un pagina si tu ha committite un error, sin permitter te de supplantar un pagina existente.
 
-'''ATTENTION!'''
+'''Attention!'''
 Isto pote esser un cambio drastic e inexpectate pro un pagina popular;
 per favor assecura te de haber comprendite le consequentias de isto ante de continuar.",
 'movepagetext-noredirectfixer' => "Per medio del formulario infra tu pote renominar un pagina, transferente tote su historia al nove nomine.
index 48e283a..73cafbb 100644 (file)
@@ -464,6 +464,9 @@ $messages = array(
 'index-category' => 'Halaman yang diindeks',
 'noindex-category' => 'Halaman yang tidak diindeks',
 'broken-file-category' => 'Halaman dengan gambar rusak',
+'categoryviewer-pagedlinks' => '($1) ($2)',
+
+'linkprefix' => '/^(.*?)([a-zA-Z\\x80-\\xff]+)$/sD',
 
 'about' => 'Tentang',
 'article' => 'Halaman isi',
@@ -597,6 +600,9 @@ $1',
 'versionrequiredtext' => 'MediaWiki versi $1 dibutuhkan untuk menggunakan halaman ini. Lihat [[Special:Version|halaman versi]]',
 
 'ok' => 'OK',
+'pagetitle' => '$1 - {{SITENAME}}',
+'pagetitle-view-mainpage' => '{{SITENAME}}',
+'backlinksubtitle' => '← $1',
 'retrievedfrom' => 'Diperoleh dari "$1"',
 'youhavenewmessages' => 'Anda mempunyai $1 ($2).',
 'newmessageslink' => 'pesan baru',
@@ -607,6 +613,7 @@ $1',
 'newmessagesdifflinkplural' => '{{PLURAL:$1||}}perubahan terakhir',
 'youhavenewmessagesmulti' => 'Anda mendapat beberapa pesan baru pada $1',
 'editsection' => 'sunting',
+'editsection-brackets' => '[$1]',
 'editold' => 'sunting',
 'viewsourceold' => 'lihat sumber',
 'editlink' => 'sunting',
@@ -628,6 +635,7 @@ $1',
 'page-rss-feed' => 'Umpan RSS "$1"',
 'page-atom-feed' => 'Umpan Atom "$1"',
 'feed-atom' => 'Atom',
+'feed-rss' => 'RSS',
 'red-link-title' => '$1 (halaman belum tersedia)',
 'sort-descending' => 'Urutkan menurun',
 'sort-ascending' => 'Urutkan menaik',
@@ -775,6 +783,7 @@ Silakan tentukan nama yang lain.',
 'nocookieslogin' => "{{SITENAME}} menggunakan ''cookies'' untuk log penggunanya. ''Cookies'' pada penjelajah web Anda dimatikan. Silakan aktifkan dan coba lagi.",
 'nocookiesfornew' => 'Akun pengguna tidak dibuat karena kami tidak dapat memastikan sumbernya.
 Pastikan Anda telah mengaktifkan kuki, lalu muat ulang halaman ini dan coba lagi.',
+'nocookiesforlogin' => '{{int:nocookieslogin}}',
 'noname' => 'Nama pengguna yang Anda masukkan tidak sah.',
 'loginsuccesstitle' => 'Berhasil masuk log',
 'loginsuccess' => "'''Anda sekarang masuk log di {{SITENAME}} sebagai \"\$1\".'''",
@@ -1073,6 +1082,7 @@ Entri catatan terakhir disediakan di bawah untuk referensi:",
 'template-semiprotected' => '(pelindungan semi)',
 'hiddencategories' => 'Halaman ini adalah anggota dari {{PLURAL:$1|1 kategori tersembunyi|$1 kategori tersembunyi}}:',
 'edittools' => '<!-- Teks di sini akan dimunculkan di bawah isian suntingan dan pemuatan.-->',
+'edittools-upload' => '-',
 'nocreatetext' => '{{SITENAME}} telah membatasi pembuatan halaman-halaman baru.
 Anda dapat kembali dan menyunting halaman yang telah ada, atau silakan [[Special:UserLogin|masuk log atau membuat akun]].',
 'nocreate-loggedin' => 'Anda tak memiliki hak akses untuk membuat halaman baru.',
@@ -1132,7 +1142,7 @@ Beberapa templat akan diabaikan.',
 'undo-success' => 'Suntingan ini dapat dibatalkan. Tolong cek perbandingan di bawah untuk meyakinkan bahwa benar itu yang Anda ingin lakukan, lalu simpan perubahan tersebut untuk menyelesaikan pembatalan suntingan.',
 'undo-failure' => 'Suntingan ini tidak dapat dibatalkan karena konflik penyuntingan antara.',
 'undo-norev' => 'Suntingan ini tidak dapat dibatalkan karena halaman tidak ditemukan atau telah dihapuskan.',
-'undo-summary' => 'Membatalkan revisi $1 oleh [[Special:Contributions/$2|$2]] ([[User talk:$2|talk]])',
+'undo-summary' => 'Membatalkan revisi $1 oleh [[Special:Contributions/$2|$2]] ([[User talk:$2|bicara]])',
 
 # Account creation failure
 'cantcreateaccounttitle' => 'Akun tak dapat dibuat',
@@ -1294,6 +1304,7 @@ Pastikan bahwa perubahan ini tetap mempertahankan kontinuitas versi terdahulu ha
 'mergehistory-comment' => '[[:$1]] telah digabungkan ke [[:$2]]: $3',
 'mergehistory-same-destination' => 'Nama halaman sumber dan tujuan tidak boleh sama',
 'mergehistory-reason' => 'Alasan:',
+'mergehistory-revisionrow' => '$1 ($2) $3 . . $4 $5 $6',
 
 # Merge log
 'mergelog' => 'Log penggabungan',
@@ -1359,7 +1370,7 @@ Rinciannya dapat ditemukan di [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGE
 'search-interwiki-default' => 'Hasil $1:',
 'search-interwiki-more' => '(selanjutnya)',
 'search-relatedarticle' => 'Berkaitan',
-'mwsuggest-disable' => 'Non-aktifkan saran AJAX',
+'mwsuggest-disable' => 'Non-aktifkan saran pencarian',
 'searcheverything-enable' => 'Cari di semua ruang nama',
 'searchrelated' => 'berkaitan',
 'searchall' => 'semua',
@@ -1470,7 +1481,9 @@ Pengembalian preferensi tidak dapat dibatalkan.',
 'username' => '{{GENDER:$1|Nama pengguna}}:',
 'uid' => 'ID {{GENDER:$1|pengguna}}:',
 'prefs-memberingroups' => '{{GENDER:$2|Anggota}} {{PLURAL:$1|kelompok|kelompok}}:',
+'prefs-memberingroups-type' => '$1',
 'prefs-registration' => 'Waktu pendaftaran:',
+'prefs-registration-date-time' => '$1',
 'yourrealname' => 'Nama asli:',
 'yourlanguage' => 'Bahasa:',
 'yourvariant' => 'Varian bahasa isi:',
@@ -1520,6 +1533,7 @@ Jika Anda memberikannya, nama asli Anda akan digunakan untuk memberi pengenalan
 'saveusergroups' => 'Simpan kelompok pengguna',
 'userrights-groupsmember' => 'Anggota dari:',
 'userrights-groupsmember-auto' => 'Anggota implisit dari:',
+'userrights-groupsmember-type' => '$1',
 'userrights-groups-help' => 'Anda dapat mengubah kelompok pengguna ini:
 * Kotak dengan tanda cek merupakan kelompok pengguna yang bersangkutan
 * Kotak tanpa tanda cek berarti pengguna ini bukan anggota kelompok tersebut
@@ -1531,6 +1545,7 @@ Jika Anda memberikannya, nama asli Anda akan digunakan untuk memberi pengenalan
 'userrights-notallowed' => 'Akun Anda tidak berhak untuk menambahkan atau membuang hak pengguna.',
 'userrights-changeable-col' => 'Kelompok yang dapat Anda ubah',
 'userrights-unchangeable-col' => 'Kelompok yang tidak dapat Anda ubah',
+'userrights-irreversible-marker' => '$1*',
 
 # Groups
 'group' => 'Kelompok:',
@@ -1691,9 +1706,11 @@ Jika Anda memberikannya, nama asli Anda akan digunakan untuk memberi pengenalan
 'minoreditletter' => 'k',
 'newpageletter' => 'B',
 'boteditletter' => 'b',
+'unpatrolledletter' => '!',
 'number_of_watching_users_pageview' => '[$1 {{PLURAL:$1|pemantau|pemantau}}]',
 'rc_categories' => 'Batasi sampai kategori (dipisah dengan "|")',
 'rc_categories_any' => 'Apa pun',
+'rc-change-size' => '$1',
 'rc-change-size-new' => '$1 {{PLURAL:$1|bita|bita}} setelah perubahan',
 'newsectionsummary' => '/* $1 */ bagian baru',
 'rc-enhanced-expand' => 'Tampilkan rincian (memerlukan JavaScript)',
@@ -1817,6 +1834,20 @@ Penggunggahan berkas Java tidak diperbolehkan karena dapat menyebabkan pengabaia
 'watchthisupload' => 'Pantau berkas ini',
 'filewasdeleted' => 'Suatu berkas dengan nama ini pernah dimuat dan selanjutnya dihapus. Harap cek $1 sebelum memuat lagi berkas tersebut.',
 'filename-bad-prefix' => "Nama berkas yang Anda muat diawali dengan '''\"\$1\"''', yang merupakan nama non-deskriptif yang biasanya diberikan secara otomatis oleh kamera digital. Harap pilih nama lain yang lebih deskriptif untuk berkas Anda.",
+'filename-prefix-blacklist' => ' #<!-- biarkan baris ini seperti adanya --> <pre>
+# Contohnya sebagai berikut:
+#   * Semuanya dari karekter "#" sampai akhir baris ini adalah komentar
+#   * Setiap garis "_" adalah awalan untuk nama file khas yang diberikan secara otomatis oleh kamera digital
+CIMG # Casio
+DSC_ # Nikon
+DSCF # Fuji
+DSCN # Nikon
+DUW # beberapa model telpon seluler
+IMG # generik
+JD # Jenoptik
+MGP # Pentax
+PICT # lainnya.
+ #</pre> <!-- biarkan baris ini seperti adanya -->',
 'upload-success-subj' => 'Berhasil dimuat',
 'upload-success-msg' => 'Pengunggahan Anda dari [$2] berhasil. Hasilnya tersedia di sini: [[:{{ns:file}}:$1]]',
 'upload-failure-subj' => 'Masalah pengunggahan',
@@ -1995,7 +2026,8 @@ Mungkin Anda ingin menyunting keterangan pada [$2 halaman deskripsi berkas] di s
 'uploadnewversion-linktext' => 'Muatkan versi yang lebih baru dari berkas ini',
 'shared-repo-from' => 'dari $1',
 'shared-repo' => 'suatu repositori bersama',
-'filepage.css' => '/* CSS yang ditempatkan di sini disertakan pada halaman deskripsi berkas, juga disertakan pada klien wiki asing */',
+'shared-repo-name-wikimediacommons' => 'Wikimedia Commons',
+'filepage.css' => '/* CSS yang ditempatkan di sini disertakan pada halaman deskripsi berkas, juga disertakan pada klien wiki lain */',
 'upload-disallowed-here' => 'Anda tidak bisa menimpa berkas ini.',
 
 # File reversion
@@ -2174,6 +2206,7 @@ Harap perhatikan bahwa situs web lain mungkin memiliki pranala ke suatu berkas d
 # Book sources
 'booksources' => 'Sumber buku',
 'booksources-search-legend' => 'Cari di sumber buku',
+'booksources-isbn' => 'ISBN:',
 'booksources-go' => 'Tuju ke',
 'booksources-text' => 'Di bawah ini adalah daftar pranala ke situs lain yang menjual buku baru dan bekas, dan mungkin juga mempunyai informasi lebih lanjut mengenai buku yang sedang Anda cari:',
 'booksources-invalid-isbn' => 'ISBN yang diberikan tampaknya tidak valid; periksa kesalahan penyalinan dari sumber asli.',
@@ -2246,7 +2279,7 @@ Perlu sedikitnya satu domain tingkat atas, misalnya "*.org".<br />
 # Special:ActiveUsers
 'activeusers' => 'Daftar pengguna aktif',
 'activeusers-intro' => 'Berikut adalah daftar pengguna yang memiliki suatu bentuk aktivitas selama paling tidak $1 {{PLURAL:$1|hari|hari}} terakhir.',
-'activeusers-count' => '$1 {{PLURAL:$1|aktivitas|aktivitas}} dalam {{PLURAL:$3|hari|$3 hari}} terakhir',
+'activeusers-count' => '$1 {{PLURAL:$1|aktivitas|aktivitas}} dalam {{PLURAL:$3|hari|$3 hari}} terakhir',
 'activeusers-from' => 'Tampilkan pengguna mulai dari:',
 'activeusers-hidebots' => 'Sembunyikan bot',
 'activeusers-hidesysops' => 'Sembunyikan pengurus',
@@ -2261,6 +2294,8 @@ Perlu sedikitnya satu domain tingkat atas, misalnya "*.org".<br />
 'listgrouprights-rights' => 'Hak',
 'listgrouprights-helppage' => 'Help:Hak akses',
 'listgrouprights-members' => '(daftar anggota)',
+'listgrouprights-right-display' => '<span class="listgrouprights-granted">$1 <code>($2)</code></span>',
+'listgrouprights-right-revoked' => '<span class="listgrouprights-revoked">$1 <code>($2)</code></span>',
 'listgrouprights-addgroup' => 'Menambahkan {{PLURAL:$2|kelompok|kelompok}}: $1',
 'listgrouprights-removegroup' => 'Menghapus {{PLURAL:$2|kelompok|kelompok}}: $1',
 'listgrouprights-addgroup-all' => 'Menambahkan semua kelompok',
@@ -2306,6 +2341,7 @@ Alamat surel yang Anda masukkan di [[Special:Preferences|preferensi akun Anda]]
 # User Messenger
 'usermessage-summary' => 'Tinggalkan pesan sistem.',
 'usermessage-editor' => 'Penyampai pesan sistem',
+'usermessage-template' => 'MediaWiki:UserMessage',
 
 # Watchlist
 'watchlist' => 'Daftar pantauan',
@@ -2472,6 +2508,7 @@ Lihat [[Special:ProtectedPages|daftar halaman terlindungi]] untuk daftar perlind
 'protect-fallback' => 'Hanya untuk pengguna dengan izin  "$1"',
 'protect-level-autoconfirmed' => 'Hanya untuk pengguna terdaftar otomatis',
 'protect-level-sysop' => 'Hanya untuk pengurus',
+'protect-summary-desc' => '[$1=$2] ($3)',
 'protect-summary-cascade' => 'runtun',
 'protect-expiring' => 'kedaluwarsa $1 (UTC)',
 'protect-expiring-local' => 'kedaluwarsa $1',
@@ -2556,6 +2593,7 @@ Lihat [[Special:Log/delete|log penghapusan]] untuk data penghapusan dan pengemba
 $1',
 'undelete-show-file-confirm' => 'Apakah Anda yakin ingin melihat revisi yang telah dihapus dari berkas "<nowiki>$1</nowiki>" per $3, $2?',
 'undelete-show-file-submit' => 'Ya',
+'undelete-revisionrow' => '$1 $2 ($3) $4 . . $5 $6 $7',
 
 # Namespace form on various pages
 'namespace' => 'Ruang nama:',
@@ -2730,6 +2768,7 @@ Lihat [[Special:BlockList|daftar pemblokiran]] untuk semua pengguna yang saat in
 'proxyblocker-disabled' => 'Fitur ini sedang tidak diakfifkan.',
 'proxyblockreason' => 'Alamat IP Anda telah diblokir karena alamat IP Anda adalah proxy terbuka. Silakan hubungi penyedia jasa internet Anda atau dukungan teknis dan beritahukan mereka masalah keamanan serius ini.',
 'proxyblocksuccess' => 'Selesai.',
+'sorbs' => 'DNSBL',
 'sorbsreason' => 'Alamat IP anda terdaftar sebagai proxy terbuka di DNSBL.',
 'sorbs_create_account_reason' => 'Alamat IP anda terdaftar sebagai proxy terbuka di DNSBL. Anda tidak dapat membuat akun.',
 'cant-block-while-blocked' => 'Anda tidak dapat memblokir pengguna lain ketika Anda sendiri sedang diblokir.',
@@ -3039,18 +3078,23 @@ Simpan ke komputer Anda dan unggah ke sini.',
 'tooltip-summary' => 'Masukkan sebuah ringkasan pendek',
 
 # Stylesheets
-'common.css' => '/* CSS yang ada di sini akan diterapkan untuk semua kulit. */',
-'standard.css' => '/* CSS yang ada di sini akan diterapkan untuk kulit Standard. */',
-'nostalgia.css' => '/* CSS yang ada di sini akan diterapkan untuk kulit Nostalgia. */',
-'cologneblue.css' => '/* CSS yang ada di sini akan diterapkan untuk kulit Cologne Blue. */',
-'monobook.css' => '/* CSS yang ada di sini akan diterapkan untuk kulit Monobook. */',
-'myskin.css' => '/* CSS yang ada di sini akan diterapkan untuk kulit MySkin. */',
-'chick.css' => '/* CSS yang ada di sini akan diterapkan untuk kulit Chick. */',
-'simple.css' => '/* CSS yang ada di sini akan diterapkan untuk kulit Simple. */',
-'modern.css' => '/* CSS yang ada di sini akan diterapkan untuk kulit Modern. */',
-'vector.css' => '/* CSS yang ada di sini akan diterapkan untuk kulit Vector. */',
-'print.css' => '/* CSS yang ada di sini akan diterapkan untuk tampilan cetak. */',
+'common.css' => '/* CSS yang ada di sini akan diterapkan pada semua kulit. */',
+'standard.css' => '/* CSS yang ada di sini akan diterapkan pada kulit Standar. */',
+'nostalgia.css' => '/* CSS yang ada di sini akan diterapkan pada kulit Nostalgia. */',
+'cologneblue.css' => '/* CSS yang ada di sini akan diterapkan pada kulit Cologne Blue. */',
+'monobook.css' => '/* CSS yang ada di sini akan diterapkan pada kulit Monobook. */',
+'myskin.css' => '/* CSS yang ada di sini akan diterapkan pada kulit MySkin. */',
+'chick.css' => '/* CSS yang ada di sini akan diterapkan pada kulit Chick. */',
+'simple.css' => '/* CSS yang ada di sini akan diterapkan pada kulit Sederhana. */',
+'modern.css' => '/* CSS yang ada di sini akan diterapkan pada kulit Modern. */',
+'vector.css' => '/* CSS yang ada di sini akan diterapkan pada kulit Vektor. */',
+'print.css' => '/* CSS yang ada di sini akan diterapkan pada tampilan cetak. */',
 'handheld.css' => '/* CSS yang ada di sini akan diterapkan untuk tampilan piranti genggam yang dikonfigurasi di $wgHandheldStyle. */',
+'noscript.css' => '/* CSS di sini akan mempengaruhi pengguna dengan skrip Java non-aktif */',
+'group-autoconfirmed.css' => '/* CSS di sini hanya mempengaruhi pengguna terkonfirmasi otomatis */',
+'group-bot.css' => '/* CSS di sini hanya mempengaruhi bot */',
+'group-sysop.css' => '/* CSS di sini hanya mempengaruhi pengurus */',
+'group-bureaucrat.css' => '/* CSS di sini hanya mempengaruhi birokrat */',
 
 # Scripts
 'common.js' => '/* JavaScript yang ada di sini akan diterapkan untuk semua kulit. */',
@@ -3063,6 +3107,10 @@ Simpan ke komputer Anda dan unggah ke sini.',
 'simple.js' => '/* Semua JavaScript di sini akan dimuatkan untuk para pengguna yang menggunakan kulit Simple */',
 'modern.js' => '/* Semua JavaScript di sini akan dimuatkan untuk para pengguna yang menggunakan kulit Modern */',
 'vector.js' => '/* Semua JavaScript di sini akan dimuatkan untuk para pengguna yang menggunakan kulit Vector */',
+'group-autoconfirmed.js' => '/* Semua JavaScript di sini hanya dimuatkan untuk pengguna terkonfirmasi otomatis */',
+'group-bot.js' => '/* Semua JavaScript di sini hanya dimuatkan untuk bot */',
+'group-sysop.js' => '/* Semua JavaScript di sini hanya dimuatkan untuk pengurus */',
+'group-bureaucrat.js' => '/* Semua JavaScript di sini hanya dimuatkan untuk birokrat */',
 
 # Metadata
 'notacceptable' => 'Server wiki tidak dapat menyediakan data dalam format yang dapat dibaca oleh client Anda.',
@@ -3107,6 +3155,7 @@ Ini mungkin disebabkan oleh pranala ke situs luar yang termasuk dalam daftar hit
 'pageinfo-views' => 'Jumlah penampilan',
 'pageinfo-watchers' => 'Jumlah pemantau halaman',
 'pageinfo-redirects-name' => 'Pengalihan ke halaman ini',
+'pageinfo-redirects-value' => '$1',
 'pageinfo-subpages-name' => 'Subhalaman halaman ini',
 'pageinfo-subpages-value' => '$1 ($2 {{PLURAL:$2|pengalihan|pengalihan}}; $3 {{PLURAL:$3|non-pengalihan|non-pengalihan}})',
 'pageinfo-firstuser' => 'Pembuat halaman',
@@ -3136,7 +3185,14 @@ Ini mungkin disebabkan oleh pranala ke situs luar yang termasuk dalam daftar hit
 
 # Skin names
 'skinname-standard' => 'Klasik',
+'skinname-nostalgia' => 'Nostalgia',
+'skinname-cologneblue' => 'Biru Köln',
+'skinname-monobook' => 'MonoBook',
+'skinname-myskin' => 'MySkin',
+'skinname-chick' => 'Chick',
 'skinname-simple' => 'Sederhana',
+'skinname-modern' => 'Modern',
+'skinname-vector' => 'Vektor',
 
 # Patrolling
 'markaspatrolleddiff' => 'Tandai telah dipatroli',
@@ -3176,6 +3232,7 @@ $1',
 Jika dijalankan, sistem Anda akan berisiko terserang.",
 'imagemaxsize' => "Batas ukuran gambar:<br />''(untuk halaman deskripsi berkas)''",
 'thumbsize' => 'Ukuran miniatur:',
+'widthheight' => '$1 × $2',
 'widthheightpage' => '$1 × $2, $3 {{PLURAL:$3|halaman|halaman}}',
 'file-info' => 'ukuran berkas: $1, tipe MIME: $2',
 'file-info-size' => '$1 × $2 piksel, ukuran berkas: $3, tipe MIME: $4',
@@ -3209,9 +3266,11 @@ Jika dijalankan, sistem Anda akan berisiko terserang.",
 'sp-newimages-showfrom' => 'Tampilkan berkas baru dimulai dari $2, $1',
 
 # Video information, used by Language::formatTimePeriod() to format lengths in the above messages
-'seconds-abbrev' => '$1d',
-'minutes-abbrev' => '$1m',
-'hours-abbrev' => '$1j',
+'video-dims' => '$1, $2 × $3',
+'seconds-abbrev' => '$1 d',
+'minutes-abbrev' => '$1 mnt',
+'hours-abbrev' => '$1 j',
+'days-abbrev' => '$1 h',
 'seconds' => '{{PLURAL:$1|$1 detik|$1 detik}}',
 'minutes' => '{{PLURAL:$1|$1 menit|$1 menit}}',
 'hours' => '{{PLURAL:$1|$1 jam|$1 jam}}',
@@ -3228,6 +3287,37 @@ Hanya butir daftar (baris yang diawali dengan tanda *) yang diperhitungkan.
 Pranala pertama pada suatu baris haruslah pranala ke berkas yang buruk.
 Pranala-pranala selanjutnya pada baris yang sama dianggap sebagai pengecualian, yaitu halaman yang dapat menampilkan berkas tersebut.',
 
+/*
+Short names for language variants used for language conversion links.
+To disable showing a particular link, set it to 'disable', e.g.
+'variantname-zh-sg' => 'disable',
+Variants for Chinese language
+*/
+'variantname-zh-hans' => 'hans',
+'variantname-zh-hant' => 'hant',
+'variantname-zh-cn' => 'cn',
+'variantname-zh-tw' => 'tw',
+'variantname-zh-hk' => 'hk',
+'variantname-zh-mo' => 'mo',
+'variantname-zh-sg' => 'sg',
+'variantname-zh-my' => 'my',
+'variantname-zh' => 'zh',
+
+# Variants for Gan language
+'variantname-gan-hans' => 'hans',
+'variantname-gan-hant' => 'hant',
+'variantname-gan' => 'gan',
+
+# Variants for Serbian language
+'variantname-sr-ec' => 'sr-ec',
+'variantname-sr-el' => 'sr-el',
+'variantname-sr' => 'sr',
+
+# Variants for Kazakh language
+'variantname-kk-kz' => 'kk-kz',
+'variantname-kk-tr' => 'kk-tr',
+'variantname-kk-cn' => 'kk-cn',
+
 # Metadata
 'metadata' => 'Metadata',
 'metadata-help' => 'Berkas ini mengandung informasi tambahan yang mungkin ditambahkan oleh kamera digital atau pemindai yang digunakan untuk membuat atau mendigitalisasi berkas. Jika berkas ini telah mengalami modifikasi, rincian yang ada mungkin tidak secara penuh merefleksikan informasi dari gambar yang sudah dimodifikasi ini.',
@@ -3248,6 +3338,8 @@ Data lain akan disembunyikan secara bawaan.
 * gpslatitude
 * gpslongitude
 * gpsaltitude',
+'metadata-langitem' => "'''$2:''' $1",
+'metadata-langitem-default' => '$1',
 
 # EXIF tags
 'exif-imagewidth' => 'Lebar',
@@ -3295,6 +3387,7 @@ Data lain akan disembunyikan secara bawaan.
 'exif-exposuretime' => 'Waktu pajanan',
 'exif-exposuretime-format' => '$1 detik ($2)',
 'exif-fnumber' => 'Nilai F',
+'exif-fnumber-format' => 'f/$1',
 'exif-exposureprogram' => 'Program pajanan',
 'exif-spectralsensitivity' => 'Sensitivitas spektral',
 'exif-isospeedratings' => 'Rating kecepatan ISO',
@@ -3308,6 +3401,7 @@ Data lain akan disembunyikan secara bawaan.
 'exif-lightsource' => 'Sumber cahaya',
 'exif-flash' => 'Kilas',
 'exif-focallength' => 'Jarak fokus lensa',
+'exif-focallength-format' => '$1 mm',
 'exif-subjectarea' => 'Wilayah subjek',
 'exif-flashenergy' => 'Energi kilas',
 'exif-focalplanexresolution' => 'Resolusi bidang fokus X',
@@ -3362,6 +3456,7 @@ Data lain akan disembunyikan secara bawaan.
 'exif-gpsareainformation' => 'Nama wilayah GPS',
 'exif-gpsdatestamp' => 'Tanggal GPS',
 'exif-gpsdifferential' => 'Koreksi diferensial GPS',
+'exif-coordinate-format' => '$1° $2′ $3″ $4',
 'exif-jpegfilecomment' => 'Komentar berkas JPEG',
 'exif-keywords' => 'Kata kunci',
 'exif-worldregioncreated' => 'Wilayah dunia tempat pengambilan gambar',
@@ -3427,15 +3522,37 @@ Data lain akan disembunyikan secara bawaan.
 'exif-originalimageheight' => 'Tinggi gambar sebelum dipotong',
 'exif-originalimagewidth' => 'Lebar gambar sebelum dipotong',
 
+# Make & model, can be wikified in order to link to the camera and model name
+'exif-contact-value' => '$1
+
+$2
+<div class="adr">
+$3
+
+$4, $5 - $6, $7
+</div>
+$8',
+'exif-subjectnewscode-value' => '$2 ($1)',
+
 # EXIF attributes
 'exif-compression-1' => 'Tak terkompresi',
 'exif-compression-2' => 'CCITT Group 3 1-Dimensional Modified Huffman RLE',
 'exif-compression-3' => 'CCITT Group 3 fax encoding',
 'exif-compression-4' => 'CCITT Group 4 fax encoding',
+'exif-compression-5' => 'LZW',
+'exif-compression-6' => 'JPEG (lama)',
+'exif-compression-7' => 'JPEG',
+'exif-compression-8' => 'Turunan (Adobe)',
+'exif-compression-32773' => 'PackBits (Macintosh RLE)',
+'exif-compression-32946' => 'Turunan (PKZIP)',
+'exif-compression-34712' => 'JPEG2000',
 
 'exif-copyrighted-true' => 'Berhak cipta',
 'exif-copyrighted-false' => 'Domain publik',
 
+'exif-photometricinterpretation-2' => 'RGB',
+'exif-photometricinterpretation-6' => 'YCbCr',
+
 'exif-unknowndate' => 'Tanggal tak diketahui',
 
 'exif-orientation-1' => 'Normal',
@@ -3450,9 +3567,19 @@ Data lain akan disembunyikan secara bawaan.
 'exif-planarconfiguration-1' => 'format chunky',
 'exif-planarconfiguration-2' => 'format planar',
 
+'exif-xyresolution-i' => '$1 dpi',
+'exif-xyresolution-c' => '$1 dpc',
+
+'exif-colorspace-1' => 'sRGB',
 'exif-colorspace-65535' => 'Tidak dikalibrasi',
 
 'exif-componentsconfiguration-0' => 'tak tersedia',
+'exif-componentsconfiguration-1' => 'Y',
+'exif-componentsconfiguration-2' => 'Cb',
+'exif-componentsconfiguration-3' => 'Cr',
+'exif-componentsconfiguration-4' => 'R',
+'exif-componentsconfiguration-5' => 'G',
+'exif-componentsconfiguration-6' => 'B',
 
 'exif-exposureprogram-0' => 'Tak terdefinisi',
 'exif-exposureprogram-1' => 'Manual',
@@ -3490,6 +3617,10 @@ Data lain akan disembunyikan secara bawaan.
 'exif-lightsource-17' => 'Cahaya standar A',
 'exif-lightsource-18' => 'Cahaya standar B',
 'exif-lightsource-19' => 'Cahaya standar C',
+'exif-lightsource-20' => 'D55',
+'exif-lightsource-21' => 'D65',
+'exif-lightsource-22' => 'D75',
+'exif-lightsource-23' => 'D50',
 'exif-lightsource-24' => 'studio ISO tungsten',
 'exif-lightsource-255' => 'Sumber cahaya lain',
 
@@ -3615,6 +3746,8 @@ Data lain akan disembunyikan secara bawaan.
 
 'exif-isospeedratings-overflow' => 'Lebih dari 65535',
 
+'exif-maxaperturevalue-value' => '$1 APEX (f/$2)',
+
 'exif-iimcategory-ace' => 'Seni, budaya, dan hiburan',
 'exif-iimcategory-clj' => 'Kejahatan dan hukum',
 'exif-iimcategory-dis' => 'Bencana dan kecelakaan',
@@ -3726,6 +3859,8 @@ Silakan konfirmasi jika Anda ingin membuat ulang halaman ini.",
 'confirmrecreate-noreason' => 'Pengguna [[User:$1|$1]] ([[User talk:$1|bicara]]) telah menghapus halaman ini setelah Anda mulai menyunting. Harap konfirmasikan bahwa Anda ingin membuat ulang halaman ini.',
 'recreate' => 'Buat ulang',
 
+'unit-pixel' => 'px',
+
 # action=purge
 'confirm_purge_button' => 'OK',
 'confirm-purge-top' => 'Hapus singgahan halaman ini?',
@@ -3737,6 +3872,15 @@ Silakan konfirmasi jika Anda ingin membuat ulang halaman ini.",
 'confirm-unwatch-button' => 'OK',
 'confirm-unwatch-top' => 'Hapus halaman ini dari daftar pantauan Anda?',
 
+# Separators for various lists, etc.
+'semicolon-separator' => ';&#32;',
+'comma-separator' => ',&#32;',
+'colon-separator' => ':&#32;',
+'autocomment-prefix' => '-&#32;',
+'pipe-separator' => '&#32;|&#32;',
+'word-separator' => '&#32;',
+'ellipsis' => '...',
+
 # Multipage image navigation
 'imgmultipageprev' => '&larr; halaman sebelumnya',
 'imgmultipagenext' => 'halaman selanjutnya &rarr;',
@@ -3842,6 +3986,7 @@ Anda juga dapat [[Special:EditWatchlist|menggunakan penyunting standar Anda]].',
 
 # Signatures
 'signature' => '[[{{ns:user}}:$1|$2]] ([[{{ns:user_talk}}:$1|bicara]])',
+'timezone-utc' => 'UTC',
 
 # Core parser functions
 'unknown_extension_tag' => 'Tag ekstensi tidak dikenal "$1"',
@@ -3855,6 +4000,7 @@ Anda juga dapat [[Special:EditWatchlist|menggunakan penyunting standar Anda]].',
 'version-variables' => 'Variabel',
 'version-antispam' => 'Pencegahan spam',
 'version-skins' => 'Kulit',
+'version-api' => 'API',
 'version-other' => 'Lain-lain',
 'version-mediahandlers' => 'Penanganan media',
 'version-hooks' => 'Kait',
@@ -3864,6 +4010,7 @@ Anda juga dapat [[Special:EditWatchlist|menggunakan penyunting standar Anda]].',
 'version-hook-name' => 'Nama kait',
 'version-hook-subscribedby' => 'Dilanggani oleh',
 'version-version' => '(Versi $1)',
+'version-svn-revision' => '(r$2)',
 'version-license' => 'Lisensi',
 'version-poweredby-credits' => "Wiki ini didukung oleh '''[//www.mediawiki.org/ MediaWiki]''', hak cipta © 2001-$1 $2.",
 'version-poweredby-others' => 'lainnya',
@@ -3879,6 +4026,8 @@ Anda seharusnya telah menerima [{{SERVER}}{{SCRIPTPATH}}/COPYING salinan Lisensi
 'version-entrypoints' => 'URL titik entri',
 'version-entrypoints-header-entrypoint' => 'Titik entri',
 'version-entrypoints-header-url' => 'URL',
+'version-entrypoints-articlepath' => '[https://www.mediawiki.org/wiki/Manual:$wgArticlePath Artikel path]',
+'version-entrypoints-scriptpath' => '[https://www.mediawiki.org/wiki/Manual:$wgScriptPath Skrip path]',
 
 # Special:FilePath
 'filepath' => 'Lokasi berkas',
index df300c1..6fff6a9 100644 (file)
@@ -793,10 +793,10 @@ Kasta met nga ikarim kadakami a bukodmo a sinurat wenno gapuanan daytoy, wenno t
 '''Saan a mangipan iti adda ti karbenganna a panagpablaak nga obra no awan ti  pammalubos!'''",
 'longpageerror' => "'''Biddut: Ti testo nga intedmo ket {{PLURAL:$1|maysa a kilobyte|$1 kil-kilobyte}} a katiddog, nga at-atiddog ngem ti kangatuan iti  {{PLURAL:$2|maysa a kilobyte|$2 kil-kilobyte}}.'''
 Isu ti gapuna a saan a maidulin.",
-'readonlywarning' => "'''Ballaag: Narikepan ti database para iti panagtaripatu, saanmo a mabalin nga idulin dagita inurnosmo tattan.'''
-No kayatmo i \"cut-n-paste\" mo dagiti testo iti testo a papeles ken idulinmo no madamdama.
+'readonlywarning' => "'''Ballaag: Narikepan ti database tapno mataripatu, isu a saanmo a mabalin nga idulin dagita inurnosmo tattan.'''
+Mabalinmo ti agkopia ken agikabil ti testom iti maysa a testo a papeles ken idulinmo para iti panagusar no madamdama.
 
-Ti administrador a nangrikep ket saan a nangted ti palawag: \$1",
+Ti administrador a nangrikep ket nangited iti daytoy a palawag: $1",
 'protectedpagewarning' => "'''Ballaag:  Daytoy a panid ket nasalakniban tapno dagiti laeng agar-aramat nga adda ti gundaway nga administrador ti makaurnos ditoy.'''
 Ti nakaudi a naikabil a listaan ket adda dita baba tapno usaren a  reperensia:",
 'semiprotectedpagewarning' => "'''Pakaammo:'''Nasalakniban daytoy a panid tapno dagiti laeng nakarehistro nga agar-aramat ti makaurnos ditoy.
@@ -2014,7 +2014,7 @@ Masapul ti kangatuan a pagturayan, a kaspagarigan "*.org".<br />
 # Special:ActiveUsers
 'activeusers' => 'Listaan dagiti nasiglat nga agar-aramat',
 'activeusers-intro' => 'Daytoy ti listaan dagiti agar-aramat nga adda inararamidda kadagiti napalabas a $1 {{PLURAL:$1|nga aldaw|nga alaldaw}}.',
-'activeusers-count' => '$1 {{PLURAL:$1|nga inurnos|kadagiti inurnos}} idi kalpasan ti  {{PLURAL:$3|nga aldaw|$3 nga alaldaw}}',
+'activeusers-count' => '$1 {{PLURAL:$1|a tignay|tigtignay}} idi kalpasan ti {{PLURAL:$3|nga aldaw|$3 nga alaldaw}}',
 'activeusers-from' => 'Iparang dagiti agar-aramat a mangrugi iti:',
 'activeusers-hidebots' => 'Ilemmeng dagiti bot',
 'activeusers-hidesysops' => 'Ilemmeng dagiti administrador',
@@ -2077,7 +2077,7 @@ Ti e-surat nga inkabilmo idiay  [[Special:Preferences|kakaykayatam]] ket agparan
 'usermessage-editor' => 'Mensahero iti sistema',
 
 # Watchlist
-'watchlist' => 'Bambantayak',
+'watchlist' => 'Bambantayan',
 'mywatchlist' => 'Bambantayan',
 'watchlistfor2' => 'Para iti $1 $2',
 'nowatchlist' => 'Awan ti banag iti listaan dagiti bambantayam.',
@@ -2085,8 +2085,8 @@ Ti e-surat nga inkabilmo idiay  [[Special:Preferences|kakaykayatam]] ket agparan
 'watchnologin' => 'Saan a nakastrek',
 'watchnologintext' => 'Masapul a [[Special:UserLogin|nakastrekka]] tapno mabaliwam dagiti bambantayam a panid.',
 'addwatch' => 'Inayon iti bambantayan',
-'addedwatchtext' => "Nainayonen ti panid iti \"[[:\$1]]\" iti [[Special:Watchlist|listaan ti bambantayam]].
-Mailistanto ditoy dagiti pinagsukat daytoy a panid iti masakbayan agraman ti kanaigna a panid-tungtongan, ket agparang ti panid a kas '''napuskol''' iti [[Special:RecentChanges|listaan ti naudi a balbaliw]] tapno nalaklaka a malasin.",
+'addedwatchtext' => 'Ti panid iti "[[:$1]]" ket nainayonen idiay [[Special:Watchlist|listaan ti bambantayam]].
+Dagiti masakbayan a panagsukat iti daytoy a panid ken dagiti mainaig a tungtunganna a panid ket mailistanto idiay.',
 'removewatch' => 'Ikkaten dita bambantayan',
 'removedwatchtext' => 'Daytoy a panid  "[[:$1]]" ket naikkat idiay [[Special:Watchlist|bambantayam]].',
 'watch' => 'bantayan',
@@ -2245,9 +2245,9 @@ Dagitoy dagiti agdama a kasasaad ti panid a '''$1''':",
 'protect-cascadeon' => 'Daytoy a panid ket agdama a  nasalakniban gapu ta nairaman kadagiti sumaganad a {{PLURAL:$1|panid, nga addaan|pampanid, nga addaan}} ti sipapakat a salaknib ti amin-amin.
 Mabalinmo a sukatan ti lessaad ti salaknib daytoy a panid, ngem saanna a tignayen ti salaknib nga amin-amin.',
 'protect-default' => 'Palubosan amin nga agar-aramat',
-'protect-fallback' => 'Masapul ti "$1" a pammalubos',
-'protect-level-autoconfirmed' => 'Serraan dagiti baro ken saan a nakarehistro nga agar-aramat',
-'protect-level-sysop' => 'Dagiti administrador laeng',
+'protect-fallback' => 'Palubosan laeng dagiti agar-aramat nga adda iti "$1" a pammalubos',
+'protect-level-autoconfirmed' => 'Palubosan laeng dagiti automatiko a napasingkedan nga agar-aramat',
+'protect-level-sysop' => 'Palubosan laeng dagiti administrador',
 'protect-summary-cascade' => 'agsariap',
 'protect-expiring' => 'agpaso inton $1 (UTC)',
 'protect-expiring-local' => 'agpaso $1',
@@ -2549,18 +2549,18 @@ Ti agserra ken aglukat iti database, masapul a masuratan ti web server.',
 # Move page
 'move-page' => 'Iyalis ti $1',
 'move-page-legend' => 'Iyalis ti panid',
-'movepagetext' => "Ti panagusar ti kinabuklan dita baba, ket panaganan ti panid, iyalis na amin ti pakasaritaan na idiay baro a nagan.
-Ti daan a titulo ket agbalin baw-ing a panid idiay baro a titulo.
-Mapabarom a kas automatiko dagiti baw-ing a nakatudo dita kasigud a titulo.
-No agpili ka a saan mo a kayat, pasaraduam nga kitaen ti [[Special:DoubleRedirects|doble]] wenno [[Special:BrokenRedirects|nadadael a baw-ing]].
-Rebbengem ti mangpatalged nga amin a panilpo ket agtultuloy a nakatudo iti nasken a papananda.
+'movepagetext' => "Ti panagusar ti kinabuklan dita baba, ket mangnagan manen ti panid, a mangiyalis amin ti pakasaritaanna idiay baro a nagan.
+Ti daan a titulo ket agbalin baw-ing a panid idiay baro a titulo.
+Mapabarom a kas automatiko dagiti baw-ing a nakatudo dita kasisigud a titulo.
+No agpilika a saanmo a kayat, pasaraduam a kitaen ti [[Special:DoubleRedirects|doble]] wenno [[Special:BrokenRedirects|nadadael a baw-ing]].
+Renbbengmo ti mangpatalged nga amin a silpo ket agtultuloy a nakatudo iti nasken a papananda.
 
-Laglagipen a ti panid ket '''saan''' a maiyalis no addan sigud a panid iti baro a titulo, malaksid no awan linaonna wenno no maysa a baw-ing a panid ken awan ti panagbaliw iti pakasaritaan ti napalabas. 
+Laglagipen a ti panid ket '''saan''' a maiyalis no addan sigud a panid iti baro a titulo, malaksid no daytoy ket maysa a baw-ing ken awan ti napalabas a pakasaritaan ti panag-urnos. 
 Kayat a sawen daytoy a mabalinmo a suktan ti nagan ti maysa a panid manipud iti punto ti pannakasukat ti nagan no nagbiddutka, ken saan mo a mabalin a suratan manen ti addaan a panid.
 
 '''Ballaag!'''
 Mabalin a maysa daytoy a nakaro ken saan a bigla a panagbaliw iti maysa a nasikat a panid;
-pangngaasim ta pasingkedam a maawatam ti ibunga dayoty sakbay nga agtuloyka a mangbaliw.",
+pangngaasim a pasingkedam a maawatam ti ibunga daytoy sakbay nga agtuloyka a mangbaliw.",
 'movepagetext-noredirectfixer' => "Ti panagusar ti kinabuklan dita baba, ket panaganan ti panid, iyalis na amin ti pakasaritaan na idiay baro a nagan.
 Ti daan a titulo ket agbalin baw-ing a panid idiay baro a titulo.
 Pasaruduam a kitaen ti [[Special:DoubleRedirects|doble]] wenno [[Special:BrokenRedirects|nadadael a baw-ing]].
@@ -3627,7 +3627,7 @@ Dagiti imahen ket agparang iti kadakkelan a resolusion, dagiti sabali a kita ti
 'specialpages-group-highuse' => 'Adu ti panaka-usar a pampanid',
 'specialpages-group-pages' => 'Listaan dagiti panid',
 'specialpages-group-pagetools' => 'Ramramit ti panid',
-'specialpages-group-wiki' => 'Linaon ti wiki ken ramramit',
+'specialpages-group-wiki' => 'Datos ken ramramit',
 'specialpages-group-redirects' => 'Maibawbaw-ing dagiti espesial a pampanid',
 'specialpages-group-spam' => 'Ramramit kontra spam',
 
index 732549b..3cc027e 100644 (file)
@@ -367,6 +367,7 @@ $messages = array(
 'newwindow' => '(opnast í nýjum glugga)',
 'cancel' => 'Hætta við',
 'moredotdotdot' => 'Meira...',
+'morenotlisted' => 'fleiri ekki skráð...',
 'mypage' => 'Síða',
 'mytalk' => 'Spjall',
 'anontalk' => 'Spjallsíða þessa vistfangs.',
@@ -668,7 +669,7 @@ Ekki gleyma að breyta [[Special:Preferences|{{SITENAME}} stillingunum]] þínum
 'gotaccount' => "Nú þegar með notandanafn? '''$1'''.",
 'gotaccountlink' => 'Skráðu þig inn',
 'userlogin-resetlink' => 'Gleymdir þú notendaupplýsingunum þínum?',
-'createaccountmail' => 'með tölvupósti',
+'createaccountmail' => 'Nota tímabundið handahófsvalið lykilorð og senda það á netfangið sem er tilgreint hér fyrir neðan',
 'createaccountreason' => 'Ástæða:',
 'badretype' => 'Lykilorðin sem þú skrifaðir eru ekki eins.',
 'userexists' => 'Þetta notandanafn er þegar í notkun.
@@ -1026,6 +1027,8 @@ Hluti sniðsins verður ekki með.",
 Þeim hefur verið sleppt.",
 'post-expand-template-argument-category' => 'Síður sem innihalda frumbreytur sniða sem hefur verið sleppt',
 'parser-template-loop-warning' => 'Lykkja í sniði fundin: [[$1]]',
+'parser-template-recursion-depth-warning' => 'Sniðið er sjálkveðið of mörgum sinnum ($1)',
+'node-count-exceeded-category' => 'Síður þar sem er umfram fjöldi hnúta',
 
 # "Undo" feature
 'undo-success' => 'Breytingin hefur verið tekin tilbaka. Vinsamlegast staðfestu og vistaðu svo.',
@@ -1107,6 +1110,8 @@ Frekari upplýsingar eru í [{{fullurl:{{#Special:Log}}/suppress|page={{FULLPAGE
 'revisiondelete' => 'Eyða/endurvekja breytingar',
 'revdelete-nooldid-title' => 'Ógild markbreyting',
 'revdelete-nooldid-text' => 'Annaðhvort hefur útgáfan sem á að fela ekki verið tilgreind, þessi útgáfa ekki verið til, eða að þú sért að reyna að fela núverandi útgáfu.',
+'revdelete-nologid-title' => 'Ógild aðgerðarskráar færsla',
+'revdelete-nologid-text' => 'Þú hefur annaðhvort ekki tilgreint færslu í aðgerðarskrá til að framkvæma þessa aðgerð á, eða að færslan sé ekki til.',
 'revdelete-no-file' => 'Umbeðin skrá er ekki til.',
 'revdelete-show-file-confirm' => 'Ertu viss um að þú viljir sjá eydda breytingu af síðunni "<nowiki>$1</nowiki>" frá $2 $3?',
 'revdelete-show-file-submit' => 'Já',
@@ -1133,6 +1138,12 @@ Frekari upplýsingar eru í [{{fullurl:{{#Special:Log}}/suppress|page={{FULLPAGE
 'revdelete-unsuppress' => 'Fjarlægja takmarkanir á endurvöktum breytingum',
 'revdelete-log' => 'Ástæða:',
 'revdelete-submit' => 'Setja á {{PLURAL:$1|valda breytingu|valdar breytingar}}',
+'revdelete-success' => "'''Sýnileiki útgáfu er uppfærð.'''",
+'revdelete-failure' => "'''Mistókst að uppfæra sýnileika útgáfu:'''
+$1",
+'logdelete-success' => "'''Sýnleiki aðgerðarskráar uppfærð.'''",
+'logdelete-failure' => "'''Mistókst að uppfæra sýnileika aðgerðarskráar:'''
+$1",
 'revdel-restore' => 'Breyta sýn',
 'revdel-restore-deleted' => 'eyddar breytingar',
 'revdel-restore-visible' => 'sýnilegar breytingar',
@@ -1142,7 +1153,12 @@ Frekari upplýsingar eru í [{{fullurl:{{#Special:Log}}/suppress|page={{FULLPAGE
 Ekki er hægt að fela hana.',
 'revdelete-show-no-access' => 'Mistókst að sýna breytingu frá $1 $2: Þessi breyting hefur verið merkt sem "takmörkuð".
 Þú hefur ekki aðgang að henni.',
+'revdelete-modify-no-access' => 'Mistókst að breyta hlut frá $1 $2: Þessi breyting hefur verið merkt sem „takmörkuð”.
+Þú hefur ekki aðgang að henni.',
+'revdelete-modify-missing' => 'Mistókst að breyta hlut með auðkennið $1: Hann finnst ekki í gagnabankanum!',
 'revdelete-no-change' => "'''Viðvörun:''' Breytingin frá $1 $2 hefur þegar umbeðnar sýnileika stillingar.",
+'revdelete-concurrent-change' => 'Mistókst að breyta hlut frá $1 $2: Staða hans virðist hafa verið breytt af einhverjum öðrum á meðan þú reyndir að breyta honum.
+Vinsamlegast athugaðu í aðgerðarskránum.',
 'revdelete-only-restricted' => 'Mistókst að fela breytingu frá $1 $2: Þú getur ekki falið breytingu fyrir möppudýrum án þess að velja eina af hinum sýnileika stillingunum.',
 'revdelete-reason-dropdown' => '*Algengar eyðingarástæður
 **Höfundarréttarbrot
@@ -1152,9 +1168,12 @@ Ekki er hægt að fela hana.',
 'revdelete-otherreason' => 'Aðrar/fleiri ástæður:',
 'revdelete-reasonotherlist' => 'Önnur ástæða',
 'revdelete-edit-reasonlist' => 'Eyðingarástæður',
+'revdelete-offender' => 'Höfundur þessarar útgáfu:',
 
 # Suppression log
 'suppressionlog' => 'Bælingarskrá',
+'suppressionlogtext' => 'Hér fyrir neðan er listi af eyðingum og bönnum sem innihalda efni sem hefur verið falið fyrir stjórnendum.
+Sjáðu [[Special:BlockList|bannlistann]] fyrir lista yfir núverandi bönn.',
 
 # History merging
 'mergehistory' => 'Sameina breytingaskrár',
@@ -1183,6 +1202,9 @@ Sjáðu til þess að þessi breyting sameini breytingarskrárnar samfellt.',
 'editundo' => 'Taka aftur þessa breytingu',
 'diff-multi' => '({{PLURAL:$1|Ein millibreyting ekki sýnd|$1 millibreytingar ekki sýndar}} frá {{PLURAL:$2|notanda|$2 notendum}}.)',
 'diff-multi-manyusers' => '({{PLURAL:$1|Ein millibreyting ekki sýnd|$1 millibreytingar ekki sýndar}} frá fleiri en {{PLURAL:$2|einum notanda|$2 notendum}}.)',
+'difference-missing-revision' => '{{PLURAL:$2|Ein útgáfa|$2 útgáfur}} samanburðarins ($1) {{PLURAL:$2|fannst|fundust}} ekki.
+
+Þetta gerist oftast þegar úreldur samanburðar-tengill tengir á síðu sem hefur verið eytt. Frekari upplýsingar eru í [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} eyðingarskránni].',
 
 # Search results
 'searchresults' => 'Leitarniðurstöður',
@@ -1226,7 +1248,7 @@ Sjáðu til þess að þessi breyting sameini breytingarskrárnar samfellt.',
 'search-interwiki-default' => '$1 útkomur:',
 'search-interwiki-more' => '(fleiri)',
 'search-relatedarticle' => 'Tengt',
-'mwsuggest-disable' => 'Gera AJAX-uppástungur óvirkar',
+'mwsuggest-disable' => 'Gera leitar uppástungur óvirkar',
 'searcheverything-enable' => 'Leita í öllum nafnrýmum',
 'searchrelated' => 'tengt',
 'searchall' => 'öllum',
@@ -1718,11 +1740,13 @@ Ef vandamálið lagast ekki, hafðu samband við [[Special:ListUsers/sysop|stjó
 'upload-copy-upload-invalid-domain' => 'Lokað er fyrir afritun skráa frá öðrum vefþjón á þessu vefsvæði.',
 
 # File backend
+'backend-fail-stream' => 'Gat ekki streymt skránni „$1“.',
 'backend-fail-backup' => 'Öryggisafritun skráarinnar $1 mistókst.',
 'backend-fail-notexists' => 'Skráin $1 er ekki til.',
 'backend-fail-notsame' => 'Ólík skrá er þegar til á $1.',
 'backend-fail-invalidpath' => '$1 er ekki gildur geymslustaður.',
 'backend-fail-delete' => 'Mistókst að eyða skránni $1.',
+'backend-fail-describe' => 'Mistókst að breyta lýsisgögnum skráarinnar „$1“.',
 'backend-fail-alreadyexists' => 'Skráin $1 er þegar til.',
 'backend-fail-store' => 'Mistókst að vista skrá $1 á $2.',
 'backend-fail-copy' => 'Mistókst að afrita skjal $1 á $2.',
@@ -1761,6 +1785,7 @@ Reyndu aftur.',
 Biðlarinn þínn er ekki stilltur til að gefa upp þessar upplýsingar.
 Þær mega vera CGI-byggðar og mega ekki styðja img_auth.
 https://www.mediawiki.org/wiki/Manual:Image_Authorization',
+'img-auth-badtitle' => 'Mistókst að búa til gildan titil útfrá „$1”.',
 'img-auth-nofile' => 'Skráin "$1" er ekki til.',
 'img-auth-streaming' => 'Streymi "$1".',
 'img-auth-noread' => 'Notandinn hefur ekki rétt til að lesa "$1"',
@@ -1846,6 +1871,7 @@ Hentugra væri ef þú gætir breytt lýsingu skráarinnar á [$2 myndasíðu] h
 'uploadnewversion-linktext' => 'Hlaða inn nýrri útgáfu af þessari skrá',
 'shared-repo-from' => 'frá $1',
 'shared-repo' => 'sameiginlegu myndasafni',
+'upload-disallowed-here' => 'Þú getur ekki yfirskrifað þessa skrá.',
 
 # File reversion
 'filerevert' => 'Taka aftur $1',
@@ -2097,7 +2123,7 @@ Leitin þarf að minnsta kosti að innihalda rótarlén, eins og "*.org"
 # Special:ActiveUsers
 'activeusers' => 'Virkir notendur',
 'activeusers-intro' => 'Þetta er listi yfir notendur sem hafa verið virkir {{PLURAL:$1|síðasta|síðustu}} $1 {{PLURAL:$1|dag|daga}}.',
-'activeusers-count' => '$1 {{PLURAL:$1|breyting|breytingar}} á {{PLURAL:$3|síðastliðnum degi|síðustu $3 dögum}}',
+'activeusers-count' => '$1 {{PLURAL:$1|aðgerð|aðgerðir}} á {{PLURAL:$3|síðastliðnum degi|síðustu $3 dögum}}',
 'activeusers-from' => 'Sýna notendur sem byrja á:',
 'activeusers-hidebots' => 'Fela vélmenni',
 'activeusers-hidesysops' => 'Fela möppudýr',
@@ -2329,8 +2355,8 @@ Núverandi staða síðunnar er '''$1''':",
 'protect-cascadeon' => 'Þessi síða er vernduð vegna þess að hún er innifalin í eftirfarandi {{PLURAL:$1|síðu, sem er keðjuvernduð|síðum, sem eru keðjuverndaðar}}.
 Þú getur breytt verndunarstigi þessarar síðu, en það mun ekki hafa áhrif á keðjuverndunina.',
 'protect-default' => 'Leyfa öllum notendum',
-'protect-fallback' => '„$1“ réttindi nauðsynleg',
-'protect-level-autoconfirmed' => 'Banna nýja og óinnskráða notendur',
+'protect-fallback' => 'Leyfa eingöngu notendur með „$1“ réttindi',
+'protect-level-autoconfirmed' => 'Leyfa aðeins sjálkrafa staðfesta notendur',
 'protect-level-sysop' => 'Leyfa aðeins stjórnendur',
 'protect-summary-cascade' => 'keðjuvörn',
 'protect-expiring' => 'rennur út $1 (UTC)',
@@ -2718,6 +2744,7 @@ Til þess að flytja út síður, skrifaðu titla þeirra í reitina hér fyrir
 
 Ef síðari möguleikinn á við getur þú einnig notað tengil, til dæmis
 [[{{#Special:Export}}/{{MediaWiki:Mainpage}}]] fyrir síðuna "[[{{MediaWiki:Mainpage}}]]".',
+'exportall' => 'Flytja út allar síður',
 'exportcuronly' => 'Aðeins núverandi útgáfu án breytingaskrár',
 'exportnohistory' => "----
 '''Athugaðu:''' Að flytja út alla breytingasögu síðna á þennan hátt hefur verið óvirkjað vegna ástæðna afkasta.",
@@ -2752,6 +2779,7 @@ Vinsamlegast heimsæktu [//www.mediawiki.org/wiki/Localisation MediaWiki-staðf
 'thumbnail-more' => 'Stækka',
 'filemissing' => 'Skrá vantar',
 'thumbnail_error' => 'Villa við gerð smámyndar: $1',
+'djvu_no_xml' => 'Mistókst að sækja XML-gögn fyrir DjVu skrá',
 'thumbnail-temp-create' => 'Mistókst að búa til tímabundna smámynd.',
 'thumbnail_invalid_params' => 'Breytur smámyndarinnar eru rangar',
 'thumbnail_dest_directory' => 'Mistókst að búa til niðurhals möppu',
@@ -2769,6 +2797,7 @@ Allir innflutningar eru skráð í [[Special:Log/import|innflutningsskránna]].'
 'import-interwiki-templates' => 'Innifala öll snið með',
 'import-interwiki-submit' => 'Flytja inn',
 'import-interwiki-namespace' => 'Ákvörðunarnafnrými:',
+'import-interwiki-rootpage' => 'Ákvörðunar grunnsíða (valfrjáls):',
 'import-upload-filename' => 'Skráarnafn:',
 'import-comment' => 'Athugasemdir:',
 'importtext' => 'Vinsamlegast fluttu út skránna frá upprunalegum wiki með því að nota [[Special:Export|Flytja út síður]].
@@ -2804,6 +2833,9 @@ Vinsamlegast reyndu aftur.',
 'import-error-interwiki' => 'Síðan "$1" var ekki flutt inn því nafn hennar er frátekið fyrir ytri tengla (tungumálatengla).',
 'import-error-special' => 'Síðan "$1" var ekki flutt inn því hún tilheyrir ákveðnu nafnrými sem leyfir ekki síður.',
 'import-error-invalid' => 'Síðan "$1" var ekki flutt inn því nafn hennar er ógilt.',
+'import-options-wrong' => '{{PLURAL:$2|Rangur möguleiki|Rangir möguleikar}}: <nowiki>$1</nowiki>',
+'import-rootpage-invalid' => 'Uppgefin ákvörðunar síða er ógildur titill.',
+'import-rootpage-nosubpage' => 'Nafnrými „$1“ ákvörðunar síðunar leyfir ekki undirsíður.',
 
 # Import log
 'importlogpage' => 'Innflutningsskrá',
@@ -2815,6 +2847,8 @@ Vinsamlegast reyndu aftur.',
 
 # JavaScriptTest
 'javascripttest' => 'JavaScript prófun',
+'javascripttest-title' => 'Keyri $1 prófun',
+'javascripttest-pagetext-noframework' => 'Þessi síða er frátekin fyrir JavaScript prófanir.',
 'javascripttest-pagetext-skins' => 'Veldu þema sem á að keyra prófanirnar á:',
 
 # Tooltip help for the actions
@@ -2905,6 +2939,8 @@ Vinsamlegast reyndu aftur.',
 'others' => 'aðrir',
 'siteusers' => '{{SITENAME}} {{PLURAL:$2|notandi|notendur}} $1',
 'anonusers' => '{{SITENAME}} {{PLURAL:$2|nafnlaus notandi|nafnlausir notendur}} $1',
+'creditspage' => 'Höfundar síðunnar',
+'nocredits' => 'Engar höfundarupplýsingar eru til um þessa síðu',
 
 # Spam protection
 'spamprotectiontitle' => 'Amapósts sía',
@@ -2918,6 +2954,7 @@ Vinsamlegast reyndu aftur.',
 
 # Info page
 'pageinfo-title' => 'Upplýsingar um $1',
+'pageinfo-not-current' => 'Því miður er ekki hægt að veita þessar upplýsingar um gamlar útgáfur.',
 'pageinfo-header-basic' => 'Grunnupplýsingar',
 'pageinfo-header-edits' => 'Breytingarskrá',
 'pageinfo-header-restrictions' => 'Verndunarstig síðunnar',
@@ -2932,6 +2969,7 @@ Vinsamlegast reyndu aftur.',
 'pageinfo-robot-noindex' => 'Óskráanleg',
 'pageinfo-views' => 'Fjöldi innlita',
 'pageinfo-watchers' => 'Fjöldi notenda, sem vakta síðuna',
+'pageinfo-few-watchers' => 'Vöktuð af færri en $1 {{PLURAL:$1|notandi|notendum}}',
 'pageinfo-redirects-name' => 'Tilvísanir til þessarar síðu',
 'pageinfo-subpages-name' => 'Undirsíður þessarar síðu',
 'pageinfo-subpages-value' => '$1 ($2 {{PLURAL:$2|tilvísun|tilvísanir}}; $3 {{PLURAL:$3|ekki tilvísun|ekki tilvísanir}})',
@@ -2946,6 +2984,7 @@ Vinsamlegast reyndu aftur.',
 'pageinfo-magic-words' => 'Töfra {{PLURAL:$1|orð}} ($1)',
 'pageinfo-hidden-categories' => '{{PLURAL:$1|Falinn flokkur|Faldir flokkar}} ($1)',
 'pageinfo-templates' => '{{PLURAL:$1|Innifalið snið|Innifalin snið}} ($1)',
+'pageinfo-transclusions' => '{{PLURAL:$1|Síða|Síður}} ítengdar á ($1)',
 'pageinfo-toolboxlink' => 'Síðuupplýsingar',
 'pageinfo-redirectsto' => 'Vísar til',
 'pageinfo-redirectsto-info' => 'upplýsingar',
@@ -2954,6 +2993,10 @@ Vinsamlegast reyndu aftur.',
 'pageinfo-protect-cascading' => 'Keðjuvörn hefst hér',
 'pageinfo-protect-cascading-yes' => 'Já',
 'pageinfo-protect-cascading-from' => 'Keðjuvörn stafar frá',
+'pageinfo-category-info' => 'Flokka upplýsingar',
+'pageinfo-category-pages' => 'Fjöldi síðna',
+'pageinfo-category-subcats' => 'Fjöldi undirflokka',
+'pageinfo-category-files' => 'Fjöldi skráa',
 
 # Skin names
 'skinname-standard' => 'Sígilt',
@@ -2975,6 +3018,8 @@ Vinsamlegast reyndu aftur.',
 'markedaspatrollederror' => 'Get ekki merkt sem yfirfarið',
 'markedaspatrollederrortext' => 'Þú verður að velja breytingu til að merkja sem yfirfarið.',
 'markedaspatrollederror-noautopatrol' => 'Þú hefur ekki réttindi til að merkja eigin breytingar sem yfirfarnar.',
+'markedaspatrollednotify' => 'Þessi breyting á $1 hefur verið merkt sem yfirfarin.',
+'markedaspatrollederrornotify' => 'Mistókst að merkja síðuna sem yfirfarna.',
 
 # Patrol log
 'patrol-log-page' => 'Yfirferðarskrá',
@@ -3004,6 +3049,8 @@ Vinsamlegast reyndu aftur.',
 'file-info-size-pages' => '$1 x $2 dílar, skráarstærð: $3, MIME-gerð: $4, $5 {{PLURAL:$5|síða|síður}} tengja í skránna.',
 'file-nohires' => 'Það er engin hærri upplausn til.',
 'svg-long-desc' => 'SVG-skrá, að nafni til $1 × $2 dílar, skráarstærð: $3',
+'svg-long-desc-animated' => 'SVG-hreyfimynd, að nafni til $1 × $2 dílar, skráarstærð: $3',
+'svg-long-error' => 'Ógild SVG skrá: $1',
 'show-big-image' => 'Mesta upplausn',
 'show-big-image-preview' => 'Stærð þessarar forskoðunar: $1',
 'show-big-image-other' => '{{PLURAL:$2|Önnur upplausn|Aðrar upplausnir}}: $1.',
@@ -3031,7 +3078,10 @@ Vinsamlegast reyndu aftur.',
 'minutes' => '{{PLURAL:$1|ein mínúta|$1 mínútur}}',
 'hours' => '{{PLURAL:$1|einn klukkutími|$1 klukkutímar}}',
 'days' => '{{PLURAL:$1|einn dagur|$1 dagar}}',
+'months' => '{{PLURAL:$1|$1 mánuður|$1 mánuðir}}',
+'years' => '{{PLURAL:$1|$1 ár}}',
 'ago' => '$1 síðan',
+'just-now' => 'akkúrat núna',
 
 # Bad image list
 'bad_image_list' => 'Sniðið er eftirfarandi:
@@ -3604,7 +3654,7 @@ Myndir eru sýndar í fullri upplausn og önnur skráarsnið eru ræst í sjálf
 'specialpages-group-highuse' => 'Mest notuðu síðurnar',
 'specialpages-group-pages' => 'Listar yfir síður',
 'specialpages-group-pagetools' => 'Síðuverkfæri',
-'specialpages-group-wiki' => 'Wiki gögn og tól',
+'specialpages-group-wiki' => 'Gögn og tól',
 'specialpages-group-redirects' => 'Tilvísaðar kerfisíður',
 'specialpages-group-spam' => 'Amapósts sía',
 
@@ -3702,8 +3752,12 @@ Tæknilegir örðugleikar eru á þessari síðu.',
 'logentry-newusers-newusers' => 'Notandaaðgangurinn $1 var stofnaður',
 'logentry-newusers-create' => 'Notandaaðgangurinn $1 var stofnaður',
 'logentry-newusers-create2' => '$1 stofnaði notandaaðganginn $3',
+'logentry-newusers-byemail' => 'Notenda aðgangurinn $3 var búinn til af $1 og lykilorðið var sent með tölvupósti',
 'logentry-newusers-autocreate' => 'Aðgangurinn $1 var stofnaður sjálfvirkt',
-'rightsnone' => '(engin)',
+'logentry-rights-rights' => '$1 breytti réttindum $3 frá $4 í $5',
+'logentry-rights-rights-legacy' => '$1 breytti réttindum $3',
+'logentry-rights-autopromote' => '$1 fékk sjálfvirkt aukin réttindi frá $4 til $5',
+'rightsnone' => '(engum)',
 
 # Feedback
 'feedback-bugornote' => 'Ef þú ert reiðubúinn að lýsa tæknilegri villu í smáatriðum, vinsamlegast [$1 tilkynntu villu].
@@ -3757,6 +3811,7 @@ Ef ekki, þá getur þú notað einfalt eyðublað hér fyrir neðan. Athugasemd
 'api-error-ok-but-empty' => 'Innri villa: ekkert svar frá vefþjón.',
 'api-error-overwrite' => 'Óheimilt er að skrifa yfir skrá sem er þegar til.',
 'api-error-stashfailed' => 'Innri villa: Vefþjónninn gat ekki geymt tímabundna skrá.',
+'api-error-publishfailed' => 'Innri villa: Vefþjónninn gat ekki gefið út tímabundna skrá.',
 'api-error-timeout' => 'Vefþjónninn svaraði ekki á tilætluðum tíma.',
 'api-error-unclassified' => 'Óþekkt villa kom upp.',
 'api-error-unknown-code' => 'Óþekkt villa: "$1"',
index 53e7ba3..bf9ae69 100644 (file)
@@ -1300,7 +1300,7 @@ I dettagli possono essere trovati nel [{{fullurl:{{#Special:Log}}/delete|page={{
 'search-interwiki-default' => 'Risultati da $1:',
 'search-interwiki-more' => '(altro)',
 'search-relatedarticle' => 'Risultati correlati',
-'mwsuggest-disable' => 'Disattiva suggerimenti AJAX',
+'mwsuggest-disable' => 'Disattiva i suggerimenti di ricerca',
 'searcheverything-enable' => 'Cerca in tutti i namespace',
 'searchrelated' => 'correlati',
 'searchall' => 'tutti',
@@ -2704,7 +2704,7 @@ Ricordare di [[Special:UnlockDB|rimuovere il blocco]] dopo aver terminato le ope
 'move-page-legend' => 'Spostamento di pagina',
 'movepagetext' => "Questo modulo consente di rinominare una pagina, spostando tutta la sua cronologia al nuovo nome. La pagina attuale diverrà automaticamente un redirect al nuovo titolo. Puoi aggiornare automaticamente i redirect che puntano al titolo originale. Puoi decidere di non farlo, ma ricordati di verificare che lo spostamento non abbia creato [[Special:DoubleRedirects|doppi redirect]] o [[Special:BrokenRedirects|redirect errati]]. L'onere di garantire che i collegamenti alla pagina restino corretti spetta a chi la sposta.
 
-Si noti che la pagina '''non''' sarà spostata se ne esiste già una con il nuovo nome, a meno che non sia costituita solo da un redirect alla vecchia e sia priva di versioni precedenti. In caso di spostamento errato si può quindi tornare subito al vecchio titolo, e non è possibile sovrascrivere per errore una pagina già esistente.
+Si noti che la pagina '''non''' sarà spostata se ne esiste già una con il nuovo nome, a meno che quest'ultima non sia costituita solo da un redirect alla vecchia e sia priva di versioni precedenti. In caso di spostamento errato si può quindi tornare subito al vecchio titolo, e non è possibile sovrascrivere per errore una pagina già esistente.
 
 '''ATTENZIONE:'''
 Un cambiamento così drastico può creare contrattempi e problemi, soprattutto per le pagine più visitate. Accertarsi di aver valutato le conseguenze dello spostamento prima di procedere.",
@@ -3045,6 +3045,7 @@ Tutte le operazioni di importazione trans-wiki sono registrate nel [[Special:Log
 'pageinfo-robot-noindex' => 'Non indicizzabile',
 'pageinfo-views' => 'Numero di visualizzazioni',
 'pageinfo-watchers' => 'Numero di utenti che hanno la pagina nei loro osservati speciali',
+'pageinfo-few-watchers' => 'Meno di $1 {{PLURAL:$1|osservatore|osservatori}}',
 'pageinfo-redirects-name' => 'Redirect a questa pagina',
 'pageinfo-subpages-name' => 'Sottopagine di questa pagina',
 'pageinfo-subpages-value' => '$1 ($2 {{PLURAL:$2|redirect}}; $3 {{PLURAL:$3|non redirect}})',
@@ -3058,8 +3059,8 @@ Tutte le operazioni di importazione trans-wiki sono registrate nel [[Special:Log
 'pageinfo-recent-authors' => 'Numero di autori diversi recenti',
 'pageinfo-magic-words' => '{{PLURAL:$1|Parola magica|Parole magiche}} ($1)',
 'pageinfo-hidden-categories' => '{{PLURAL:$1|Categoria nascosta|Categorie nascoste}} ($1)',
-'pageinfo-templates' => '{{PLURAL:$1|Template incluso}} in ($1)',
-'pageinfo-transclusions' => '{{PLURAL:$1|Pagina inclusa}} in ($1)',
+'pageinfo-templates' => 'Template {{PLURAL:$1|incluso|inclusi}} ($1)',
+'pageinfo-transclusions' => '{{PLURAL:$1|Pagina|Pagine}} in cui è incluso ($1)',
 'pageinfo-toolboxlink' => 'Informazioni sulla pagina',
 'pageinfo-redirectsto' => 'Reindirizza a',
 'pageinfo-redirectsto-info' => 'info',
index cafb07c..20efe9e 100644 (file)
@@ -363,7 +363,7 @@ $magicWords = array(
 
 $messages = array(
 # User preference toggles
-'tog-underline' => 'リンクの下線:',
+'tog-underline' => 'リンクの下線',
 'tog-justify' => '段落に均等割り付けを設定',
 'tog-hideminor' => '最近の更新に細部の編集を表示しない',
 'tog-hidepatrolled' => '最近の更新に巡回済みの編集を表示しない',
@@ -578,7 +578,7 @@ $messages = array(
 'categorypage' => 'カテゴリのページを表示',
 'viewtalkpage' => '議論を表示',
 'otherlanguages' => '他言語版',
-'redirectedfrom' => '($1から転送)',
+'redirectedfrom' => '($1から転送)',
 'redirectpagesub' => '転送ページ',
 'lastmodifiedat' => 'このページの最終更新日時は $1 $2 です。',
 'viewcount' => 'このページは {{PLURAL:$1|$1 回}}アクセスされました。',
@@ -1143,7 +1143,7 @@ IP アドレスは複数の利用者で共有されている場合がありま
 'templatesused' => 'このページで使用されている{{PLURAL:$1|テンプレート}}:',
 'templatesusedpreview' => 'このプレビューで使用されている{{PLURAL:$1|テンプレート}}:',
 'templatesusedsection' => 'この節で使用されている{{PLURAL:$1|テンプレート}}:',
-'template-protected' => '(保護)',
+'template-protected' => '(保護)',
 'template-semiprotected' => '(半保護)',
 'hiddencategories' => 'このページは {{PLURAL:$1|$1 個の隠しカテゴリ}}に属しています:',
 'edittools' => '<!-- ここに書いたテキストは編集及びアップロードのフォームの下に表示されます。 -->',
@@ -1439,7 +1439,7 @@ $1",
 'search-interwiki-default' => '$1の結果:',
 'search-interwiki-more' => '(続き)',
 'search-relatedarticle' => '関連',
-'mwsuggest-disable' => 'Ajaxによる検索候補の提示を無効にする',
+'mwsuggest-disable' => '検索候補の提示を無効にする',
 'searcheverything-enable' => 'すべての名前空間を検索',
 'searchrelated' => '関連',
 'searchall' => 'すべて',
@@ -1799,7 +1799,7 @@ $1 {{PLURAL:$1|文字}}以下である必要があります。',
 'recentchangeslinked-summary' => "これは指定したページからリンクされている(または指定したカテゴリに含まれている)ページの最近の変更の一覧です。
 [[Special:Watchlist|自分のウォッチリスト]]にあるページは'''太字'''で表示されます。",
 'recentchangeslinked-page' => 'ページ名:',
-'recentchangeslinked-to' => '指定したページの「リンク元」ページの変更を表示',
+'recentchangeslinked-to' => 'このページへのリンク元での変更の表示に切り替え',
 
 # Upload
 'upload' => 'ファイルをアップロード',
@@ -2593,6 +2593,7 @@ $2による直前の版へ変更されました。',
 'prot_1movedto2' => '[[$1]] を [[$2]] へ移動',
 'protect-badnamespace-title' => '保護不可能な名前空間',
 'protect-badnamespace-text' => 'この名前空間のページは保護できません。',
+'protect-norestrictiontypes-text' => '利用できる制限の種類がないため、このページは保護できません。',
 'protect-norestrictiontypes-title' => '保護できないページ',
 'protect-legend' => '保護の確認',
 'protectcomment' => '理由:',
@@ -2710,7 +2711,7 @@ $1',
 'tooltip-invert' => '選択した名前空間 (チェックを入れている場合は、関連付けられた名前空間も含む) のページの変更を非表示にするには、このボックスにチェックを入れる',
 'namespace_association' => '関連付けられた名前空間も含める',
 'tooltip-namespace_association' => '選択した名前空間に関連付けられたトークページ (逆にトークページの名前空間を選択した場合も同様) の名前空間も含めるには、このボックスにチェックを入れる',
-'blanknamespace' => '(標準)',
+'blanknamespace' => '(標準)',
 
 # Contributions
 'contributions' => '{{GENDER:$1|利用者}}の投稿記録',
@@ -2922,10 +2923,12 @@ $1 のブロックの理由は「''$2''」です。",
 [[Special:DoubleRedirects|二重転送]]や[[Special:BrokenRedirects|迷子のリダイレクト]]を確認する必要があります。
 リンクを正しく維持するのは移動した人の責任です。
 
-移動先が既に存在する場合は、そのページが転送ページであり、かつ過去の版を持たない場合を除いて移動'''できません'''。つまり、間違えてページ名を変更した場合には元に戻せます。また移動によって既存のページを上書きしてしまうことはありません。
+移動先のページが既に存在する場合は、その移動先が転送ページであり、かつ過去の版を持たない場合以外は移動'''できません'''。
+つまり、間違えてページ名を変更した場合には元に戻せます。また移動によって既存のページを上書きしてしまうことはありません。
 
-'''注意!'''
-よく閲覧されるページや、他の多くのページからリンクされているページを移動すると予期しない結果が起こるかもしれません。ページの移動に伴う影響をよく考えてから踏み切るようにしてください。",
+'''注意!'''
+よく閲覧されるページや、他の多くのページからリンクされているページを移動すると予期しない結果が起こるかもしれません。
+ページの移動に伴う影響をよく考えてから踏み切るようにしてください。",
 'movepagetext-noredirectfixer' => "下のフォームを使用すると、ページ名を変更でき、そのページの履歴も変更先に移動できます。
 移動元のページは移動先への転送ページになります。
 自動的な修正を選択しない場合は、[[Special:DoubleRedirects|二重転送]]や[[Special:BrokenRedirects|迷子のリダイレクト]]を確認する必要があります。
@@ -3276,6 +3279,7 @@ MediaWiki 全般のローカライズ (地域化) に貢献したい場合は、
 'pageinfo-robot-noindex' => '検索エンジンに収集されない',
 'pageinfo-views' => '閲覧回数',
 'pageinfo-watchers' => 'ページをウォッチリストに入れている人数',
+'pageinfo-few-watchers' => 'ウォッチしている利用者 $1 {{PLURAL:$1|人未満}}',
 'pageinfo-redirects-name' => 'このページへのリダイレクト数',
 'pageinfo-redirects-value' => '$1',
 'pageinfo-subpages-name' => 'このページの下位ページ数',
@@ -3364,8 +3368,8 @@ $1',
 'svg-long-desc-animated' => 'アニメーション SVG ファイル、$1 × $2 ピクセル、ファイルサイズ: $3',
 'svg-long-error' => '無効な SVG ファイル: $1',
 'show-big-image' => '高解像度での画像',
-'show-big-image-preview' => 'このプレビューのサイズ$1。',
-'show-big-image-other' => 'その他の{{PLURAL:$2|解像度}}$1。',
+'show-big-image-preview' => 'このプレビューのサイズ$1。',
+'show-big-image-other' => 'その他の{{PLURAL:$2|解像度}}$1。',
 'show-big-image-size' => '$1 × $2 ピクセル',
 'file-info-gif-looped' => 'ループします',
 'file-info-gif-frames' => '$1 {{PLURAL:$1|フレーム}}',
@@ -4352,6 +4356,7 @@ MediaWikiは、有用であることを期待して配布されていますが
 'api-error-ok-but-empty' => '内部エラー: サーバーからの応答がありません。',
 'api-error-overwrite' => '既存のファイルへの上書きは許可されていません。',
 'api-error-stashfailed' => '内部エラー: サーバーは一時ファイルを格納できませんでした。',
+'api-error-publishfailed' => '内部エラー:サーバーは一時ファイルを発行できませんでした。',
 'api-error-timeout' => 'サーバーが決められた時間内に応答しませんでした。',
 'api-error-unclassified' => '不明なエラーが発生しました。',
 'api-error-unknown-code' => '不明なエラー:「$1」',
index a764494..7b51016 100644 (file)
@@ -219,7 +219,7 @@ $messages = array(
 'underline-default' => 'დამოკიდებული მომხმარებელზე ან ბრაუზერის არჩევანზე',
 
 # Font style option in Special:Preferences
-'editfont-style' => 'რედაქტირების არის შრიფტის ტიპი:',
+'editfont-style' => 'á\83 á\83\94á\83\93á\83\90á\83¥á\83¢á\83\98á\83 á\83\94á\83\91á\83\98á\83¡ á\83\90á\83 á\83\94á\83\90á\83\9aá\83\98á\83¡ á\83¨á\83 á\83\98á\83¤á\83¢á\83\98á\83¡ á\83¢á\83\98á\83\9eá\83\98:',
 'editfont-default' => 'ბრაუზერის უპირობო არჩევანი',
 'editfont-monospace' => 'მონოშირული შრიფტი',
 'editfont-sansserif' => 'შრიფტი სანს-სერიფი',
@@ -613,7 +613,7 @@ $2',
 'gotaccount' => "უკვე რეგისტრირებული ხართ? '''$1'''",
 'gotaccountlink' => 'შესვლა',
 'userlogin-resetlink' => 'ავტორიზაციის მონაცემები დაგავიწყდათ?',
-'createaccountmail' => 'á\83\94á\83\9a\83¤á\83\9dá\83¡á\83¢á\83\98á\83\97',
+'createaccountmail' => 'á\83\92á\83\90á\83\9bá\83\9dá\83\98á\83§á\83\94á\83\9cá\83\94á\83\97 á\83¨á\83\94á\83\9bá\83\97á\83®á\83\95á\83\94á\83\95á\83\98á\83\97á\83\9dá\83\91á\83\98á\83¡ á\83\9bá\83\94á\83\97á\83\9dá\83\93á\83\98á\83\97 á\83¨á\83\94á\83 á\83©á\83\94á\83£á\83\9aá\83\98 á\83\93á\83 á\83\9dá\83\94á\83\91á\83\98á\83\97á\83\98 á\83\9eá\83\90á\83 á\83\9dá\83\9aá\83\98 á\83\93á\83\90 á\83\9bá\83\98á\83¡á\83\98 á\83\92á\83\90á\83\92á\83\96á\83\90á\83\95á\83\9cá\83\90 á\83¥á\83\95á\83\94á\83\9bá\83\9dá\83\97 á\83\9bá\83\98á\83\97á\83\98á\83\97á\83\94á\83\91á\83£á\83\9a á\83\94á\83\9a. á\83¤á\83\9dá\83¡á\83¢á\83\98á\83¡ á\83\9bá\83\98á\83¡á\83\90á\83\9bá\83\90á\83 á\83\97á\83\96á\83\94:',
 'createaccountreason' => 'მიზეზი:',
 'badretype' => 'თქვენს მიერ შეყვანილი პაროლები ერთმანეთს არ ემთხვევა.',
 'userexists' => 'ეს სახელი უკვე გამოყენებულია.
@@ -689,6 +689,7 @@ $1 საათში.',
 # E-mail sending
 'php-mail-error-unknown' => 'ამოუცნობი შეცდომა PHP-ის mail() ფუნქციაში',
 'user-mail-no-addy' => 'ცდილობდა ელ-ფოსტის გაგზავნას ელ-ფოსტის მისამართის გარეშე.',
+'user-mail-no-body' => 'ცდილობდა ცარიელი ან უაზროდ მოკლე შინაარსის ელექტრონული წერილის გაგზავნას.',
 
 # Change password dialog
 'resetpass' => 'შეცვალეთ პაროლი',
@@ -1227,7 +1228,7 @@ $1",
 'search-interwiki-default' => 'შედეგები $1-დან:',
 'search-interwiki-more' => '(გაგრძელება)',
 'search-relatedarticle' => 'დაკავშირებული',
-'mwsuggest-disable' => 'გათიშეთ AJAX დახმარებები',
+'mwsuggest-disable' => 'გათიშეთ ძიების შეთავაზებები',
 'searcheverything-enable' => 'ძიება სახელთა ყველა სივრცეებში',
 'searchrelated' => 'მიბმული',
 'searchall' => 'ყველა',
@@ -1303,7 +1304,7 @@ $1",
 'prefs-help-watchlist-token' => 'ამ ველის შევსება საიდუმლო გასაღებით შექმნის RSS ტრანსლაციას თქვენი კონტროლის სიისთვის.
 ყველა, ვინც იცის გასაღები, შესძლებს იხილოს თქვენი კონტროლის სია. ფრთხილად იყავით საიდუმლო მნიშვნელობის არჩევისას.
 თქვენ შეგიძლიათ გამოიყენოთ ასევე შემთვევითი მნიშვნელობა: $1',
-'savedprefs' => 'თქვენ მიერ შერჩეული პარამეტრები დამახსოვრებულია.',
+'savedprefs' => 'თქვენ მიერ შერჩეული პარამეტრები დამახსოვრებულია.',
 'timezonelegend' => 'სასაათო სარტყელი:',
 'localtime' => 'ადგილობრივი დრო:',
 'timezoneuseserverdefault' => 'გამოიყენე ნაგულისხმევი პარამეტრები ($1)',
@@ -1382,10 +1383,10 @@ $1",
 # User rights
 'userrights' => 'მომხმარებელთა უფლებების მართვა',
 'userrights-lookup-user' => 'მომხმარებელთა ჯგუფების მართვა',
-'userrights-user-editname' => 'á\83\9bá\83\9dá\83\9bá\83®á\83\9bá\83\90á\83 á\83\94á\83\91á\83\9aá\83\98á\83¡ á\83¡á\83\90á\83®á\83\94á\83\9aá\83\98á\83¡ á\83¨á\83\94á\83¢á\83\90á\83\9cá\83\90:',
+'userrights-user-editname' => 'á\83¨á\83\94á\83\98á\83¢á\83\90á\83\9cá\83\94á\83\97 á\83\9bá\83\9dá\83\9bá\83®á\83\9bá\83\90á\83 á\83\94á\83\91á\83\9aá\83\98á\83¡ á\83¡á\83\90á\83®á\83\94á\83\9aá\83\98:',
 'editusergroup' => 'მომხმარებელთა ჯგუფების რედაქტირება',
-'editinguser' => "á\83\9bá\83\9dá\83\9bá\83®á\83\9bá\83\90á\83 á\83\94á\83\91á\83\9aá\83\98á\83¡ á\83£á\83¤á\83\9aá\83\94á\83\91á\83\94á\83\91á\83\98á\83¡ á\83¨á\83\94á\83ªá\83\95á\83\9aá\83\90 á\83\9bá\83\9dá\83\9bá\83®á\83\9bá\83\90á\83 á\83\94á\83\91á\83\9aá\83\98á\83¡á\83\97á\83\95á\83\98á\83¡ '''[[User:$1|$1]]''' $2",
-'userrights-editusergroup' => 'á\83 á\83\94á\83\93á\83\90á\83¥á\83¢á\83\98á\83 á\83\94á\83\91á\83\90 á\83\92á\83\90á\83£á\83\99á\83\94á\83\97á\83\94á\83\97 á\83\9bá\83\9dá\83\9bá\83®á\83\9bá\83\90á\83 á\83\94á\83\91á\83\94á\83\9aá\83\97á\83\90 á\83¯á\83\92á\83£á\83¤á\83\94á\83\91á\83¡',
+'editinguser' => "á\83£á\83¤á\83\9aá\83\94á\83\91á\83\94á\83\91á\83\98á\83¡ á\83¨á\83\94á\83ªá\83\95á\83\9aá\83\90 á\83\9bá\83\9dá\83\9bá\83®á\83\9bá\83\90á\83 á\83\94á\83\91á\83\9aá\83\98á\83¡á\83\97á\83\95á\83\98á\83¡: '''[[User:$1|$1]]''' $2",
+'userrights-editusergroup' => 'á\83\93á\83\90á\83\90á\83 á\83\94á\83\93á\83\90á\83¥á\83¢á\83\98á\83 á\83\94á\83\97 á\83\9bá\83\9dá\83\9bá\83®á\83\9bá\83\90á\83 á\83\94á\83\91á\83\94á\83\9aá\83\97á\83\90 á\83¯á\83\92á\83£á\83¤á\83\94á\83\91á\83\98',
 'saveusergroups' => 'მომხმარებელთა ჯგუფების შენახვა',
 'userrights-groupsmember' => 'ჯგუფის წევრი:',
 'userrights-groupsmember-auto' => 'ნაგულისხმევი წევრი:',
@@ -1394,7 +1395,7 @@ $1",
 * თუ ჯგუფის სახელწოდებასთან გაკეთებულია ნიშნული, ე.ი მომხმარებელი შედის ამ ჯგუფში.
 * თუ ნიშნული არ არის – მომხმარებელი არ განეკუთვნება არსებულ ჯგუფს.
 * ნიშანი * ნიშნავს, რომ თქვენ არ შეგიძლიათ მომხმარებლის ჯგუფიდან წაშლა, თუ დაამატებთ მას იქ ან პირიქით.',
-'userrights-reason' => 'მიზეზი:',
+'userrights-reason' => 'á\83¨á\83\94á\83ªá\83\95á\83\9aá\83\98á\83¡ á\83\9bá\83\98á\83\96á\83\94á\83\96á\83\98:',
 'userrights-no-interwiki' => 'თქვენ არ გაქვთ მომხმარებლის უფლებების რედაქტირების უფლება სხვა ვიკი-ებში.',
 'userrights-nodatabase' => 'მონაცემთა ბაზა $1 არ არსებობს, ან არ არის ლოკალური.',
 'userrights-nologin' => 'თქვენ უნდა [[Special:UserLogin|წარადგინოთ თავი სისტემისადმი]] ადმინისისტრატორის ანგარიშით იმისთვის, რომ გასცეთ მომხმარებელთა უფლებები.',
@@ -2176,7 +2177,7 @@ $1',
 'emailusername' => 'მომხმარებლის სახელი:',
 'emailusernamesubmit' => 'შენახვა',
 'email-legend' => 'წერილის გაგზავნა სხვა მომხმარებლისადმი {{grammar:genitive|{{SITENAME}}}}',
-'emailfrom' => 'á\83\92á\83\90á\83\9bá\83\9dá\83\9bá\83\92á\83\96á\83\90á\83\95á\83\9cá\83\98:',
+'emailfrom' => 'გამგზავნი:',
 'emailto' => 'მიმღები:',
 'emailsubject' => 'თემა:',
 'emailmessage' => 'შეტყობინება:',
@@ -2193,7 +2194,7 @@ $1',
 'usermessage-template' => 'MediaWiki:მომხმარებლის შეტყობინება',
 
 # Watchlist
-'watchlist' => 'á\83©á\83\94á\83\9bá\83\98 á\83\99á\83\9dá\83\9cá\83¢á\83 á\83\9dá\83\9aá\83\98á\83¡ á\83¡á\83\98á\83\90',
+'watchlist' => 'კონტროლის სია',
 'mywatchlist' => 'კონტროლის სია',
 'watchlistfor2' => '$1 ($2) თვის',
 'nowatchlist' => 'თქვენი კონტროლის სია ცარიელია.',
@@ -2344,6 +2345,7 @@ $UNWATCHURL
 'prot_1movedto2' => '[[$1]] გადატანილია გვერდზე [[$2]]',
 'protect-badnamespace-title' => 'დაუცველი სახელთა სივრცე',
 'protect-badnamespace-text' => 'ამ სახელთა სივრცის გვერდების დაცვა შეუძლებელია.',
+'protect-norestrictiontypes-text' => 'ამ გვერდის დაცვა შეუძლებელია, რადგან მისთვის არ არსებობს შესაბამისი დაცვის ტიპი.',
 'protect-norestrictiontypes-title' => 'დაუცველი გვერდი',
 'protect-legend' => 'დაცვის დადასტურება',
 'protectcomment' => 'მიზეზი:',
@@ -2657,11 +2659,18 @@ $1',
 # Move page
 'move-page' => '$1 — გადატანა',
 'move-page-legend' => 'გვერდის გადატანა',
-'movepagetext' => 'ქვემოთ მოცემული ფორმა გვერდს სახელს გადაარქმევს, რაც გადაიტანს მასთან დაკავშირებულ ისტორიასაც ახალ სახელზე. ძველი სათაური გახდება გადამისამართების გვერდი ახალ სათაურზე. ბმულები ძველი გვერდის სათაურზე არ შეიცვლება; შეამოწმეთ ორმაგი ან გამწყდარი გადამისამართებები. თქვენ ხართ პასუხისმგებელი, რომ ბმულები მკითხველს დანიშნულებისამებრ მიიყვანს.
+'movepagetext' => "ქვემოთ მოცემული ფორმა გვერდს სახელს გადაარქმევს, რაც გადაიტანს მასთან დაკავშირებულ ისტორიასაც ახალ სახელზე. 
+ძველი სათაური გახდება გადამისამართების გვერდი ახალ სათაურზე. 
+ბმულები ძველი გვერდის სათაურზე არ შეიცვლება; 
+შეამოწმეთ [[Special:DoubleRedirects|ორმაგი]] ან [[Special:BrokenRedirects|გამწყდარი გადამისამართებები]]. 
+თქვენ ხართ პასუხისმგებელი, რომ ბმულები მკითხველს დანიშნულებისამებრ მიიყვანს.
 
-გაითვალისწინეთ, რომ გვერდი არ გადავა, თუ ახალი სათაურით სტატია უკვე არსებობს, გარდა იმ შემთხვევისა, თუ ის ცარიელია ან გადამისამართებაა და არ აქვს გვერდის რედაქტირების ისტორია. ეს ნიშნავს, რომ თქვენ შეგიძლიათ დაუბრუნოთ ძველი სახელი გვერდს, თუ შეცდომა დაუშვით, მაგრამ არ შეგიძლიათ ზემოთ გადააწეროთ არსებულ გვერდს.
+გაითვალისწინეთ, რომ გვერდი არ გადავა, თუ ახალი სათაურით სტატია უკვე არსებობს, გარდა იმ შემთხვევისა, როდესაც მსგავსი გვერდი ცარიელია ან გადამისამართებაა და არ აქვს გვერდის რედაქტირების ისტორია. 
+ეს ნიშნავს, რომ თქვენ შეგიძლიათ დაუბრუნოთ ძველი სახელი გვერდს, თუ შეცდომა დაუშვით, მაგრამ არ შეგიძლიათ ზემოთ გადააწეროთ არსებულ გვერდს.
 
-<b>გაფრთხილებთ!</b> ამ მოქმედებამ შეიძლება მნიშვნელოვანი და მოულოდნელი ცვლილება გამოიწვის პოპულარულ გვერდზე; სანამ გააგრძელებდეთ, გთხოვთ დარწმუნდეთ, რომ თქვენ გესმით თქვენი ქმედების შედეგები.',
+'''ფრთხილად!'''
+ამ მოქმედებამ შეიძლება მნიშვნელოვანი და მოულოდნელი ცვლილება გამოიწვის პოპულარულ გვერდზე; 
+სანამ გააგრძელებდეთ, გთხოვთ დარწმუნდეთ, რომ თქვენ გესმით თქვენი ქმედების შედეგები.",
 'movepagetext-noredirectfixer' => "ქვემოთ მოცემული ფორმა გვერდს სახელს გადაარქმევს, რაც გადაიტანს მასთან დაკავშირებულ ისტორიასაც ახალ სახელზე. 
 ძველი სათაური გახდება გადამისამართების გვერდი ახალ სათაურზე.
 შეამოწმეთ [[Special:DoubleRedirects|ორმაგი]] ან [[Special:BrokenRedirects|გამწყდარი]] გადამისამართებები. 
@@ -2833,6 +2842,7 @@ $1',
 'import-error-interwiki' => 'გვერდი „$1“ არ იქნა იმპორტირებული, რადგანაც მისი სახელი დარეგისტრირებულია გარე ბმულებისათვის (interwiki).',
 'import-error-special' => 'გვერდი „$1“ არ იქნა იმპორტირებული, რადგანაც ის განეკუთვნება განსაკუთრებულ სახელთა სივრცეს, რომელიც კრძალავს გვერდების შექმნას.',
 'import-error-invalid' => 'გვერდი "$1" იმპორტირება არ მოხდა მიუღებელი სახელის გამო.',
+'import-error-unserialize' => 'ვერსია $2 გვერდისათვის „$1“ არ შეიძლება იყოს სტრუქტურირებული (დესერიალიზებული). მიღებულია შეტყობინება, რომ ამ ვერსიაში გამოიყენება $3 შემცველი მოდელი, სერიალიზებული ფორმატში $4.',
 'import-options-wrong' => 'არასწორი {{PLURAL:$2|პარამეტრი|პარამეტრი}}: <nowiki>$1</nowiki>',
 'import-rootpage-invalid' => 'ძირეული გვერდის მითითებული სახელი არასწორია.',
 'import-rootpage-nosubpage' => 'სახელტა სივრცეში მითითებულ ძირეულ გვერდში „$1“ ქვეგვერდები დაუშვებელია.',
@@ -2985,6 +2995,7 @@ $1',
 'pageinfo-robot-noindex' => 'არ ინდექსირდება',
 'pageinfo-views' => 'ხილვების რაოდენობა',
 'pageinfo-watchers' => 'გვერდის დამკვირვებელთა რაოდენობა',
+'pageinfo-few-watchers' => 'სულ მცირე $1 {{PLURAL:$1|დამკვირვებელი|დამკვირვებელი}}',
 'pageinfo-redirects-name' => 'გადამისამართება ამ გვერდზე',
 'pageinfo-redirects-value' => '$1',
 'pageinfo-subpages-name' => 'ამ გვერდის ქვეგვერდები',
@@ -3000,6 +3011,7 @@ $1',
 'pageinfo-magic-words' => 'ჯადოსნური {{PLURAL:$1|სიტყვა|სიტყვა}} ($1)',
 'pageinfo-hidden-categories' => 'დამალული {{PLURAL:$1|კატეგორია|კატეგორია}} ($1)',
 'pageinfo-templates' => 'ინტეგრირებულია {{PLURAL:$1|თარგი|თარგი}} ($1)',
+'pageinfo-transclusions' => '{{PLURAL:$1|ჩართული გვერდი|ჩართული გვერდი}} ($1)',
 'pageinfo-toolboxlink' => 'გვერდის ინფორმაცია',
 'pageinfo-redirectsto' => 'გადამისამართება',
 'pageinfo-redirectsto-info' => 'ინფორმაცია',
@@ -3934,6 +3946,7 @@ MediaWiki ვრცელდება იმ იმედით, რომ ი
 'logentry-newusers-newusers' => 'მომხმარებლის ანგარიში $1 შექმნილია',
 'logentry-newusers-create' => 'შეიქმნა მომხმარებლის ანგარიში $1',
 'logentry-newusers-create2' => 'მომხმარებლის ანგარიში $3 შექმნა მომხმარებელმა $1',
+'logentry-newusers-byemail' => 'მომხმარებლის ანგარიში $3 შექმნა მომხმარებელმა $1 და პაროლი გაგზავნა ელ. ფოსტით',
 'logentry-newusers-autocreate' => 'ავტომატურად შეიქმნა მომხმარებლის ანგარიში $1',
 'logentry-rights-rights' => '$1 შეცვალა ჯგუფის წევრობა $3-თვის $4-დან $5-ზე',
 'logentry-rights-rights-legacy' => '$1 შეცვალა ჯგუფის წევრობა $3-თვის',
@@ -3991,7 +4004,8 @@ MediaWiki ვრცელდება იმ იმედით, რომ ი
 'api-error-nomodule' => 'შიდა შეცდომა. ატვირთვის მოდული არ არის კონფიგურირებული.',
 'api-error-ok-but-empty' => 'შიდა შეცდომა. სერვერს არ დაუბრუნებია ინფორმაცია ატვირთვადი ფაილის შესახებ.',
 'api-error-overwrite' => 'არსებული ფაილის შეცვლა მიუღებელია.',
-'api-error-stashfailed' => 'შიდა შეცდომა. ვიკიმ ვერ შეძლო დროებით ფაილის შენახვა.',
+'api-error-stashfailed' => 'შიდა შეცდომა: სერვერმა ვერ შეძლო დროებითი ფაილის შენახვა.',
+'api-error-publishfailed' => 'შიდა შეცდომა: სერვერმა ვერ შეძლო დროებითი ფაილის შენახვა.',
 'api-error-timeout' => 'სერვერმა არ მოახდინა რეაგირება მოსალოდნელ დროში.',
 'api-error-unclassified' => 'აღმოჩენილია უცნობი შეცდომა.',
 'api-error-unknown-code' => 'უცნობი შეცდომა : „$1“',
index 989a16c..0c50033 100644 (file)
@@ -674,7 +674,7 @@ Beno ke [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} deletion log
 Sıma be idarekerênia ho ra şikinê hona [$1 nê ferqi bıvênê], eke wazenê dewam kerê.",
 'rev-delundel' => 'bıasne/wedare',
 'rev-showdeleted' => 'bıasne',
-'revisiondelete' => 'Çımraviarnaisu bıestere/peyser bia',
+'revisiondelete' => 'Çımraviarnaisu bestere/peyser bia',
 'revdelete-nooldid-title' => 'Çımraviarnaena waştiye nêvêrena',
 'revdelete-nooldid-text' => 'Sıma vırastena nê fonksiyoni rê ya jü çımraviarnaena waştiye diyar nêkerdo, çımraviarnaena diyarkerdiye çına, ya ki sıma wazenê ke çımraviarnaena nıkaêne bınımnê.',
 'revdelete-nologtype-title' => 'Qet qeydê cı nêdiya',
@@ -902,7 +902,7 @@ Kaberê bini ke şıma de kewti irtıbat, adresa e-postey şıma eşkera nêbena
 'right-move' => 'Pelu bere',
 'right-movefile' => 'Dosyu bere',
 'right-upload' => 'Dosyu bar ke',
-'right-delete' => 'Pelu bıestere',
+'right-delete' => 'Pelu bestere',
 'right-undelete' => 'Esterıtena na pele peyser bıcê',
 
 # Special:Log/newusers
@@ -921,7 +921,7 @@ Kaberê bini ke şıma de kewti irtıbat, adresa e-postey şıma eşkera nêbena
 'action-move' => 'na pele bere',
 'action-movefile' => 'na dosya bere',
 'action-upload' => 'na dosya bar ke',
-'action-delete' => 'na pele bıestere',
+'action-delete' => 'na pele bestere',
 'action-undelete' => 'na pele meestere',
 
 # Recent changes
@@ -1007,7 +1007,7 @@ Kaberê bini ke şıma de kewti irtıbat, adresa e-postey şıma eşkera nêbena
 'file-anchor-link' => 'Dosya',
 'filehist' => 'Tarixê dosya',
 'filehist-help' => "Serba diyaena viartê dosya tarixê ke qısımê tarix/zeman'i derê inu bıteqne.",
-'filehist-deleteall' => 'Pêrune bıestere',
+'filehist-deleteall' => 'Pêrune bestere',
 'filehist-deleteone' => 'bestere',
 'filehist-revert' => 'raçarne',
 'filehist-current' => 'nıkaên',
@@ -1036,8 +1036,8 @@ Cêr [$2 pela arezekerdena dosya de] arezekerdene asnina.',
 'filerevert-submit' => 'Raçarne',
 
 # File deletion
-'filedelete' => 'Bıestere $1',
-'filedelete-legend' => 'Dosya bıestere',
+'filedelete' => 'Bestere $1',
+'filedelete-legend' => 'Dosya bestere',
 'filedelete-comment' => 'Sebeb:',
 'filedelete-submit' => 'Bestere',
 'filedelete-otherreason' => 'Sebebo bin/ilaweki:',
@@ -1168,7 +1168,7 @@ Nara dıme, vurnaisê na pele u pela hurênaisê dawa alaqedare ita bena lista,
 'changed' => 'vuriya',
 
 # Delete
-'deletepage' => 'Pele bıestere',
+'deletepage' => 'Pele bestere',
 'delete-legend' => 'Bestere',
 'confirmdeletetext' => 'Tı hawo kena ke jü pele be tarixê dae pêro bıne ra bıesterê.
 Eke ferqê neticê na kerdene de bena u no kar be gorê [[{{MediaWiki:Policy-url}}|qeydunê esterıtene]] beno, wa gurêy tesdiq ke.',
@@ -1398,7 +1398,7 @@ Kerem ke, qeydkerdene ra ver gozaga verqayti bıgurene.',
 Tı şikina çımunê dae bıvênê',
 'tooltip-ca-history' => 'Versiyonê verênê na pele',
 'tooltip-ca-protect' => 'Na pele bısevekne',
-'tooltip-ca-delete' => 'Na pele bıestere',
+'tooltip-ca-delete' => 'Na pele bestere',
 'tooltip-ca-move' => 'Namê na pele bıvurne',
 'tooltip-ca-watch' => 'Na pele bıcê lista huya şêrkerdene',
 'tooltip-ca-unwatch' => 'Na pele lista huya şêrkerdene ra wedare',
index b50820f..76c8e2a 100644 (file)
@@ -1628,7 +1628,7 @@ $2',
 'whatlinkshere-hideredirs' => '$1 ಪುನರ್ನಿರ್ದೇಶನಗಳು',
 'whatlinkshere-hidetrans' => '$1 ಸೇರಿಸುವಿಕೆಗಳು',
 'whatlinkshere-hidelinks' => '$1 ಕೊಂಡಿಗಳು',
-'whatlinkshere-hideimages' => '$1 ಚಿತ್ರ ಕೊಂಡಿಗಳು',
+'whatlinkshere-hideimages' => '$1 ಚಿತ್ರ ಕೊಂಡಿಗಳು',
 'whatlinkshere-filters' => 'ಶೋಧಕಗಳು',
 
 # Block/unblock
index 6f53f2f..d42a7ae 100644 (file)
@@ -366,7 +366,7 @@ $messages = array(
 'tog-minordefault' => '사소한 편집을 기본적으로 선택하기',
 'tog-previewontop' => '편집 상자 앞에 미리 보기 보기',
 'tog-previewonfirst' => '처음 편집할 때 미리 보기 보기',
-'tog-nocache' => '브라우저의 문서 캐시 끄기',
+'tog-nocache' => '브라우저 문서 캐시 비활성화',
 'tog-enotifwatchlistpages' => '주시문서 목록에 속한 문서나 파일이 바뀌면 이메일로 알림',
 'tog-enotifusertalkpages' => '내 토론 문서가 바뀌면 이메일로 알림',
 'tog-enotifminoredits' => '문서나 파일의 사소한 편집도 이메일로 알림',
@@ -1408,7 +1408,7 @@ $1",
 'search-interwiki-default' => '$1 결과:',
 'search-interwiki-more' => '(더 보기)',
 'search-relatedarticle' => '관련',
-'mwsuggest-disable' => 'AJAX 검색어 제안 끄기',
+'mwsuggest-disable' => '찾기 제안 비활성화',
 'searcheverything-enable' => '모든 이름공간에서 찾기',
 'searchrelated' => '관련',
 'searchall' => '모두',
@@ -1780,9 +1780,9 @@ HTML 태그를 확인하세요.',
 [[Special:FileList|파일 목록]]에서 이전에 올라온 파일을 찾을 수 있습니다. [[Special:Log/upload|올리기 기록]]에는 파일이 올라온 기록이 남습니다. 삭제 기록은 [[Special:Log/delete|삭제 기록]]에서 볼 수 있습니다.
 
 문서에 파일을 넣으려면 아래 방법 중 하나를 사용하세요.
-* '''<code><nowiki>[[</nowiki>{{ns:file}}<nowiki>:File.jpg]]</nowiki></code>''' 파일의 온전한 모양을 사용하고자 할 때.
-* '''<code><nowiki>[[</nowiki>{{ns:file}}<nowiki>:File.png|200픽셀|섬네일|왼쪽|설명]]</nowiki></code>''' 파일의 넓이를 200픽셀로 하고 왼쪽 정렬하며 '설명' 이라는 주석을 파일 밑에 달 때.
-* '''<code><nowiki>[[</nowiki>{{ns:media}}<nowiki>:File.ogg]]</nowiki></code>''' 파일을 직접 보여주지 않고 파일로 바로 링크할때.",
+* '''<code><nowiki>[[</nowiki>{{ns:file}}<nowiki>:File.jpg]]</nowiki></code>''' 파일의 온전한 모양을 사용하고자 할 때
+* '''<code><nowiki>[[</nowiki>{{ns:file}}<nowiki>:File.png|200픽셀|섬네일|왼쪽|설명]]</nowiki></code>''' 파일의 넓이를 200픽셀로 하고 왼쪽 정렬하며 '설명' 이라는 주석을 파일 밑에 달 때
+* '''<code><nowiki>[[</nowiki>{{ns:media}}<nowiki>:File.ogg]]</nowiki></code>''' 파일을 직접 보여주지 않고 파일로 바로 링크할 때",
 'upload-permitted' => '허용하는 파일 확장자: $1',
 'upload-preferred' => '권장하는 파일 확장자: $1',
 'upload-prohibited' => '금지하는 파일 확장자: $1',
@@ -1839,14 +1839,14 @@ $2 형식만 사용할 수 있습니다.',
 'fileexists-extension' => '비슷한 이름의 파일이 존재합니다: [[$2|thumb]]
 * 올리려는 파일 이름: <strong>[[:$1]]</strong>
 * 존재하는 파일 이름: <strong>[[:$2]]</strong>
\8b¤ë¥¸ ì\9d´ë¦\84ì\9c¼ë¡\9c ì\8b\9cë\8f\84í\95´ ì£¼세요.',
\8b¤ë¥¸ ì\9d´ë¦\84ì\9c¼ë¡\9c ì\84 í\83\9dí\95\98세요.',
 'fileexists-thumbnail-yes' => '이 파일은 원본 그림이 아닌, 다른 그림의 크기를 줄인 섬네일 파일인 것 같습니다.
 [[$1|thumb]]
-<strong>[[:$1]]</strong> í\8c\8cì\9d¼ì\9d\84 í\99\95ì\9d¸í\95´ì£¼세요.
-해당 파일이 현재 올리려는 파일과 같다면, 더 작은 크기의 그림을 올릴 필요는 없습니다.',
+<strong>[[:$1]]</strong> í\8c\8cì\9d¼ì\9d\84 í\99\95ì\9d¸í\95\98세요.
+해당 파일이 현재 올리려는 파일과 같다면 더 작은 크기의 그림을 올릴 필요는 없습니다.',
 'file-thumbnail-no' => '파일 이름이 <strong>$1</strong>으로 시작합니다.
 이 파일은 원본 그림이 아닌, 다른 그림의 크기를 줄인 섬네일 파일인 것 같습니다.
\8d\94 í\95´ì\83\81ë\8f\84ê°\80 ì¢\8bì\9d\80 í\8c\8cì\9d¼ì\9d´ ì\9e\88ë\8b¤ë©´ ê·¸ í\8c\8cì\9d¼ì\9d\84 ì\98¬ë ¤ì£¼ì\84¸ì\9a\94. ì\95\84ë\8b\88ë©´ ì\98¬ë¦¬ë ¤ë\8a\94 í\8c\8cì\9d¼ ì\9d´ë¦\84ì\9d\84 ë°\94꾸ì\96´ ì£¼세요.',
\8d\94 í\95´ì\83\81ë\8f\84ê°\80 ì¢\8bì\9d\80 í\8c\8cì\9d¼ì\9d´ ì\9e\88ë\8b¤ë©´ ê·¸ í\8c\8cì\9d¼ì\9d\84 ì\98¬ë¦¬ê±°ë\82\98 ì\95\84ë\8b\88ë©´ ì\98¬ë¦¬ë ¤ë\8a\94 í\8c\8cì\9d¼ ì\9d´ë¦\84ì\9d\84 ë°\94꾸세요.',
 'fileexists-forbidden' => '같은 이름의 파일이 이미 있고, 덮어쓸 수 없습니다.
 그래도 파일을 올리시려면, 뒤로 돌아가서 다른 이름으로 시도해 주시기 바랍니다.
 [[File:$1|thumb|center|$1]]',
@@ -2302,7 +2302,7 @@ URL이 맞고 해당 웹사이트가 작동하는지 확인해주세요.',
 'cachedspecial-refresh-now' => '최신 버전 보기.',
 
 # Special:Categories
-'categories' => '분류',
+'categories' => '분류 목록',
 'categoriespagetext' => '{{PLURAL:$1}}문서나 자료를 담고 있는 분류 목록입니다.
 [[Special:UnusedCategories|사용되지 않는 분류]]는 여기에 보이지 않습니다.
 [[Special:WantedCategories|필요한 분류]]도 참고하세요.',
@@ -3232,8 +3232,9 @@ $1 사용자가 차단된 이유는 다음과 같습니다: "$2"',
 'pageinfo-robot-policy' => '검색 엔진 통계',
 'pageinfo-robot-index' => '색인 가능',
 'pageinfo-robot-noindex' => '색인 불가능',
-'pageinfo-views' => '읽힌 횟수',
+'pageinfo-views' => '읽은 수',
 'pageinfo-watchers' => '문서를 주시하는 사용자 수',
+'pageinfo-few-watchers' => '{{PLURAL:$1|주시하는 사용자}} $1명 미만',
 'pageinfo-redirects-name' => '이 문서로 넘겨주기',
 'pageinfo-redirects-value' => '$1개',
 'pageinfo-subpages-name' => '이 문서의 하위 문서',
@@ -3261,7 +3262,7 @@ $1 사용자가 차단된 이유는 다음과 같습니다: "$2"',
 'pageinfo-category-info' => '분류 정보',
 'pageinfo-category-pages' => '문서 수',
 'pageinfo-category-subcats' => '하위 분류 수',
-'pageinfo-category-files' => '파일 수',
+'pageinfo-category-files' => '파일 수',
 
 # Skin names
 'skinname-standard' => '클래식',
index 7fc0482..3fffafc 100644 (file)
@@ -872,6 +872,7 @@ Sedema qedexekirina $3 ev e: ''$2''",
 'datedefault' => 'Tercih tune ne',
 'prefs-beta' => "Taybetmendiyên Beta'yê",
 'prefs-datetime' => 'Dîrok û dem',
+'prefs-user-pages' => 'Rûpelên bikarhêner',
 'prefs-personal' => 'Profîla bikarhêner',
 'prefs-rc' => 'Guherandinên dawî',
 'prefs-watchlist' => 'Lîsteya şopandinê',
@@ -1025,6 +1026,7 @@ Sedema qedexekirina $3 ev e: ''$2''",
 'action-browsearchive' => 'li rûpelên jêbirî bigere',
 'action-undelete' => 'vê rûpelê dîsa çêke',
 'action-userrights' => 'hemû mafên bikarhêneran biguherîne',
+'action-sendemail' => 'e-nameyan bişîne',
 
 # Recent changes
 'nchanges' => '$1 {{PLURAL:$1|guherandinek|guherandin}}',
@@ -1648,6 +1650,7 @@ Sedemekê binivîse!",
 'unblockiptext' => "Nivîsara jêr bikarwîne ji bo qebûlkirina nivîsandinê bikarhênerekî ya IP'yeka berê astengkirî.",
 'ipusubmit' => 'Vê astengkirinê rake',
 'unblocked' => '[[User:$1|$1]] niha vê astengkirinê ye',
+'unblocked-range' => '$1 hat astengkirin.',
 'unblocked-id' => '$1 dîsa vê astengkirinê ye',
 'blocklist' => 'Bikarhênerên astengkirî',
 'ipblocklist' => "Listek ji adresên IP'yan û bikarhêneran yê hatine astengkirin",
@@ -1910,6 +1913,9 @@ Ji ber ku girêdaneke derve di wê rûpelê de heye ev pirsgirêk pêk hat.',
 'bydate' => 'li gor dîrokê',
 'sp-newimages-showfrom' => 'Daneyên nû ji dema $1, saet $2 ve bibîne',
 
+# Video information, used by Language::formatTimePeriod() to format lengths in the above messages
+'ago' => 'berî $1',
+
 # Variants for Kurdish language
 'variantname-ku-arab' => 'Tîpên erebî',
 'variantname-ku-latn' => 'Tîpên latînî',
@@ -2032,6 +2038,9 @@ Ji kerema xwe zanibe ku tu bi rastî dixwazî vê rûpelê dîsa çêkî.",
 'confirm_purge_button' => 'Baş e',
 'confirm-purge-top' => 'Bîra vê rûpelê jêbîbe ?',
 
+# action=watch/unwatch
+'confirm-watch-button' => 'Temam',
+
 # Multipage image navigation
 'imgmultipageprev' => '← rûpela berî vê',
 'imgmultipagenext' => 'rûpela din →',
index 2e1f405..346dd04 100644 (file)
@@ -13,6 +13,7 @@
  * @author Esteban97
  * @author Kaganer
  * @author LeighvsOptimvsMaximvs
+ * @author MF-Warburg
  * @author McDutchie
  * @author MissPetticoats
  * @author Omnipaedista
@@ -1650,7 +1651,7 @@ Si pagina nova cum ipso nomine post deletionem creata est, emendationes restitut
 'blanknamespace' => '(principale)',
 
 # Contributions
-'contributions' => 'Conlationes usoris',
+'contributions' => 'Conlationes {{GENDER:$1|usoris}}',
 'contributions-title' => 'Conlationes usoris $1',
 'mycontris' => 'Conlationes',
 'contribsub2' => 'Pro $1 ($2)',
index aefa70f..e49f297 100644 (file)
@@ -11,6 +11,7 @@
  * @author Kaffi
  * @author Kaganer
  * @author Les Meloures
+ * @author MF-Warburg
  * @author Purodha
  * @author Reedy
  * @author Robby
@@ -1205,7 +1206,7 @@ Denkt w.e.g drunn datt d'Navigatiounslinken d'Wiel vun de Versiounen nees zréck
 'search-interwiki-default' => '$1 Resultater:',
 'search-interwiki-more' => '(méi)',
 'search-relatedarticle' => 'A Verbindung',
-'mwsuggest-disable' => 'Ajax-Virschléi ausschalten',
+'mwsuggest-disable' => 'Sich-Virschléi ausschalten',
 'searcheverything-enable' => 'An allen Nummraim sichen',
 'searchrelated' => 'a Verbindng',
 'searchall' => 'all',
@@ -2148,7 +2149,7 @@ D\'E-Mailadress, déi Dir an [[Special:Preferences|Ären Astellungen]] aginn hut
 'usermessage-editor' => 'Benoriichtegungs-System',
 
 # Watchlist
-'watchlist' => 'Meng Iwwerwaachungslëscht',
+'watchlist' => 'Iwwerwaachungslëscht',
 'mywatchlist' => 'Iwwerwaachungslëscht',
 'watchlistfor2' => 'Vum $1 $2',
 'nowatchlist' => 'Är Iwwerwaachungslëscht ass eidel.',
@@ -2197,9 +2198,7 @@ All weider Ännerungen op dëser Säit an der assoziéierter Diskussiounssäit g
 'enotif_anon_editor' => 'Anonyme Benotzer $1',
 'enotif_body' => 'Léiwe $WATCHINGUSERNAME,
 
-D\'{{SITENAME}}-Säit "$PAGETITLE" gouf vum $PAGEEDITOR den $PAGEEDITDATE $CHANGEDORCREATED. Aktuell Versioun: $PAGETITLE_URL
-
-$NEWPAGE
+$PAGEINTRO $NEWPAGE
 
 Resumé vum Mataarbechter: $PAGESUMMARY $PAGEMINOREDIT
 
@@ -2208,21 +2207,22 @@ E-Mail: $PAGEEDITOR_EMAIL
 Wiki: $PAGEEDITOR_WIKI
 
 Et gi soulaang keng weider Maile geschéckt, bis Dir d\'Säit nees emol besicht hutt.
-Op Ärer Iwwerwaachungslëscht kënnt Dir all Benoorichtigungsmarkeren zesummen zrécksetzen.
+Op Ärer Iwwerwaachungslëscht kënnt Dir all Benoorichtigungsmarkeren zesummen zErécksetzen.
 
 
-             Äre frëndleche {{SITENAME}} Benoriichtigungssystem
+Äre frëndleche {{SITENAME}} Benoriichtigungssystem
 
 --
 
-Fir d\'Astellungen op Ã¤ren E-Mailbenoriichtigungen z\'änneren, besicht w.e.g.
+Fir d\'Astellungen op Ã\84ren E-Mailbenoriichtigungen z\'änneren, besicht w.e.g.
 {{canonicalurl:{{#special:Preferences}}}}
 
 
-Fir d\'Astellungen vun Ã¤rer Iwwerwaachungslëscht z\'änneren, besicht w.e.g.
+Fir d\'Astellungen vun Ã\84rer Iwwerwaachungslëscht z\'änneren, besicht w.e.g.
 {{canonicalurl:Special:Watchlist/edit}}
 
-
+Feedback a weider Hëllef:
+{{canonicalurl:{{MediaWiki:Helppage}}}}
 Fir d\'Säit vun Ärer Iwwerwaachungslëscht erofzehuelen, gitt w.e.g. op
 $UNWATCHURL
 
@@ -2413,7 +2413,7 @@ $1',
 'blanknamespace' => '(Haapt)',
 
 # Contributions
-'contributions' => 'Kontributioune vum Benotzer $1',
+'contributions' => 'Kontributioune {{GENDER:$1|vum Benotzer $1}}',
 'contributions-title' => 'Kontributioune vum $1',
 'mycontris' => 'Kontributiounen',
 'contribsub2' => 'Fir $1 ($2)',
@@ -2510,8 +2510,8 @@ Kuckt d'[[Special:BlockList|Spär-Lëscht]] fir all Spären nozekucken.",
 'unblocked' => "D'Spär fir de [[User:$1|Benotzer $1]] gouf opgehuewen",
 'unblocked-range' => "D'Spär vum $1 gouf opgehuewen",
 'unblocked-id' => "D'Spär $1 gouf opgehuewen",
-'blocklist' => 'Gespaarte Benotzer',
-'ipblocklist' => 'Gespaarte Benotzer',
+'blocklist' => 'Gespaart Benotzer',
+'ipblocklist' => 'Gespaart Benotzer',
 'ipblocklist-legend' => 'No engem gespaarte Benotzer sichen',
 'blocklist-userblocks' => 'Benotzerspäre verstoppen',
 'blocklist-tempblocks' => 'Temporär Späre verstoppen',
@@ -2609,18 +2609,18 @@ Fir d'Datebank ze spären oder fir d'Spär opzehiewen muss dëse Fichier vum Web
 # Move page
 'move-page' => 'Réckel $1',
 'move-page-legend' => 'Säit réckelen',
-'movepagetext' => "Wann dir dëse Formulaire benotzt, réckelt dir eng komplett Säit mat hirem Historique op en neien Numm.
+'movepagetext' => "Wann dir dëse Formulaire benotzt gitt Dir enger Säit en aneren Numm a réckelt se mat hirem Historique op den neien Numm.
 Den alen Titel gëtt eng Viruleedung op déi nei Säit.
 Dir kënnt Viruleedungen déi op déi al Säit ginn automatesch aktualiséieren.
 Wann Dir dat net maacht, da vergewëssert Iech datt keng [[Special:DoubleRedirects|duebel]] oder [[Special:BrokenRedirects|futtis Viruleedungen]] am Spill sinn.
 Dir sidd responsabel datt d'Linke weiderhin dohinner pointéieren, wou se hi sollen.
 
 Beuecht w.e.g. datt d'Säit '''net''' geréckelt gëtt, wann et schonns eng Säit mat deem Titel gëtt, ausser déi ass eidel, ass eng Viruleedung oder huet keen Historique.
-Dëst bedeit datt dir eng Säit zréck op hiren ursprénglechen Numm ëmbenenne kënnt wann Dir Iech geiert hat an datt dir keng Säit iwwerschreiwe kënnt, déi et schonns gëtt.
+Dëst bedeit datt dir eng Säit zréck op hiren ursprénglechen Numm ëmbenenne kënnt wann Dir Iech geiert hat an datt Dir keng Säit iwwerschreiwe kënnt, déi et schonns gëtt.
 
 '''OPGEPASST!'''
 Dëst kann en drastesche Changement fir eng populär Säit bedeiten;
-verstitt w.e.g. d'Konsequenze vun Ã¤rer Handlung Ã©ier Dir d'Säit réckelt.",
+verstitt w.e.g. d'Konsequenze vun Ã\84rer Handlung Ã©ier Dir dëst maacht.",
 'movepagetext-noredirectfixer' => "Wann Dir dëse Formulaire benotzt, réckelt dir eng komplett Säit mat hirem Historique op en neien Numm.
 Den alen Titel gëtt eng Viruleedung op den neien Titel.
 Dir kënnt Viruleedungen déi op déi al Säit ginn automatesch aktualiséieren.
@@ -2937,6 +2937,7 @@ Dëst warscheinlech duerch en externe Link den op der schwaarzer Lëscht (blackl
 'pageinfo-robot-noindex' => 'Net indexéierbar',
 'pageinfo-views' => 'Zuel vun de Kéieren déi dës Säit gekuckt gouf',
 'pageinfo-watchers' => "Zuel vun de Benotzer déi d'Säit iwwerwaachen",
+'pageinfo-few-watchers' => 'Manner wéi $1 {{PLURAL:$1|Benotzer deen iwwerwaacht|Benotzer déi iwwerwaachen}}',
 'pageinfo-redirects-name' => 'Viruleedungen op dës Säit',
 'pageinfo-subpages-name' => 'Ënnersäite vun dëser Säit',
 'pageinfo-subpages-value' => '$1 ($2 {{PLURAL:$2|Viruleedung|Viruleedungen}}; $3 {{PLURAL:$3|Ënnersäit|Ënnersäiten}})',
index 4863025..8d9160e 100644 (file)
@@ -279,7 +279,7 @@ $messages = array(
 'nstab-main' => 'Ччин',
 'nstab-user' => 'Уртахдин ччин',
 'nstab-media' => 'Медия ччин',
-'nstab-special' => 'Куьмекчи ччин',
+'nstab-special' => 'Квимекдин ччин',
 'nstab-project' => 'Проектдин ччин',
 'nstab-image' => 'Файл',
 'nstab-mediawiki' => 'Малумат',
@@ -597,7 +597,7 @@ $messages = array(
 'prefs-edits' => 'Дьузар хъувунрин кьадар',
 'prefsnologin' => 'Куьне гьахьнавач',
 'changepassword' => 'Парол дегишарун',
-'prefs-skin' => 'КЪайдадиз ттунин тема',
+'prefs-skin' => 'Къайдадиз ттунин тема',
 'skin-preview' => 'Сифтедин килигун',
 'datedefault' => 'Туькlуьрмир',
 'prefs-beta' => 'Бета-мумкинвилер',
@@ -613,7 +613,7 @@ $messages = array(
 'prefs-changeemail' => 'Э-почта дегишарун',
 'prefs-setemail' => 'Э-почта эцигна туькIуьрун',
 'prefs-email' => 'E-mail туькlуьрунин кьадарар',
-'prefs-rendering' => 'КЪецепатан  акунар',
+'prefs-rendering' => 'Къецепатан акунар',
 'saveprefs' => 'Хуьн',
 'resetprefs' => 'Хуьн тавунвай дегишвилер алудун',
 'restoreprefs' => 'Авайл хьиз кьунвай низамарунар туькIуьр хъувун',
@@ -1054,7 +1054,7 @@ $messages = array(
 'whatlinkshere-hideredirs' => '$1 рахкъурунар',
 'whatlinkshere-hidetrans' => '$1 кутунар',
 'whatlinkshere-hidelinks' => '$1 элячlунар',
-'whatlinkshere-hideimages' => '$1 Ñ\88икилÑ\80из Ñ\8dлÑ\8fÑ\87Ó\80унар',
+'whatlinkshere-hideimages' => '$1 Ñ\84аjлÑ\80ин Ñ\8dлаÑ\87lунар',
 'whatlinkshere-filters' => 'Куьзунагар',
 
 # Block/unblock
index a27eb2f..b58684d 100644 (file)
@@ -7,6 +7,7 @@
  * @ingroup Language
  * @file
  *
+ * @author Audriusa
  * @author Auwris
  * @author Break Through Pain
  * @author Dark Eagle
@@ -315,6 +316,7 @@ $messages = array(
 'newwindow' => '(atsidaro naujame lange)',
 'cancel' => 'Atšaukti',
 'moredotdotdot' => 'Daugiau...',
+'morenotlisted' => 'Daugiau nėra',
 'mypage' => 'Naudotojo puslapis',
 'mytalk' => 'Mano aptarimas',
 'anontalk' => 'Šio IP aptarimas',
@@ -338,7 +340,7 @@ $messages = array(
 'vector-action-protect' => 'Užrakinti',
 'vector-action-undelete' => 'Atkurti',
 'vector-action-unprotect' => 'Keisti apsaugą',
-'vector-simplesearch-preference' => 'Įjungti išplėstinius paieškos pasiūlymus (tik „Vector“ išvaizda)',
+'vector-simplesearch-preference' => 'Supaprastinta paieška (tik „Vector“ išvaizda)',
 'vector-view-create' => 'Kurti',
 'vector-view-edit' => 'Redaguoti',
 'vector-view-history' => 'Istorija',
@@ -500,9 +502,9 @@ Egzistuojančių specialiųjų puslapių sąrašą galite rasti [[Special:Specia
 # General errors
 'error' => 'Klaida',
 'databaseerror' => 'Duomenų bazės klaida',
-'dberrortext' => 'Įvyko duomenų bazės užklausos sintaksės klaida.
-Tai gali reikšti klaidą programinėje įrangoje.
-Paskutinė mėginta duomenų bazės užklausa buvo:
+'dberrortext' => 'Neteisinga duomenų bazės užklausos sintaksė.
+Galima klaida programinėje įrangoje.
+Paskutinė mėginta užklausa:
 <blockquote><tt>$1</tt></blockquote>
 iš funkcijos: „<tt>$2</tt>“.
 Duomenų bazė grąžino klaidą „<tt>$3: $4</tt>“.',
@@ -690,6 +692,7 @@ Palaukite prieš bandant vėl.',
 # E-mail sending
 'php-mail-error-unknown' => 'Nežinoma klaida PHP mail() funkcijoje',
 'user-mail-no-addy' => 'Bandyta išsiųsti elektroninį laišką be el. pašto adreso.',
+'user-mail-no-body' => 'Mėginta siųsti tuščia ar pernelyg trumpą E-pašto žinutė.',
 
 # Change password dialog
 'resetpass' => 'Keisti slaptažodį',
@@ -933,6 +936,8 @@ Greičiausiai jis yra ištrintas.',
 'edit-already-exists' => 'Negalima sukurti naujo puslapio.
 Jis jau egzistuoja.',
 'defaultmessagetext' => 'Numatytasis pranešimo tekstas',
+'invalid-content-data' => 'Neleistinas turinys.',
+'content-not-allowed-here' => 'Turinys "$1" puslapyje [[$2]] nėra leistinas.',
 
 # Content models
 'content-model-wikitext' => 'wikitekstas',
@@ -1089,7 +1094,8 @@ Prašome patikrinti sąrašus.',
 'revdelete-only-restricted' => 'Klaida slepiant $1 $2 elementą: jūs negalite paslėpti elementų nuo administratorių peržiūros nepasirenkant vieno iš kitų matomumo nustatymų.',
 'revdelete-reason-dropdown' => '*Dažnos trynimo priežastys
 ** Autorinių teisių pažeidimas
-** Netinkama asmeninė informacija
+** Netinkamas komentaras ar asmeninė informacija
+** Netinkamas naudotojo vardas
 ** Informacija, kuri gali būti šmeižikiška',
 'revdelete-otherreason' => 'Kita/papildoma priežastis:',
 'revdelete-reasonotherlist' => 'Kita priežastis',
@@ -2086,6 +2092,7 @@ Palaikomi protokolai: <code>$1</code> (nei vieno iš jų nenurodykite paieškoje
 'mailnologin' => 'Nėra adreso',
 'mailnologintext' => 'Jums reikia būti [[Special:UserLogin|prisijungusiam]] ir turi būti įvestas teisingas el. pašto adresas jūsų [[Special:Preferences|nustatymuose]], kad siųstumėte el. laiškus kitiems nautotojams.',
 'emailuser' => 'Rašyti laišką šiam naudotojui',
+'emailuser-title-target' => 'Siųsti E-pašto žinutę {{GENDER:$1|user}}',
 'emailuser-title-notarget' => 'El. pašto vartotojas',
 'emailpage' => 'Siųsti el. laišką naudotojui',
 'emailpagetext' => 'Jūs gali pasinaudoti šia forma norėdami nusiųsti el. laišką šiam naudotojui.
@@ -2158,6 +2165,16 @@ taip pat bus '''paryškinti''' [[Special:RecentChanges|naujausių keitimų sąra
 'enotif_mailer' => '{{SITENAME}} Pranešimų sistema',
 'enotif_reset' => 'Pažymėti visus puslapius kaip aplankytus',
 'enotif_impersonal_salutation' => '{{SITENAME}} naudotojau',
+'enotif_subject_deleted' => '{{GENDER:$2|Naudotojas}} ištrynė puslapį $1, priklausantį projektui {{SITENAME}}',
+'enotif_subject_created' => '{{GENDER:$2|Naudotojas}} sukūrė puslapį $1, priklausantį projektui {{SITENAME}}',
+'enotif_subject_moved' => '{{GENDER:$2|Naudotojas}} pervardino puslapį $1, priklausantį projektui {{SITENAME}}',
+'enotif_subject_restored' => '{{GENDER:$2|Naudotojas}} atstatė puslapį $1, priklausantį projektui {{SITENAME}}',
+'enotif_subject_changed' => '{{GENDER:$2|Naudotojas}} redagavo puslapį $1, priklausantį projektui {{SITENAME}}',
+'enotif_body_intro_deleted' => '$PAGEEDITDATE {{GENDER:$2|Naudotojas}} ištrynė puslapį $1, priklausantį projektui {{SITENAME}}, žr.                     $3.',
+'enotif_body_intro_created' => '$PAGEEDITDATE {{GENDER:$2|Naudotojas}} sukūrė puslapį $1, priklausantį projektui {{SITENAME}}. Dabartinė versija matoma $3.',
+'enotif_body_intro_moved' => '$PAGEEDITDATE {{GENDER:$2|Naudotojas}} pervardino puslapį $1, priklausantį projektui {{SITENAME}}. Dabartinė versija matoma $3.',
+'enotif_body_intro_restored' => '$PAGEEDITDATE {{GENDER:$2|Naudotojas}} atstatė puslapį $1, priklausantį projektui {{SITENAME}}. Dabartinė versija matoma $3.',
+'enotif_body_intro_changed' => '$PAGEEDITDATE {{GENDER:$2|Naudotojas}} redagavo puslapį $1, priklausantį projektui {{SITENAME}}. Dabartinė versija matoma $3.',
 'enotif_lastvisited' => 'Užeikite į $1, jei norite matyti pakeitimus nuo paskutiniojo apsilankymo.',
 'enotif_lastdiff' => 'Užeikite į $1, jei norite pamatyti šį pakeitimą.',
 'enotif_anon_editor' => 'anoniminis naudotojas $1',
@@ -2261,6 +2278,8 @@ Dabar veikiančių puslapių apsaugų sąrašą rasite [[Special:ProtectedPages|
 'prot_1movedto2' => '[[$1]] pervadintas į [[$2]]',
 'protect-badnamespace-title' => 'Neapsaugota vardų sritis',
 'protect-badnamespace-text' => 'Puslapiai šioje vardų srityje negali būti apsaugoti.',
+'protect-norestrictiontypes-text' => 'Šis puslapis negali būti apsaugotas nes neturi galimų apribojimų tipų.',
+'protect-norestrictiontypes-title' => 'Neapsaugomas puslapis',
 'protect-legend' => 'Užrakinimo patvirtinimas',
 'protectcomment' => 'Priežastis:',
 'protectexpiry' => 'Baigia galioti:',
@@ -2926,6 +2945,10 @@ Leidžia pridėti atmetimo priežastį komentaruose',
 'pageinfo-contentpage' => 'Priskirtas turinio puslapiams',
 'pageinfo-contentpage-yes' => 'Taip',
 'pageinfo-protect-cascading-yes' => 'Taip',
+'pageinfo-category-info' => 'Informacija apie kategoriją',
+'pageinfo-category-pages' => 'Puslapių skaičius',
+'pageinfo-category-subcats' => 'Dukterinių kategorijų skaičius',
+'pageinfo-category-files' => 'Failų skaičius',
 
 # Skin names
 'skinname-standard' => 'Klasikinė',
@@ -2948,6 +2971,8 @@ Leidžia pridėti atmetimo priežastį komentaruose',
 'markedaspatrollederror' => 'Negalima pažymėti, kad patikrinta',
 'markedaspatrollederrortext' => 'Jums reikia nurodyti versiją, kurią pažymėti kaip patikrintą.',
 'markedaspatrollederror-noautopatrol' => 'Jums neleidžiama pažymėti savo paties keitimų kaip patikrintų.',
+'markedaspatrollednotify' => '$1 keitimas pažymėtas patikrintu.',
+'markedaspatrollederrornotify' => 'Nepavyko pažymėti kaip patikrinto.',
 
 # Patrol log
 'patrol-log-page' => 'Patikrinimų sąrašas',
@@ -3622,6 +3647,7 @@ Jūs taip pat galite [[Special:EditWatchlist|naudoti standartinį redaktorių]].
 'version-license' => 'Licencija',
 'version-poweredby-credits' => "Šis projektas naudoja '''[//www.mediawiki.org/ MediaWiki]''', autorystės teisės © 2001-$1 $2.",
 'version-poweredby-others' => 'kiti',
+'version-credits-summary' => 'Už indėlį kuriant [[Special:Version|MediaWiki]] dėkojame',
 'version-license-info' => 'MediaWiki yra nemokama programinė įranga; galite ją platinti ir/arba modifikuoti pagal GNU General Public License, kurią publikuoja Free Software Foundation; taikoma 2-oji licenzijos versija arba (Jūsų pasirinkimu) bet kuri vėlesnė versija. 
 
 MediaWiki yra platinama su viltimi, kad ji bus naudinga, bet BE JOKIOS GARANTIJOS; be jokios numanomos PARDAVIMO arba TINKAMUMO TAM TIKRAM TIKSLUI garantijos. Daugiau informacijos galite sužinoti GNU General Public License. 
@@ -3764,6 +3790,7 @@ Paveikslėliai yra rodomi pilna raiška, kiti failų tipai paleidžiami tiesiogi
 'logentry-newusers-newusers' => '$1 sukūrė naudotojo paskyrą',
 'logentry-newusers-create' => '$1 sukūrė naudotojo paskyrą',
 'logentry-newusers-create2' => '$1 sukūrė naudotojo paskyrą $3',
+'logentry-newusers-byemail' => 'Naudotojas $1 sukūrė paskyrą $3, slaptažodis išsiųstas E-paštu.',
 'logentry-newusers-autocreate' => 'Paskyra $1 buvo sukurta automatiškai',
 'logentry-rights-rights' => '$1 pakeista narystė grupėje $3 iš $4 į $5',
 'logentry-rights-rights-legacy' => '$1 pakeista narystė grupėje $3',
@@ -3788,6 +3815,7 @@ Kitu atveju, galite naudotis žemiau esančia paprastesne forma. Jūsų komentar
 
 # Search suggestions
 'searchsuggest-search' => 'Ieškoti',
+'searchsuggest-containing' => 'turintys',
 
 # API errors
 'api-error-badaccess-groups' => 'Jums neleidžiama įkelti failus į šią wiki.',
index 5722a74..050dc83 100644 (file)
@@ -8,6 +8,7 @@
  * @file
  *
  * @author Alno
+ * @author Hoo
  * @author Jagwar
  * @author The Evil IP address
  * @author Urhixidur
@@ -863,8 +864,8 @@ Raha toa moa ka tsy nieritreritra ny hamorona ity takelaka ity ianao dia miveren
 'anontalkpagetext' => "----<i>Ity pejy ity dia pejin-dresak'olona tsy nanokatra na tsy nampiasa ny kaontiny.
 Noho izany dia ilainay ny mampiasa ny adiresy IP-ny hanondroana azy. Mety zarazarain'olona maro ny adiresy IP iray. Raha mpikambana tsy nisoratra anarana ianao, ka raha mahita resaka ts ho anao, azonao atao ny [[Special:UserLogin/signup|manokatra kaonty]], na [[Special:UserLogin|miditra]] mba tsy ho voafangarao amin'ny mpikambana hafa tsy nisoratra anarana.</i>",
 'noarticletext' => "'''Tsy mbola nisy namorona io lahatsoratra io.
-Azonao atao ny [[Special:Search/{{PAGENAME}}||Tadiavo ny momba ny {{PAGENAME}}]].'''
-* '''[{{SERVER}}{{localurl:{{NAMESPACE}}:{{PAGENAME}}|action=edit}} Na forony eto ny lahatsoratra momba ny {{PAGENAME}}]'''.",
+Azonao atao ny [[Special:Search/{{PAGENAME}}|Tadiavo ny momba ny {{PAGENAME}}]].'''
+* '''[{{fullurl:{{FULLPAGENAME}}|action=edit}} Na forony eto ny lahatsoratra momba ny {{PAGENAME}}]'''.",
 'noarticletext-nopermission' => "Mbola tsy misy lahatsoratra ao amin'io pejy io.
 
 Azonao atao ny [[Special:Search/{{PAGENAME}}|mikaroka ity lohateny ity]] eny amin'ny pejy hafa na <span class=\"plainlinks\">[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} mitady ao amin'ny laogy misy fifandraisana]</span>, fa tsy azonao atao ny mamorona ity pejy ity.",
@@ -1988,7 +1989,7 @@ Aza manadino manamarina raha tsy misy rohy makany amin'ny endrika hafa alohan'ny
 'listusers-creationsort' => "Afantina amin'ny daty fanokafana",
 'usereditcount' => 'fanovana $1 {{PLURAL:}}',
 'usercreated' => "Noforonina ny {{GENDER:$3}} $1 tamin'ny $2",
-'newpages' => 'pejy Vaovao',
+'newpages' => 'Pejy vaovao',
 'newpages-username' => 'Solonanarana:',
 'ancientpages' => 'Ireo pejy tranainy indrindra',
 'move' => 'Hamindra azy toerana',
@@ -3306,7 +3307,7 @@ Aseho amin'ny tena habeny ny sary aseho, ny hafa dia alefa miaraka amin'ny rindr
 'logentry-newusers-newusers' => 'Noforonina ny kaontim-pikambana $1',
 'logentry-newusers-create' => 'Noforonina ny kaontim-pikambana $1',
 'logentry-newusers-create2' => "Noforonin'i $1 ny kaomtim-pikambana $3",
-'logentry-newusers-autocreate' => 'Noforonina ho azy ny kaontim-pikambana $&',
+'logentry-newusers-autocreate' => 'Noforonina ho azy ny kaontim-pikambana $1',
 'logentry-rights-rights' => "$1 dia nanova ny sokajim-pikambana isian'i $3 avy amin'ny $4 lasa $5",
 'logentry-rights-rights-legacy' => "$1 nanova ny vonodrom-pikambana isian'i $3",
 'logentry-rights-autopromote' => 'Lasa $5 ho azy i $1 izay $4 taloha',
index 050deb4..081bc4c 100644 (file)
@@ -25,47 +25,47 @@ $namespaceNames = array(
 
 $messages = array(
 # User preference toggles
-'tog-underline' => 'Garih bawahi link:',
+'tog-underline' => 'Garih bawahi tautan:',
 'tog-justify' => 'Ratokan paragraf',
 'tog-hideminor' => 'Suruakkan suntingan ketek di parubahan tabaru',
 'tog-hidepatrolled' => 'Suruakkan suntingan nan lah dijago di parubahan tabaru',
-'tog-newpageshidepatrolled' => 'Suruakkan halaman nan lah dijago dari senarai halaman baru',
-'tog-extendwatchlist' => 'Kambangkan senarai pantauan untuak malihek sado parubahan, indak nan baru se',
-'tog-usenewrc' => 'Kalompok parubahan dek laman dalam parubahan tabaru jo daftar pantauan (paralu JavaScript)',
+'tog-newpageshidepatrolled' => 'Suruakkan laman nan lah dijago dari dafta laman baru',
+'tog-extendwatchlist' => 'Kambangkan dafta pantauan untuak malihek sado parubahan, indak nan baru se',
+'tog-usenewrc' => 'Gunokan tampilan parubahan tingkek lanjuik (paralu JavaScript)',
 'tog-numberheadings' => 'Agiah nomor judua sacaro otomatis',
 'tog-showtoolbar' => 'Tampilkan bilah suntiang (paralu JavaScript)',
-'tog-editondblclick' => 'Suntiang laman jo klik ganda (JavaScript)',
-'tog-editsection' => 'Fungsikan penyuntingan subbagian malalui [sunting] pranala',
-'tog-editsectiononrightclick' => 'Hiduikan bagian panyuntiangan jo mangklik kanan pado judul bagian (JavaScript)',
-'tog-showtoc' => 'Caliakkan dafta isi (untuak laman nan mampunyoi labiah dari 3 subbagian)',
-'tog-rememberpassword' => 'Kana log masuak denai di peramban ko (salamo $1 {{PLURAL:$1|hari|hari}})',
-'tog-watchcreations' => 'Tambahkan laman nan den buek jo gambar nan den unggah ka daftar pantauan',
-'tog-watchdefault' => 'Tambahkan laman jo gambar nan den suntiang ka daftar pantauan',
-'tog-watchmoves' => 'Tambahkan laman jo gambar nan den pindah ka daftar pantauan',
-'tog-watchdeletion' => 'Tambahkan laman jo gambar nan den hapuih ka daftar pantauan',
+'tog-editondblclick' => 'Suntiang laman jo klik duo kali (paralu JavaScript)',
+'tog-editsection' => 'Fungsikan penyuntiangan subbagian malalui [sunting] tautan',
+'tog-editsectiononrightclick' => 'Hiduikkan bagian panyuntiangan jo mangklik kanan pado judul bagian (paralu JavaScript)',
+'tog-showtoc' => 'Tunjuakkan dafta isi (untuak laman nan labiah dari 3 subbagian)',
+'tog-rememberpassword' => 'Ingek log masuak denai di paramban ko (salamo $1 {{PLURAL:$1|hari}})',
+'tog-watchcreations' => 'Tambahkan laman nan den buek jo gambar nan den unggah ka dafta pantauan',
+'tog-watchdefault' => 'Tambahkan laman jo gamba nan den suntiang ka dafta pantauan',
+'tog-watchmoves' => 'Tambahkan laman jo gamba nan den pindah ka dafta pantauan',
+'tog-watchdeletion' => 'Tambahkan laman jo gamba nan den hapuih ka dafta pantauan',
 'tog-minordefault' => 'Tandoi sadoalah suntiangan sabagai suntiangan ketek sacaro baku',
 'tog-previewontop' => 'Tampilkan pratonton sabalun kotak suntiang',
-'tog-previewonfirst' => 'Caliakkan pratayang pado suntiangan patamo',
-'tog-nocache' => 'Matikan panyinggahan laman peramban',
-'tog-enotifwatchlistpages' => 'Kirimkan surel kalau laman atau gambar pado daftar pantauan lah barubah',
-'tog-enotifusertalkpages' => 'E-mail ambo jiko laman barundiang denai lah barubah',
+'tog-previewonfirst' => 'Tunjuakkan pratonton pado suntiangan patamo',
+'tog-nocache' => 'Matikan panyinggahan laman paramban',
+'tog-enotifwatchlistpages' => 'Kirimkan surel, kalau laman atau gambar pado daftar pantauan den lah barubah',
+'tog-enotifusertalkpages' => "Kirimkan denai surel ko' laman diskusi den lah barubah",
 'tog-enotifminoredits' => 'Kirimkan surel juo untuk saketek suntingan pado laman jo gambar',
-'tog-enotifrevealaddr' => 'Cogokan alamaik e-mail den pado e-mail notifikasi',
-'tog-shownumberswatching' => 'Tujuakkan jumlah pamantau',
+'tog-enotifrevealaddr' => 'Tunjuakkan alamaik surel ambo pado pambaritauan surel',
+'tog-shownumberswatching' => 'Tunjuakkan jumlah pamantau',
 'tog-oldsig' => 'Tando tangan kini:',
-'tog-fancysig' => 'Palakuan tando tangan sabagai teks wiki (tanpa suatu tautan otomatis)',
-'tog-externaleditor' => 'Gunokan editor eksternal sacaro bawaan (untuak nan ahli sajo, kabutuahan pangaturan khusus pado komputer Sanak [//www.mediawiki.org/wiki/Manual:External_editors Informasi labiah lanjuik.].)',
+'tog-fancysig' => 'Jadikan tando tangan manjadi teks wiki (indak jo tautan otomatis)',
+'tog-externaleditor' => 'Gunokan editor dari lua sacaro bawaan (untuak nan ahli sajo, butuah pangaturan khusus di komputer Sanak [//www.mediawiki.org/wiki/Manual:External_editors Informasi labiah lanjuik.])',
 'tog-externaldiff' => 'Gunokan diff eksternal sacaro bawaan (untuak nan ahli sajo, kabutuahan pangaturan khusus pado komputer Sanak [//www.mediawiki.org/wiki/Manual:External_editors Informasi labiah lanjuik.].)',
 'tog-showjumplinks' => 'Aktifkan tautan pambantu "langsuang ka"',
 'tog-uselivepreview' => 'Gunokan pratayang langsuang (JavaScript) (eksperimental)',
 'tog-forceeditsummary' => 'Ingekkan awak bilo kotak ringkasan suntiangan masih kosoang',
-'tog-watchlisthideown' => 'Sambunyikan suntiangan awak di dafta pantauan',
-'tog-watchlisthidebots' => 'Sambunyikan suntiangan bot di dafta pantauan',
-'tog-watchlisthideminor' => 'Sambunyikan suntiangan ketek di dafta pantauan',
-'tog-watchlisthideliu' => 'Sambunyikan suntiangan pangguno masuak log di dafta pantauan',
-'tog-watchlisthideanons' => 'Sambunyikan suntiangan pangguno indak di kana di dafta pantauan',
-'tog-watchlisthidepatrolled' => 'Sambunyikan suntiangan tapatroli di dafta pantauan',
-'tog-ccmeonemails' => 'Kiriman awak salinan surel nan awak kiriman ka urang lain',
+'tog-watchlisthideown' => 'Suruakkan suntiangan surang di dafta pantauan',
+'tog-watchlisthidebots' => 'Suruakkan suntiangan bot di dafta pantauan',
+'tog-watchlisthideminor' => 'Suruakkan suntiangan ketek di dafta pantauan',
+'tog-watchlisthideliu' => 'Suruakkan suntiangan pangguno masuak log di dafta pantauan',
+'tog-watchlisthideanons' => 'Suruakkan suntiangan pangguno indak di kana di dafta pantauan',
+'tog-watchlisthidepatrolled' => 'Suruakkan suntiangan tapatroli di dafta pantauan',
+'tog-ccmeonemails' => 'Kiriman awak salinan surel nan dikiriman ka urang lain',
 'tog-diffonly' => 'Jan tampilan isi laman di bawah pabedoan suntiangan',
 'tog-showhiddencats' => 'Tampilan kategori tasambunyi',
 'tog-norollbackdiff' => 'Jan tampilan pabedoan sasudah malakukan pangambalian',
@@ -87,7 +87,7 @@ $messages = array(
 'tuesday' => 'Salaso',
 'wednesday' => "Raba'a",
 'thursday' => 'Kamih',
-'friday' => 'Jumek',
+'friday' => 'Jumaik',
 'saturday' => 'Sabtu',
 'sun' => 'Min',
 'mon' => 'Sin',
@@ -106,7 +106,7 @@ $messages = array(
 'august' => 'Agustus',
 'september' => 'September',
 'october' => 'Oktober',
-'november' => 'November',
+'november' => 'Nopember',
 'december' => 'Desember',
 'january-gen' => 'Januari',
 'february-gen' => 'Pebruari',
@@ -118,7 +118,7 @@ $messages = array(
 'august-gen' => 'Agustus',
 'september-gen' => 'September',
 'october-gen' => 'Oktober',
-'november-gen' => 'November',
+'november-gen' => 'Nopember',
 'december-gen' => 'Desember',
 'jan' => 'Jan',
 'feb' => 'Peb',
@@ -127,50 +127,50 @@ $messages = array(
 'may' => 'Mai',
 'jun' => 'Jun',
 'jul' => 'Jul',
-'aug' => 'Agu',
+'aug' => 'Ags',
 'sep' => 'Sep',
 'oct' => 'Okt',
-'nov' => 'Nov',
+'nov' => 'Nop',
 'dec' => 'Des',
 
 # Categories related messages
-'pagecategories' => '{{PLURAL:$1|Kategori|Kategori}}',
+'pagecategories' => '{{PLURAL:$1|Kategori}}',
 'category_header' => 'Laman dalam kategori "$1"',
 'subcategories' => 'Subkategori',
 'category-media-header' => 'Laman/Media dalam kategori "$1"',
-'category-empty' => "''Kini ko, indak ado terdapat laman ataupun media dalam kategori iko.''",
-'hidden-categories' => '{{PLURAL:$1|Kategori tapandam|Kategori tapandam}}',
+'category-empty' => "''Kini ko, indak ado laman ataupun media dalam kategori ko.''",
+'hidden-categories' => '{{PLURAL:$1|Kategori tapandam}}',
 'hidden-category-category' => 'Kategori tasambunyi',
-'category-subcat-count' => '{{PLURAL:$2|Kategori ko hanyo punyo subkategori berikut.|Kategori ko punyo {{PLURAL:$1|subkategori|$1 subkategori}}, dari total $2.}}',
-'category-subcat-count-limited' => 'Kategori iko mamiliki {{PLURAL:$1|subkategori|$1 subkategori}} barikuik.',
-'category-article-count' => '{{PLURAL:$2|Kategori ko hanyo punyo laman berikut.|Kategori ko punyo  {{PLURAL:$1|laman|$1 laman}} dari total $2.}}',
-'category-article-count-limited' => 'Kategori iko mamiliki {{PLURAL:$1|ciek laman|$1 laman}} barikuik.',
-'category-file-count' => '{{PLURAL:$2|Kategori iko hanyo mamiliki ciek laman barikuik.|Kategori iko mamiliki {{PLURAL:$1|laman|$1 laman}} barikuik, dari total $2.}}',
-'category-file-count-limited' => 'Kategori iko mamiliki {{PLURAL:$1|laman|$1 laman}} barikuik.',
-'listingcontinuesabbrev' => 'lanjuik',
+'category-subcat-count' => '{{PLURAL:$2|Kategori ko punyo {{PLURAL:$1|$1 subkategori}}, dari total $2.}}',
+'category-subcat-count-limited' => 'Kategori iko mamiliki {{PLURAL:$1|$1 subkategori}} barikuik.',
+'category-article-count' => '{{PLURAL:$2|Kategori ko punyo {{PLURAL:$1|$1 laman}}, dari total $2.}}',
+'category-article-count-limited' => 'Kategori iko mamiliki {{PLURAL:$1|$1 laman}} barikuik.',
+'category-file-count' => '{{PLURAL:$2|Kategori ko ado {{PLURAL:$1|$1 laman}}, dari $2 laman.}}',
+'category-file-count-limited' => 'Kategori iko mamiliki {{PLURAL:$1|$1 laman}} barikuik.',
+'listingcontinuesabbrev' => 'samb.',
 'index-category' => 'Laman nan diindeks',
 'noindex-category' => 'Laman nan indak diindeks',
-'broken-file-category' => 'Laman jo gambar rusak',
+'broken-file-category' => 'Laman jo gamba rusak',
 
-'about' => 'Tentang',
+'about' => 'Perihal',
 'article' => 'Artikel',
-'newwindow' => '(buka di jandela baru)',
+'newwindow' => '(bukak di jandela baru)',
 'cancel' => 'Batalkan',
 'moredotdotdot' => 'Lainnyo...',
 'morenotlisted' => 'Salabiahnyo...',
 'mypage' => 'Laman',
 'mytalk' => 'Maota',
-'anontalk' => 'Ota IP iko',
+'anontalk' => 'Diskusi IP ko',
 'navigation' => 'Pinteh',
 'and' => '&#32;jo',
 
 # Cologne Blue skin
-'qbfind' => 'Pencarian',
-'qbbrowse' => 'Browse',
+'qbfind' => 'Pancarian',
+'qbbrowse' => 'Jalajah',
 'qbedit' => 'Suntiang',
 'qbpageoptions' => 'Laman ko',
 'qbmyoptions' => 'Laman denai',
-'qbspecialpages' => 'Halaman istimewa',
+'qbspecialpages' => 'Laman istimewa',
 'faq' => 'FAQ',
 'faqpage' => 'Project:FAQ',
 
@@ -178,21 +178,21 @@ $messages = array(
 'vector-action-addsection' => 'Bagian baru',
 'vector-action-delete' => 'Hapuih',
 'vector-action-move' => 'Pindahkan',
-'vector-action-protect' => 'Lindungi',
+'vector-action-protect' => 'Linduangkan',
 'vector-action-undelete' => 'Pambatalan panghapusan',
 'vector-action-unprotect' => 'Tuka palinduangan',
 'vector-simplesearch-preference' => 'Aktifkan kotak pancarian sadarano (hanyo kulik Vector)',
 'vector-view-create' => 'Buek',
 'vector-view-edit' => 'Suntiang',
-'vector-view-history' => 'Caliak riwayaik nan lalu',
+'vector-view-history' => 'Riwayaik lalu',
 'vector-view-view' => 'Baco',
 'vector-view-viewsource' => 'Caliak sumber',
 'actions' => 'Tindakan',
 'namespaces' => 'Ruang namo:',
-'variants' => 'Variasi:',
+'variants' => 'Varian:',
 
 'navigation-heading' => 'Menu navigasi',
-'errorpagetitle' => 'Kesalahan',
+'errorpagetitle' => 'Kasalahan',
 'returnto' => 'Baliak ka $1',
 'tagline' => 'Dari {{SITENAME}}',
 'help' => 'Bantuan',
@@ -200,11 +200,11 @@ $messages = array(
 'searchbutton' => 'Cari',
 'go' => 'Tuju',
 'searcharticle' => 'Tuju',
-'history' => 'Riwayaik halaman',
+'history' => 'Riwayaik laman',
 'history_short' => 'Riwayaik',
 'updatedmarker' => 'diubah sajak kunjuangan tarakhir ambo',
 'printableversion' => 'Versi cetak',
-'permalink' => 'Pranala parmanen',
+'permalink' => 'Pranala permanen',
 'print' => 'Cetak',
 'view' => 'Tampilkan',
 'edit' => 'Suntiang',
@@ -215,16 +215,16 @@ $messages = array(
 'deletethispage' => 'Hapuih laman iko',
 'undelete_short' => 'Batal hapuih $1 {{PLURAL:$1|suntiangan|suntiangan}}',
 'viewdeleted_short' => 'Liek {{PLURAL:$1|ciek suntiangan|$1 suntiangan}} nan dihapuih',
-'protect' => 'Lindungi',
+'protect' => 'Linduangkan',
 'protect_change' => 'ubah',
 'protectthispage' => 'Lindungi laman iko',
 'unprotect' => 'Tuka palinduangan',
 'unprotectthispage' => 'Tuka palindungan laman ko',
 'newpage' => 'Laman baru',
 'talkpage' => 'Musyawarahkan laman ko',
-'talkpagelinktext' => 'Maota',
+'talkpagelinktext' => 'maota',
 'specialpage' => 'Laman istimewa',
-'personaltools' => 'Pakakeh paribadi',
+'personaltools' => 'Pakakeh pribadi',
 'postcomment' => 'Bagian baru',
 'articlepage' => 'Liek isi laman',
 'talk' => 'Rundiang',
@@ -237,7 +237,7 @@ $messages = array(
 'templatepage' => 'Caliak laman templat',
 'viewhelppage' => 'Caliak laman bantuan',
 'categorypage' => 'Caliak laman kategori',
-'viewtalkpage' => 'Caliak laman ota',
+'viewtalkpage' => 'Caliak laman diskusi',
 'otherlanguages' => 'Dalam bahaso lain',
 'redirectedfrom' => '(Dialiahkan dari $1)',
 'redirectpagesub' => 'Laman pengalihan',
@@ -248,8 +248,8 @@ $messages = array(
 'jumptonavigation' => 'pinteh',
 'jumptosearch' => 'cari',
 'view-pool-error' => 'Maaf, server sadang sibuak pado kini ko.
-Talalu banyak pangguno barusaho mancaliak laman iko.
-Tunggu sabanta sabalum Sanak mancubo baliak mangakses laman iko.
+Talalu banyak pangguno barusaho mancaliak laman ko.
+Tunggu sabanta sabalum Sanak mancubo baliak mangakses laman ko.
 
 $1',
 'pool-timeout' => 'Lewat waktu manunggu kunci',
@@ -267,32 +267,32 @@ $1',
 'disclaimerpage' => 'Project:Sanggahan umum',
 'edithelp' => 'Bantuan suntiangan',
 'edithelppage' => 'Help:Suntingan',
-'helppage' => 'Help:Takadia',
-'mainpage' => 'Laman Utamo',
-'mainpage-description' => 'Laman utamo',
+'helppage' => 'Help:Isi',
+'mainpage' => 'Palanta',
+'mainpage-description' => 'Palanta',
 'policy-url' => 'Project:Kabijakan',
 'portal' => 'Portal komunitas',
 'portal-url' => 'Project:Portal komunitas',
 'privacy' => 'Kecipehan privasi',
 'privacypage' => 'Project:Kecipehan privasi',
 
-'badaccess' => 'Kesalahan hak akses',
-'badaccess-group0' => 'Sanak indak diizinkan untuak malakukan tindakan nan Sanak minta.',
-'badaccess-groups' => 'Tindakan nan Sanak minta dibatasi untuak pangguno dalam {{PLURAL:$2|kalompok|ciek dari kelompok}}: $1.',
+'badaccess' => 'Kasalahan hak akses',
+'badaccess-group0' => 'Sanak indak diizinkan untuak malakukan tindakan nan Sanak nio.',
+'badaccess-groups' => 'Tindakan nan Sanak nio dibatasi untuak pangguno dalam {{PLURAL:$2|kalompok}}: $1.',
 
 'versionrequired' => 'Dibutuahkan MediaWiki versi $1',
-'versionrequiredtext' => 'MediaWiki versi $1 dibutuahkan untuak manggunokan laman ijo. Caliak [[Special:Version|laman versi]]',
+'versionrequiredtext' => 'MediaWiki versi $1 dibutuahkan untuak manggunokan laman ko. Caliak [[Special:Version|versi laman]]',
 
 'ok' => 'OK',
 'retrievedfrom' => 'Didapek dari "$1"',
 'youhavenewmessages' => 'Awak punyo $1 ($2).',
 'newmessageslink' => 'pasan baru',
-'newmessagesdifflink' => 'parubahan terakhir',
-'youhavenewmessagesfromusers' => 'Sanak mandapek $1 dari {{PLURAL:$3|another user|$3 users}} ($2)',
+'newmessagesdifflink' => 'parubahan tarakhia',
+'youhavenewmessagesfromusers' => 'Sanak mandapek $1 dari {{PLURAL:$3|$3 pangguno}} ($2)',
 'youhavenewmessagesmanyusers' => 'Sanak mandapek $1 dari banyak pangguno ($2)',
-'newmessageslinkplural' => '{{PLURAL:$1|sabuah pasan baru|pasan baru}}',
+'newmessageslinkplural' => '{{PLURAL:$1|pasan baru}}',
 'newmessagesdifflinkplural' => '{{PLURAL:$1|parubahan}} taakhia',
-'youhavenewmessagesmulti' => 'Awak ang mandapek pasan baru pado $1',
+'youhavenewmessagesmulti' => 'Sanak mandapek pasan baru pado $1',
 'editsection' => 'suntiang',
 'editold' => 'suntiang',
 'viewsourceold' => 'caliak sumber',
@@ -306,11 +306,11 @@ $1',
 'collapsible-expand' => 'Kambangan',
 'thisisdeleted' => 'Caliak atau kambalian $1?',
 'viewdeleted' => 'Caliak $1?',
-'restorelink' => 'Caliak {{PLURAL:$1|ciek suntiangan|$1 suntiangan}} nan dihapuih',
+'restorelink' => '{{PLURAL:$1|$1 suntiangan}} lah dihapuih',
 'feedlinks' => 'Umpan:',
 'feed-invalid' => 'Tipe pamintaan umpan indak tapek.',
-'feed-unavailable' => 'Umpan sindikasi indak tasadio',
-'site-rss-feed' => '$1 RSS Umpan',
+'feed-unavailable' => 'Sindikasi umpan indak tasadio',
+'site-rss-feed' => '$1 Umpan RSS',
 'site-atom-feed' => 'Umpan Atom $1',
 'page-rss-feed' => 'Umpan RSS "$1"',
 'page-atom-feed' => '"$1" umpan Atom',
@@ -356,12 +356,12 @@ Basis data manghasilkan kasalahan "$3: $4".',
 'readonly' => 'Basis data dikunci',
 'enterlockreason' => 'Masuakkan alasan panguncian, tamasuak pakiraan bilo kunci akan dibuka',
 'readonlytext' => 'Basis data sadang dikunci tahadok masuakan baru. Panguruih nan malakukan panguncian mamberikan panjalehan sabagai berikut: <p>$1',
-'missing-article' => 'Basis data indak dapek manamukan teks dari laman nan saharuihnyo ado, yaitu "$1" $2.
+'missing-article' => 'Basisdata indak dapek manamukan teks dari laman nan saharuihnyo ado, yaitu "$1" $2.
 
 Hal ko biasonyo disababkan dek pranala usang ka pabaikkan tadahulu laman nan alah dihapuih.
 
-Jikok bukan iko panyababnyo, Sanak mungkin alah manamukan sabuah bug dalam pakakeh lunak.
-Silakan laporkan hal iko ka [[Special:ListUsers/sysop|Pangurus]], dangan manyabuikkan alamaik URL nan dituju.',
+Jikok bukan ko panyababnyo, Sanak mungkin alah manamukan sabuah bug dalam pakakeh lunak.
+Silakan laporkan hal iko ka [[Special:ListUsers/sysop|pangurus]], sarato manyabuikkan alamaik URL nan dituju.',
 'missingarticle-rev' => '(revisi#: $1)',
 'missingarticle-diff' => '(Bedo: $1, $2)',
 'readonly_lag' => 'Basis data alah dikunci otomatis salagi basis data sakunder malakukan sinkronisasi jo basis data utamo',
@@ -380,11 +380,11 @@ Silakan laporkan hal iko ka [[Special:ListUsers/sysop|Pangurus]], dangan manyabu
 'badarticleerror' => 'Tindakan iko indak dapek dilaksanakan di laman iko.',
 'cannotdelete' => 'Laman atau berkas "$1" indak dapek dihapuih.
 Mungkin alah dihapuih jo urang lain.',
-'cannotdelete-title' => 'Indak bisa mangapuih halaman "$1"',
+'cannotdelete-title' => 'Indak dapek mangapuih laman "$1"',
 'delete-hook-aborted' => 'Pengapusan batal jo hook.
 Indak ado keterangan.',
 'badtitle' => 'Judul indak sah',
-'badtitletext' => 'Permintaan judul laman indak sah, kosong, atau antarbaso atau antarwiki yang salah sambuang. Mungkin juo ado kandungan karakter yang indak buliah digunoan untuak judul.',
+'badtitletext' => 'Pamintaan judul laman indak sah, kosong, atau antarbaso atau antarwiki nan salah sambuang. Mungkin juo ado kandungan karakter nan indak buliah digunoan untuak judul.',
 'perfcached' => 'Data barikuik ko diambiak dari singgahan dan mungkin indak data nan baru. Nan tabanyak dari {{PLURAL:$1|suatu hasil dari|$1 hasilnyo}} ado di singgahan.',
 'perfcachedts' => 'Data barikuik ko singgahan, dan tarakhir diperbarui $1. Nan tabanyak dari {{PLURAL:$1|suatu hasil dari|$1 hasilnyo}} ado di singgahan.',
 'querypage-no-updates' => 'Pamutakhiran dari laman iko sadang dimatian. Data nan ado di siko saat iko indak akan dimuaik ulang.',
@@ -395,7 +395,7 @@ Indak ado keterangan.',
 'actionthrottledtext' => 'Anda dibatasi untuak malakuan tindakan iko talalu banyak dalam waktu singkek. Sila mancubo laik satalah bara menit.',
 'protectedpagetext' => 'Laman ko alah dikunci untuak manghindari panyuntiangan.',
 'viewsourcetext' => 'Sanak dapek malihek atau manyalin sumber laman iko:',
-'viewyourtext' => 'Sanak bisa mancaliak dan mangopi sumber untuak "editan sanak" ka halaman iko',
+'viewyourtext' => 'Sanak dapek mancaliak jo mangkopi sumber untuak "suntiangan sanak" ka laman ko',
 'protectedinterface' => 'Laman iko baisi teks antarmuko untuak digunoan dek parangkaik lunak di wiki iko sajo, dan alah dikunci untuak maindaan kasalahan. 
 Untuak manambah atau maubah tajamahan di sadonyo wiki, harap gunoan [//translatewiki.net/ translatewiki.net], yaitu proyek palokalan MediaWiki.',
 'editinginterface' => "'''Paringatan:''' Sanak manyuntiang laman nan digunoan untuak manyadiokan teks antarmuko untuak parangkaik lunak.
@@ -416,7 +416,7 @@ Pangurus nan manguncinyo manawarkan penjelasan: "$3"',
 'invalidtitle-knownnamespace' => '↓Judul nan indak sah jo ruangnamo "$2" dan teks "$3"',
 'invalidtitle-unknownnamespace' => 'Judul nan tak sah jo nomor ruang namo indak diketahui $1 dan teks "$2"',
 'exception-nologin' => 'Indak log masuak',
-'exception-nologin-text' => 'Halaman ko hanyo bisa disuntiang dek pangguno badaftar.',
+'exception-nologin-text' => 'Laman ko hanyo dapek disuntiang dek pangguno nan mandaftar.',
 
 # Virus scanner
 'virus-badscanner' => "Kasalahan konfigurasi: pamindai virus indak dikenal: ''$1''",
@@ -447,12 +447,12 @@ Parhatian bahawa bara laman mungkin masih taruih manunjukkan bahawa Sanak masih
 'userlogout' => 'Kalua log',
 'notloggedin' => 'Alun masuak log',
 'nologin' => "Alun mampunyoi akun? '''$1'''.",
-'nologinlink' => 'Cipta akun baru',
-'createaccount' => 'Buek akun baharu',
-'gotaccount' => "Alah tadaftar sabagai pangguno? '''$1'''.",
+'nologinlink' => 'Buek akun baru',
+'createaccount' => 'Buek akun',
+'gotaccount' => "Alah tadafta sabagai pangguno? '''$1'''.",
 'gotaccountlink' => 'Masuak log',
-'userlogin-resetlink' => 'Lupo detail info masuak Sanak?',
-'createaccountmail' => 'Pakai kato sandi sumbarang samantaro lalu kirim ka alamaik surel nan di bawah ko',
+'userlogin-resetlink' => 'Lupo rincian info masuak Sanak?',
+'createaccountmail' => 'Pakai kato sandi sumbarang samantaro, lalu kirim ka alamaik surel nan di bawah ko',
 'createaccountreason' => 'Alasan:',
 'badretype' => 'Kato sandi nan Sanak masuakkan salah.',
 'userexists' => 'Namo pangguno nan dipiliah alah tapakai.
@@ -475,7 +475,7 @@ Pastian Sanak alah mangaktifan kuki, lalu muek ulang laman iko dan cubo baliak.'
 Namo psngguno msmbedokan kapitalisasi.
 Pariso baliak ejaan Sanak, atau [[Special:UserLogin/signup|buek akun baharu]].',
 'nosuchusershort' => 'Indak ado pangguno jo namo "$1".
-Sila pariso baliak ejaan Sanak.',
+Cubo pariso baliak ejaan Sanak.',
 'nouserspecified' => 'Sanak harus mamasuakkan namo pangguno.',
 'login-userblocked' => 'Pangguno iko diblokir. Indak diizinan/dipabuliahan untuak masuak log.',
 'wrongpassword' => 'Kato sandi nan Sanak masuakkan salah. Sila cubo baliak.',
@@ -578,57 +578,57 @@ ingin maubahnyo, Sanak dapek maabaikan pasan iko dan taruih manggunokan sandi la
 'passwordreset-emailelement' => 'Namo pangguno: $1
 Sandi samantaro: $2',
 'passwordreset-emailsent' => 'Surel pangingek alah dikiriman.',
-'passwordreset-emailsent-capture' => 'E-mail paringatan alah dikirim, nan tacaliak di bawah ko.',
+'passwordreset-emailsent-capture' => 'Surel paringatan alah dikirim, nan nampak di bawah ko.',
 'passwordreset-emailerror-capture' => 'Surel pangingek, nan ditampilkan di bawah, alah dibuek, tapi pengirimannyo gagal ka pangguno: $1',
 
 # Special:ChangeEmail
 'changeemail' => 'Tuka alamat e-mail.',
 'changeemail-header' => 'Ganti alamat e-mail.',
-'changeemail-text' => 'Panuahan formulir iko untuak mangganti alamat e-mail. Sanak harus mamasuakkan kato kunci untuak mangonfirmasi.',
-'changeemail-no-info' => 'Sanak harus masuak log untuak mangakses halaman ko.',
-'changeemail-oldemail' => 'Alamat e-mail kini:',
-'changeemail-newemail' => 'Alamat e-mail baharu:',
+'changeemail-text' => 'Isi formulir ko untuak mangganti alamat surel. Sanak harus mamasuakkan kato sandi untuak mayakinkan parubahan.',
+'changeemail-no-info' => 'Sanak harus masuak log untuak mangakses laman ko.',
+'changeemail-oldemail' => 'Alamat surel kini:',
+'changeemail-newemail' => 'Alamat surel baru:',
 'changeemail-none' => '(indak ado)',
 'changeemail-password' => 'Sandi {{SITENAME}} Sanak:',
-'changeemail-submit' => 'Ganti e-mail.',
+'changeemail-submit' => 'Ganti surel.',
 'changeemail-cancel' => 'Batalkan',
 
 # Edit page toolbar
-'bold_sample' => 'Teks dicetak taba',
-'bold_tip' => 'Teks dicetak taba',
-'italic_sample' => 'Teks dicetak miriang',
-'italic_tip' => 'Teks dicetak miriang',
+'bold_sample' => 'Teks taba',
+'bold_tip' => 'Teks taba',
+'italic_sample' => 'Teks miriang',
+'italic_tip' => 'Teks miriang',
 'link_sample' => 'Judul pranala',
-'link_tip' => 'Pranala dalam',
-'extlink_sample' => 'http://www.example.com judul pranala',
+'link_tip' => 'Pranala internal',
+'extlink_sample' => 'http://www.hanyo-contoh.com judul pranala',
 'extlink_tip' => 'Pranala lua (ingek awalannyo http://)',
-'headline_sample' => 'Teks tajuk',
-'headline_tip' => 'Tingkek 2 tajuk',
-'nowiki_sample' => 'Masuakkan disiko teks yang indak diformat',
-'nowiki_tip' => 'Abaikan pemformatan wiki',
+'headline_sample' => 'Teks judul',
+'headline_tip' => 'Tingkek 2 judul',
+'nowiki_sample' => 'Masuakkan disiko teks nan indak baformat',
+'nowiki_tip' => 'Abaikan format wiki',
 'image_tip' => 'Cantumkan berkas',
 'media_tip' => 'Pranala berkas',
-'sig_tip' => 'Tandotangan awak jo tando waktu',
-'hr_tip' => 'Garih horizontal',
+'sig_tip' => 'Tandotangan sanak jo waktu',
+'hr_tip' => 'Garih mandata',
 
 # Edit pages
 'summary' => 'Ringkasan:',
-'subject' => 'Subjek/tajuk:',
-'minoredit' => 'Iko disuntiang saketek',
+'subject' => 'Subjek/judul:',
+'minoredit' => 'Suntiangan ketek',
 'watchthis' => 'Pantau laman ko',
-'savearticle' => 'Simpan halaman',
-'preview' => 'Pratonton',
+'savearticle' => 'Simpan laman',
+'preview' => 'Caliak',
 'showpreview' => 'Caliak pratonton',
 'showlivepreview' => 'Pratayang langsuang',
 'showdiff' => 'Caliak parubahan',
-'anoneditwarning' => "'''Peringatan:''' Awak alun masuak log.
-Alamat IP awak akan tacatat pado riwayat suntingan laman ko.",
+'anoneditwarning' => "'''Ingek:''' Sanak alun masuak log.
+Alamat IP sanak tacatat pado riwayaik suntiangan laman ko.",
 'anonpreviewwarning' => "''Sanak alun masuak log. Manyimpan laman akan manyababkan alamaik IP Sanak tacatat pado riwayat suntiangan laman iko.''",
 'missingsummary' => "'''Paringatan:''' Sanak indak mamasuakan ringkasan panyuntiangan. Jikok Sanak baliak manakan tombol Simpan, suntiangan Sanak akan disimpan tanpa ringkasan panyuntiangan.",
 'missingcommenttext' => 'Sila masuakan komenta di bawah iko.',
 'missingcommentheader' => "'''Paringatan:''' Sanak alun maagihan subjek atau judul untuak komenta Sanak. Jikok Sanak baliak manakan \"{{int:savearticle}}\", suntiangan Sanak akan disimpan tanpa komenta tasabuik.",
-'summary-preview' => 'Pratonton ringkasan:',
-'subject-preview' => 'Pratayang sabyek/tajuak:',
+'summary-preview' => 'Ringkasan pratayang:',
+'subject-preview' => 'Pratayang subyek/judul:',
 'blockedtitle' => 'Pangguno diblokir',
 'blockedtext' => "'''Namo pangguno atau alamaik IP Sanak alah diblokir.'''
 
@@ -682,17 +682,16 @@ Jadi, kami tapaso harus mamakai alamat IP nan basangkutan untuak maidentifikasik
 Jikok Sanak adolah saurang pangguno anonim dan marasa mandapekkan komentar-komentar nan indak relevan nan ditujuan langsung kapado Sanak, sila [[Special:UserLogin/signup|mambuek akun]] atau [[Special:UserLogin|masuak log]] untuak mahindari karancuan jo pangguno anonim lainnya di lain wakatu.''",
 'noarticletext' => 'Kini ko indak ada teks di laman iko.
 Sanak dapek [[Special:Search/{{PAGENAME}}|malakukan pancarian untuak judul laman iko]] di laman-laman lain, <span class="plainlinks">[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} mancari log takaik], atau [{{fullurl:{{FULLPAGENAME}}|action=edit}} manyuntiang laman iko]</span>.',
-'noarticletext-nopermission' => 'Kini ko indak ado teks dalam laman iko.
-
-Sanak dapek [[Special:Search/{{PAGENAME}}|malakukan pancahari untuak judul laman iko]] di laman lain, atau <span class="plainlinks">[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} mancahari log takaik] </span>, tapi Sanak indak punyo izin untuak mambuek laman iko.',
+'noarticletext-nopermission' => 'Kini ko indak ado teks dalam laman ko.
+Sanak dapek [[Special:Search/{{PAGENAME}}|malakukan pancarian untuak judul laman ko]] di laman lain, atau <span class="plainlinks">[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} mancahari log takaik] </span>, tapi Sanak indak punyo izin untuak mambuek laman ko.',
 'missing-revision' => 'Revisi $1 di laman nan banamo "{{PAGENAME}}" ko indak ado.
 
 Hal iko biasonyo disababkan dek pranala sijarah nan alah kadaluarsa ka laman nan alah dihapuih.
 Rinciannyo dapek dicaliak di [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} log panghapuihan].',
 'userpage-userdoesnotexist' => 'Akun pangguno "<nowiki>$1</nowiki>" indak tadafta.',
 'userpage-userdoesnotexist-view' => 'Pangguno "$1" indak tadafta.',
-'blocked-notice-logextract' => 'Pangguno iko sadang diblokir.
-Entri log pamblokiran tabaharu iko disadioan di bawah iko untuak referensi:',
+'blocked-notice-logextract' => 'Pangguno ko tangah diblokir.
+Entri log pamblokiran tabaru disadioan di bawah ko untuak referensi:',
 'clearyourcache' => "'''Catatan:''' Sasudah menyimpan, Sanak mungkin harus meminteh singgahan paramban Sanak untuak maliek parubahan.
 * '''Firefox / Safari:''' Tahan ''Shift'' sambia mangklik ''Reload'', atau takan ''Ctrl-F5'' atau ''Ctrl-R'' (''⌘-R'' di Mac)
 * '''Google Chrome:''' Takan ''Ctrl-Shift-R'' (''⌘-Shift-R'' di Mac)
@@ -710,7 +709,7 @@ Pratayang iko alun disimpan!'''",
 'userinvalidcssjstitle' => "'''Paringatan:''' Kulik \"\$1\" indak ditamuan. Harap diingek bahawa laman .css dan .js manggunokan huruf kecil, contoh {{ns:user}}:Foo/vector.css dan bukannyo {{ns:user}}:Foo/Vector.css.",
 'updated' => '(Dipabaharui)',
 'note' => "'''Catatan:'''",
-'previewnote' => "'''Ingek bahasonyo iko hanyo pratonton'''
+'previewnote' => "'''Ingek ko hanyo pratonton'''
 Parubahan Sanak alun disimpan!",
 'continue-editing' => 'Pai ka area mangedit.',
 'previewconflict' => 'Pratayang iko mancaminan teks pado bagian ateh kotak suntiangan teks sabagaimano akan taliek bilo Sanak manyimpannyo.',
@@ -762,12 +761,12 @@ Entri catatan tarakhir disadioan di bawah untuak referensi:",
 'cascadeprotectedwarning' => "'''PARINGATAN:''' Laman iko sadang dilinduangi sahinggo hanyo pangguno jo hak akses pangurus sajo nan dapek manyuntiangnyo karano disaratokan dalam {{PLURAL:$1|laman|laman-laman}} barikuik nan alah dilinduangi jo opsi 'palinduangan runtun':",
 'titleprotectedwarning' => "'''Paringatan: Laman iko alah dilinduangi sahinggo diparaluan [[Special:ListGroupRights|hak khusus]] untuak mambueknyo.'''
 Entri catatan tarakhir disadioan di bawah untuak referensi:",
-'templatesused' => '{{PLURAL:$1|Templat|Templat}} yang digunoan di laman iko:',
+'templatesused' => '{{PLURAL:$1|Templat}} yang digunoan di laman ko:',
 'templatesusedpreview' => '{{PLURAL:$1|Templat|Templat}} yang digunoan dalam pratonton ko:',
 'templatesusedsection' => '{{PLURAL:$1|Templat|Templat}} nan digunoan di bagian iko:',
 'template-protected' => '(dilinduangi)',
 'template-semiprotected' => '(semi-perlindungan)',
-'hiddencategories' => 'Laman ko marupokan kalompok dari {{PLURAL:$1|1 kategori tapandam|$1 kategori tapandam}}:',
+'hiddencategories' => 'Laman ko marupokan kalompok dari {{PLURAL:$1|$1 kategori tapandam}}:',
 'nocreatetext' => '{{SITENAME}} alah mambatasi pambuekan laman-laman baharu.
 Sanak dapek baliak dan manyuntiang laman nan alah ado, atau sila [[Special:UserLogin|masuak log atau mambuek akun]].',
 'nocreate-loggedin' => 'Sanak ndak mampunyoi hak akses untuak mambuek laman baharu.',
@@ -775,23 +774,23 @@ Sanak dapek baliak dan manyuntiang laman nan alah ado, atau sila [[Special:UserL
 'sectioneditnotsupported-text' => 'Panyuntiangan bagian indak didukuang di laman suntiang iko.',
 'permissionserrors' => 'Kasalahan Hak Akses',
 'permissionserrorstext' => 'Sanak ndak mampunyoi hak untuak malakuan hal itu karano {{PLURAL:$1|alasan|alasan-alasan}} barikuik:',
-'permissionserrorstext-withaction' => 'Awak indak punyo hak akses untuak $2, karano {{PLURAL:$1|alasan|alasan}} berikut:',
-'recreate-moveddeleted-warn' => "'''Paringatan: Sanak mambuek ulang suatu laman nan alah parnah dihapuih.'''
+'permissionserrorstext-withaction' => 'Awak indak punyo hak akses untuak $2, karano {{PLURAL:$1|alasan}} barikuik:',
+'recreate-moveddeleted-warn' => "'''Ingek: Sanak mambuek ulang suatu laman nan alah dihapuih.'''
 
-Harap patimbangan apokah layak untuak malanjutan suntiangan Sanak.
-Barikuik adolah log panghapuihan dan pamindahan dari laman iko:",
-'moveddeleted-notice' => 'Laman iko alah dihapuih.
-Sabagai referensi, barikuik adolah log panghapusan dan pamindahan laman iko.',
+Harap ditimbang apo rancak malanjuikan suntiangan Sanak.
+Barikuik ko log panghapuihan jo pamindahan dari laman ko:",
+'moveddeleted-notice' => 'Laman ko alah dihapuih.
+Sabagai referensi, barikuik adolah log panghapuihan dan pamindahannyo.',
 'log-fulllog' => 'Liek saluruah log',
 'edit-hook-aborted' => 'Suntiangan dibatalan samo kait parser
 tanpa ado katarangan.',
-'edit-gone-missing' => 'Indak bisa mamperbarui halaman.
+'edit-gone-missing' => 'Indak dapek mampabarui laman.
 Mungkin alah dihapuih.',
 'edit-conflict' => 'Konflik suntingan.',
 'edit-no-change' => 'Suntiangan sanak ditulak, karano indak ado parubahan nan tajadi ka teks.',
-'edit-already-exists' => 'Indak bisa mambuek halaman baru.
-Alah ado.',
-'defaultmessagetext' => 'Teks pasan default.',
+'edit-already-exists' => 'Indak dapek mambuek aman baru.
+Nyo alah ado.',
+'defaultmessagetext' => 'Teks baku.',
 'content-failed-to-parse' => 'Gagal manjabarkan konten $2 untuak model $1: $3',
 'invalid-content-data' => 'Data kanduangan indak valid.',
 'content-not-allowed-here' => 'Konten "$1" indak diizinan di laman [[$2]]',
@@ -803,16 +802,16 @@ Alah ado.',
 'content-model-css' => 'CSS',
 
 # Parser/template warnings
-'expensive-parserfunction-warning' => "'''Warning:''' Laman ko manganduang talalu banyak panggilan fungsi parser.
+'expensive-parserfunction-warning' => "'''Paringatan:''' Laman ko manganduang talalu banyak panggilan fungsi parser.
 
-Seharusnyo kurang dari $2 {{PLURAL:$2|panggilan|$2 panggilan}}, tapi {{PLURAL:$1|kini ado $1 panggilan|kini ko ado $1 panggilan}}.",
+Seharusnyo kurang dari $2 {{PLURAL:$2|panggilan}}, tapi {{PLURAL:$1|kini ado $1 panggilan}}.",
 'expensive-parserfunction-category' => 'Laman nan talalu banyak panggilan fungsi parser',
 'post-expand-template-inclusion-warning' => "'''Peringatan:''' Ukuran templat talalu gadang.
 Babarapo templat akan diabaikan.",
 'post-expand-template-inclusion-category' => 'Laman nan ukurannyo templatnyo malabiahi bateh',
-'post-expand-template-argument-warning' => 'Peringatan: Laman ko barisi satidaknyo ciek uraian templat na baukuran ekspansi nan talalu gadang. 
+'post-expand-template-argument-warning' => 'Paringatan: Laman ko barisi satidaknyo ciek uraian templat na ukuran ekspansinyo talalu gadang. 
 Uraian-uraian tu alah diabaikan.',
-'post-expand-template-argument-category' => 'Laman nan barisi uraian template nan diabaikan',
+'post-expand-template-argument-category' => 'Laman nan barisi uraian templat nan diabaikan',
 'parser-template-loop-warning' => 'Hubungan barulang templat tadeteksi: [[$1]]',
 'parser-template-recursion-depth-warning' => 'Limit kadalaman hubungan barulang templat lah talampau ($1)',
 'language-converter-depth-warning' => 'Bateh kadalaman pangonversi bahaso lah talampau ($1)',
@@ -820,53 +819,99 @@ Uraian-uraian tu alah diabaikan.',
 'node-count-exceeded-warning' => 'Laman hitungan-node lah talampau',
 'expansion-depth-exceeded-category' => 'Laman dima kadalaman ekspansi lah talampau',
 'expansion-depth-exceeded-warning' => 'Laman kadalaman ekspansi lah talampau',
+'parser-unstrip-loop-warning' => 'Unstrip loop detected',
+'parser-unstrip-recursion-limit' => 'Unstrip recursion limit exceeded ($1)',
 'converter-manual-rule-error' => 'Kasalahan tadeteksi di aturan manual konversi bahaso',
 
 # "Undo" feature
-'undo-success' => 'Suntiangan iko dapek dibatalan. 
-Tolong cek pabandiangan di bawah untuak mayakinkan bahwa bana itu nan Sanak ingin buek, lalu simpan parubahan tasabuik untuak manyalasaikan pambatalan suntiangan.',
+'undo-success' => 'Suntiangan ko dapek dibatalan. 
+Tolong cek pabedoan di bawah untuak mayakinkan bahwa bana nan tu Sanak nio buek, lalu simpan parubahan tasabuik untuak manyalasaikan pambatalan suntiangan.',
 'undo-failure' => 'Suntiangan ko indak dapek dibatalan dek konflik panyuntiangan antaro.',
 'undo-norev' => 'Suntiangan ko indak dapek dibatalan dek laman indak ditamukan atau lah dihapuih.',
-'undo-summary' => 'Mambatalan revisi $1 oleh [[Special:Contributions/$2|$2]] ([[User talk:$2|talk]])',
+'undo-summary' => 'Mambatalan revisi $1 oleh [[Special:Contributions/$2|$2]] ([[User talk:$2|maota]])',
+
+# Account creation failure
+'cantcreateaccounttitle' => 'Indak dapek mambuek akun',
+'cantcreateaccount-text' => "Mambuek akun dari alamat IP ko ('''$1''') alah diblok jo [[User:$3|$3]].
+
+Alasan nan diagiah jo $3 adolah ''$2''",
 
 # History pages
 'viewpagelogs' => 'Caliak log untuak laman ko',
-'currentrev-asof' => 'Revisi terkini pado $1',
+'nohistory' => 'Indak ado sajarah panyuntiangan untuak laman ko',
+'currentrev' => 'Revisi tabaru',
+'currentrev-asof' => 'Revisi tabaru pado $1',
 'revisionasof' => 'Pabaikkan per $1',
 'revision-info' => 'Revisi sajak $1 dek $2',
 'previousrevision' => '← Pabaikkan sabalunnyo',
-'nextrevision' => 'Revisi selanjutnyo →',
-'currentrevisionlink' => 'Revisi terkini',
+'nextrevision' => 'Revisi selanjuiknyo →',
+'currentrevisionlink' => 'Revisi tabaru',
 'cur' => 'kini',
+'next' => 'lanjuik',
 'last' => 'sabalun',
-'histlegend' => "Membandingkan pilihan: Tandoi antaro duo versi nan ingin dibandingan dangan mamilih kotak radionyo, dan takan tombol ''Bandiangan versi tapiliah''.<br />
-Legend: '''({{int:kini}})''' = perbedaan jo versi taakhia, '''({{int:dulu}})''' = pabedoan jo versi sabalunnyo, '''{{int:k}}''' = suntiangan ketek, '''{{int:b}}''' = suntiangan bot.",
+'page_first' => 'awal',
+'page_last' => 'akhir',
+'histlegend' => "Bandiangkan pilihan: Tandoi revisi untuak mambandiangkan dan takan enter atau tombol di bawah.<br />
+Contoh: '''({{int:cur}})''' = bedo jo versi tarakhia, '''({{int:last}})''' = bedo jo versi sabalunnyo, '''{{int:minoreditletter}}''' = suntiangan ketek.",
 'history-fieldset-title' => 'Talusuri riwayaik',
 'history-show-deleted' => 'Hanyo nan dihapuih',
 'histfirst' => 'Nan lamo',
 'histlast' => 'Nan baru',
+'historysize' => '({{PLURAL:$1|$1  bita}})',
+'historyempty' => '(kosong)',
 
 # Revision feed
+'history-feed-title' => 'Riwayat revisi',
+'history-feed-description' => 'Riwayat revisi laman ko di wiki',
 'history-feed-item-nocomment' => '$1 pado $2',
+'history-feed-empty' => 'Laman nan dicari indak ado.
+Mungkin alah dihapuih dari wiki, atau diagiah namo baru.
+Cuba [[Special:Search|cari dulu]] untuak laman lain nan relevan.',
 
 # Revision deletion
+'rev-deleted-comment' => '(ringkasan suntiangan dihapuih)',
+'rev-deleted-user' => '(namo pangguno dihapuih)',
+'rev-deleted-event' => '(isi dihapuih)',
+'rev-deleted-user-contribs' => '[namo pangguno atau alamat IP dihapuih - suntiangan disuruakkan pad dafta kontribusi]',
+'rev-deleted-text-permission' => "Revisi laman ko alah '''dihapuih'''.
+Rinciannyo mungkin ado di [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} log panghapuihan]",
+'rev-deleted-text-unhide' => "Revisi laman ko alah '''dihapuih'''.
+Rinciannyo mungkin ado di [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} log penghapuihan].
+Angku masih dapek [$1 maliek revisi ko] ko' amuah.",
+'rev-suppressed-text-unhide' => "Revisi laman ko alah '''tabanam'''.
+Rinciannyo mungkin ado di [{{fullurl:{{#Special:Log}}/suppress|page={{FULLPAGENAMEE}}}} log pambanaman].
+Angku masih dapek [$1 maliek revisi ko] ko' amuah.",
+'rev-deleted-text-view' => "Laman revisi ko alah '''dihapuih'''.
+Angku dapek mancaliaknyo; rinciannyo mungkin ado di [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} log penghapuihan].",
+'rev-suppressed-text-view' => "Revisi laman ko alah '''tabanam'''.
+Angku dapek malieknyo; rinciannyo mungkin ado di [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} log pambanaman]",
+'rev-deleted-no-diff' => "Angku indak dapek maliek pabedoan ko dek salah satu dari revisinyo alah '''dihapuih'''.
+Rinciannyo mungkin ado di [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} log penghapuihan].",
 'rev-delundel' => 'tampilkan/suruakkan',
+'rev-showdeleted' => "tunjua'an",
+'revdelete-show-file-submit' => 'Yo',
+'revdelete-radio-set' => 'Yo',
+'revdelete-radio-unset' => 'Indak',
+'revdelete-log' => 'Alasan:',
 'revdel-restore' => 'ganti tampilan',
 'revdel-restore-deleted' => 'suntiangan nan alah dihapuih',
 'revdel-restore-visible' => 'tampilan revisi',
+'pagehist' => 'Riwayaik laman',
+'revdelete-otherreason' => 'Alasan lain/tambahan:',
+'revdelete-reasonotherlist' => 'Alasan lain',
 
 # Merge log
-'revertmerge' => 'Bata bagabuang',
+'revertmerge' => 'Batagabuang',
 
 # Diffs
-'history-title' => 'Riwayaik pabaiakkan dari "$1"',
+'history-title' => 'Riwayaik revisi dari "$1"',
 'lineno' => 'Barih $1:',
 'compareselectedversions' => 'Bandiangan versi tapiliah',
-'editundo' => 'batalan',
-'diff-multi' => '({{PLURAL:$1|ciek |$1 revisi antaro}} oleh {{PLURAL:$2|ciek|$2 pangguno}} indak ditampilkan)',
+'editundo' => 'batal',
+'diff-multi' => '({{PLURAL:$1|$1 revisi antaro}} oleh {{PLURAL:$2|$2 pangguno}} indak ditampilkan)',
 
 # Search results
-'searchresults' => 'Asia pancarian',
+'searchresults' => 'Hasil pancarian',
 'searchresults-title' => 'Hasil pancarian untuak "$1"',
 'searchresulttext' => 'Untuak informasi labiah lanjuik tantang pancarian {{SITENAME}}, caliak [[{{MediaWiki:Helppage}}|{{int:help}}]].',
 'searchsubtitle' => 'Awak mancari \'\'\'[[:$1]]\'\'\' ([[Special:Prefixindex/$1|sado laman yang dimulai jo "$1"]]{{int:pipe-separator}}[[Special:WhatLinksHere/$1|sado laman nan tapauik ka "$1"]])',
@@ -875,12 +920,13 @@ Legend: '''({{int:kini}})''' = perbedaan jo versi taakhia, '''({{int:dulu}})'''
 'notextmatches' => 'Indak ado judul nan pas',
 'prevn' => '{{PLURAL:$1|$1}} sabalunnyo',
 'nextn' => '{{PLURAL:$1|$1}} salanjuiknyo',
-'prevn-title' => '$1 {{PLURAL:$1|Hasil|Hasil-hasil}} sabalunnyo',
-'nextn-title' => '$1 {{PLURAL:$1|Hasil|Hasil-hasil}} barikuiknyo',
-'shown-title' => 'Tampilkan $1 {{PLURAL:$1|hasil|hasil-hasil}} per laman',
+'prevn-title' => '$1 {{PLURAL:$1|hasil}} sabalunnyo',
+'nextn-title' => '$1 {{PLURAL:$1|hasil}} barikuiknyo',
+'shown-title' => 'Tampilkan $1 {{PLURAL:$1|hasil}} per laman',
 'viewprevnext' => 'Caliakkan ($1 {{int:pipe-separator}} $2) ($3)',
 'searchmenu-exists' => "'''Ado laman nan banamo \"[[:\$1]]\" pado wiki ko.'''",
 'searchmenu-new' => "'''Buek laman \"[[:\$1]]\" di wiki ko!'''",
+'searchhelp-url' => 'Help:Isi',
 'searchprofile-articles' => 'Laman isi',
 'searchprofile-project' => 'Laman Bantuan jo Proyek',
 'searchprofile-images' => 'Multimedia',
@@ -891,8 +937,9 @@ Legend: '''({{int:kini}})''' = perbedaan jo versi taakhia, '''({{int:dulu}})'''
 'searchprofile-images-tooltip' => 'Cari untuak berkas',
 'searchprofile-everything-tooltip' => 'Cari sadoalahnyo (tamasuak laman maota)',
 'searchprofile-advanced-tooltip' => 'Pacarian di ruang namo tatantu',
-'search-result-size' => '$1 ({{PLURAL:$2|1 kato|$2 kato}})',
-'search-result-category-size' => '{{PLURAL:$1|1 anggota|$1 anggota}} ({{PLURAL:$2|1 subkategori|$2 subkategori}}, {{PLURAL:$3|1 berkas|$3 berkas}})',
+'search-result-size' => '$1 ({{PLURAL:$2|$2 kato}})',
+'search-result-category-size' => '{{PLURAL:$1|$1 anggota}} ({{PLURAL:$2|$2 subkategori}}, {{PLURAL:$3|$3 berkas}})',
+'search-result-score' => 'Relevansi: $1%',
 'search-redirect' => '(pangaliahan $1)',
 'search-section' => '(bagian $1)',
 'search-suggest' => 'Mungkin maksud awak: $1',
@@ -901,9 +948,9 @@ Legend: '''({{int:kini}})''' = perbedaan jo versi taakhia, '''({{int:dulu}})'''
 'search-interwiki-more' => '(selanjutnyo)',
 'searchrelated' => 'bakaitan',
 'searchall' => 'sado',
-'showingresults' => "Di bawah iko dikaluaan inggo {{PLURAL:$1|'''1''' asia|'''$1''' asia}}, dimulai dari #'''$2'''.",
-'showingresultsnum' => "Di bawah iko dikaluaan {{PLURAL:$3|'''1'''|'''$3'''}} asia, dimulai dari #'''$2'''.",
-'showingresultsheader' => "{{PLURAL:$5|Hasil '''$1''' dari '''$3'''|Hasil '''$1 - $2''' dari '''$3'''}} untuak '''$4'''",
+'showingresults' => "Di bawah ko dikaluaan sampai {{PLURAL:$1|'''$1''' hasil}}, dimulai dari #'''$2'''.",
+'showingresultsnum' => "Di bawah ko dikaluaan {{PLURAL:$3|'''$3'''}} hasil mulai dari #'''$2'''.",
+'showingresultsheader' => "{{PLURAL:$5|Hasil '''$1 - $2''' dari '''$3'''}} untuak '''$4'''",
 'nonefound' => "'''Catatan''': hanyo babarapo ruangnamo yang dicari sacaro default.
 Cubo awali permintaan awak tu jo ''all:'' untuak mancari sado kandungan (tamasuak laman ota, templat, dll), atau gunoan ruangnamo yang diinginkan sabagai awalan.",
 'search-nonefound' => 'Indak ado hasil nan cocok sasuai jo parmintaan',
@@ -912,23 +959,151 @@ Cubo awali permintaan awak tu jo ''all:'' untuak mancari sado kandungan (tamasua
 'powersearch-ns' => 'Mancari di ruangnamo:',
 'powersearch-redir' => 'Dafta pangaliahan',
 'powersearch-field' => 'Mancari',
+'powersearch-togglelabel' => 'Piliah:',
+'powersearch-toggleall' => 'Sadonyo',
+'powersearch-togglenone' => 'Dak ado',
 
 # Preferences page
-'preferences' => 'Preferensi',
-'mypreferences' => 'Preferensi',
-'prefs-beta' => 'Corak Beta',
-'prefs-labs' => 'Corak Uji',
-'youremail' => 'Surek Elektronik:',
+'preferences' => 'Pangaturan',
+'mypreferences' => 'Pangaturan',
+'prefs-skin' => 'Kulik',
+'skin-preview' => 'Caliak',
+'datedefault' => 'Indak usah diatua',
+'prefs-beta' => 'Baru dicubo (Beta)',
+'prefs-datetime' => 'Tangga jo wakatu',
+'prefs-labs' => 'Alaik uji',
+'prefs-user-pages' => 'Laman pangguno',
+'prefs-personal' => 'Profil pangguno',
+'prefs-rc' => 'Parubahan tabaru',
+'prefs-watchlist' => 'Dafta pantauan',
+'prefs-watchlist-days' => 'Lamonyo dalam daftar pantauan:',
+'prefs-watchlist-days-max' => 'Maksimum $1 {{PLURAL:$1|hari}}',
+'prefs-watchlist-edits' => 'Jumlah suntiangan maksimum nan ditampilkan di dafta pantauan nan labiah langkok:',
+'prefs-watchlist-edits-max' => 'Nilai maksimum: 1000',
+'prefs-watchlist-token' => 'Token pantauan:',
+'prefs-misc' => 'Lain-lain',
+'prefs-resetpass' => 'Tuka kato sandi',
+'prefs-changeemail' => 'Tuka alamaik surel',
+'prefs-setemail' => 'Atua alamaik surel',
+'prefs-email' => 'Opsi surel',
+'prefs-rendering' => 'Tampilan',
+'saveprefs' => 'Simpan',
+'resetprefs' => 'Batalan parubahan',
+'restoreprefs' => 'Baliakkan ka setelan bawaan',
+'prefs-editing' => 'Panyuntiangan',
+'prefs-edit-boxsize' => 'Ukuran kotak panyuntiangan.',
+'rows' => 'Barih:',
+'columns' => 'Kolom',
+'searchresultshead' => 'Cari',
+'resultsperpage' => 'Hasil per laman:',
+'stub-threshold' => 'Ambang bateh untuak format <a href="#" class="stub">tautan rintisan</a>:',
+'stub-threshold-disabled' => 'Nonaktifkan',
+'recentchangesdays' => 'Jumlah ari nan ditampilkan di parubahan tabaru:',
+'recentchangesdays-max' => 'Maksimum $1 {{PLURAL:$1|hari}}',
+'recentchangescount' => 'Standar jumlah suntiangan nan ditampilkan:',
+'prefs-help-recentchangescount' => 'Iko untuak parubahan tabaru, riwayaik laman nan lalu, sarato log.',
+'prefs-help-watchlist-token' => 'Mangisi kotak ko jo kunci rasio (PIN) akan manghasilkan sindikasi RSS untuak dafta pantauan Angku. Sia juo nan tau jo kunci ko dapek mambaco dafta pantauan Angku, jadi hati-hatilah mamiliah nilainyo 
+Barikuik ko nilai acak nan dapek Angku gunoan: $1',
+'savedprefs' => 'Pangaturan Angku alah tasimpan',
+'timezonelegend' => 'Zona wakatu:',
+'localtime' => 'Wakatu satampaik:',
+'timezoneuseserverdefault' => 'Gunokan nan dari wiki ($1)',
+'timezoneuseoffset' => 'Lainnyo (tantuan pabedoannyo)',
+'timezoneoffset' => 'Pabedoan¹:',
+'servertime' => 'Wakatu server:',
+'guesstimezone' => 'Isikan dari panjalajah web',
+'timezoneregion-africa' => 'Afrika',
+'timezoneregion-america' => 'Amerika',
+'timezoneregion-antarctica' => 'Antarktika',
+'timezoneregion-arctic' => 'Arktik',
+'timezoneregion-asia' => 'Asia',
+'timezoneregion-atlantic' => 'Samudera Atlantik',
+'timezoneregion-australia' => 'Australia',
+'timezoneregion-europe' => 'Eropa',
+'timezoneregion-indian' => 'Samudera Hindia',
+'timezoneregion-pacific' => 'Samudera Pasifik',
+'allowemail' => 'Izinkan pangguno lain mangirim surel',
+'prefs-searchoptions' => 'Cari',
+'prefs-namespaces' => 'Ruang namo',
+'defaultns' => 'Ataupun cari dalam ruang namo lain:',
+'default' => 'baku',
+'prefs-files' => 'Berkas',
+'prefs-custom-css' => 'CSS pribadi',
+'prefs-custom-js' => 'JS pribadi',
+'prefs-common-css-js' => 'CSS/JS babagi untuak sado kulik:',
+'prefs-reset-intro' => 'Angku dapek manggunokan laman ko untuak mangambalikan pangaturan ka setelan baku situs ko.
+Pangambalian pangaturan indak dapek dibatalan.',
+'prefs-emailconfirm-label' => 'Surel konfirmasi:',
+'prefs-textboxsize' => 'Ukuran kotak suntiang',
+'youremail' => 'Surel:',
+'username' => '{{GENDER:$1|Namo pangguno}}:',
+'prefs-registration' => 'Wakatu pandaftaran:',
 'yourrealname' => 'Namo sabananyo:',
-'prefs-help-email' => 'Alamaik surek elektronik ko hanyo tambahan se, namun paralu untuak maulang kato kunci, jiko awak ang lupo kato kunci.',
-'prefs-help-email-others' => 'Awak ang juo dapek mamiliah untuak mangizinkan urang lain manghubungi awak ang jo surek elektronik malalui laman pangguno atau laman ota.
-Alamaik surek elektronik awak ang tu indak kan katahuan dek urang lain nan manghubungi awak ang tu.',
+'yourlanguage' => 'Bahaso',
+'yourvariant' => 'Varian bahaso isi:',
+'prefs-help-variant' => 'Varian atau ortografi pilihan Angku untuak manampilkan isi laman wiki ko.',
+'yournick' => 'Tando tangan:',
+'prefs-help-signature' => 'Komen pado laman maota paralu ditandotangani jo "<nowiki>~~~~</nowiki>" nan kan diubah manjadi tando tangan Angku jo wakatu saat kini ko.',
+'badsig' => 'Tando tangan mantah indak sah; pariso tag HTML.',
+'badsiglength' => 'Tando tangan Angku panjang bana.
+Jan labiah dari $1 {{PLURAL:$1|karakter}}.',
+'yourgender' => 'Jenis kelamin:',
+'gender-unknown' => 'Indak ditanyo',
+'gender-male' => 'Laki-laki',
+'gender-female' => 'Padusi',
+'prefs-help-gender' => 'Lainnyo: digunoan untuak manyabuik gender jo parangkaik lunak. Informasi ko akan tabukak untuak umum.',
+'email' => 'Surel',
+'prefs-help-realname' => "Namo asli sifaiknyo opsional.
+Jiko' Angku manambahkannyo, namo asli Angku akan digunoan untuak mengenal hasil karaja Angku.",
+'prefs-help-email' => 'Alamaik surel ko hanyo tambahan se, namun paralu untuak maulang kato kunci, jikok Sanak lupo kato kunci.',
+'prefs-help-email-others' => 'Sanak dapek mamiliah untuak mangizinkan urang lain manghubungi jo surel malalui laman pangguno atau laman diskusi.
+Alamaik surel tu indakkan tau dek urang nan manghubungi sanak tu.',
+'prefs-help-email-required' => 'Alamaik surel wajib diisi.',
+'prefs-info' => 'Informasi dasar',
+'prefs-i18n' => 'Internasionalisasi',
+'prefs-signature' => 'Tando tangan',
+'prefs-dateformat' => 'Format tangga',
+'prefs-timeoffset' => 'Format wakatu',
+'prefs-advancedediting' => 'Opsi lanjuik',
+'prefs-advancedrc' => 'Opsi lanjuik',
+'prefs-advancedrendering' => 'Opsi lanjuik',
+'prefs-advancedsearchoptions' => 'Opsi lanjuik',
+'prefs-advancedwatchlist' => 'Opsi lanjuik',
+'prefs-displayrc' => 'Pilihan tampilan',
+'prefs-displaysearchoptions' => 'Pilihan tampilan',
+'prefs-displaywatchlist' => 'Pilihan tampilan',
+'prefs-diffs' => 'Pabedoan',
+
+# User preference: e-mail validation using jQuery
+'email-address-validity-valid' => 'Alamaik surel nampaknyo sah',
+'email-address-validity-invalid' => 'Masuakkan alamaik surel nan sah',
+
+# User rights
+'userrights' => 'Manajemen hak pangguno',
+'userrights-lookup-user' => 'Mangatua kalompok pangguno',
+'userrights-user-editname' => 'Masuakkan namo pangguno:',
+'editusergroup' => 'Suntiang kalompok pangguno',
 
 # Groups
-'group-sysop' => 'Pengurus',
-
+'group' => 'Kalompok:',
+'group-user' => 'Pangguno',
+'group-autoconfirmed' => 'Pangguno takonfirmasi otomatis',
+'group-bot' => 'Bot',
+'group-sysop' => 'Panguruih',
+'group-bureaucrat' => 'Birokrat',
+'group-suppress' => 'Pangawas',
+'group-all' => '(sadonyo)',
+
+'group-user-member' => '{{GENDER:$1|pangguno}}',
+
+'grouppage-user' => '{{ns:project}}:Pangguno',
 'grouppage-sysop' => '{{ns:project}}:Pengurus',
 
+# Rights
+'right-createpage' => 'Mambuek laman baru (nan bukan laman diskusi)',
+'right-createtalk' => 'Mambuek laman diskusi',
+'right-createaccount' => 'Mambuek akun baru',
+
 # Special:Log/newusers
 'newuserlogpage' => 'Log pangguno baru',
 
@@ -936,28 +1111,33 @@ Alamaik surek elektronik awak ang tu indak kan katahuan dek urang lain nan mangh
 'rightslog' => 'Log parubahan hak akses',
 
 # Associated actions - in the sentence "You do not have permission to X"
+'action-read' => 'baco laman ko',
 'action-edit' => 'suntiang laman ko',
+'action-createpage' => 'buek laman',
+'action-createtalk' => 'buek laman diskusi',
+'action-createaccount' => 'buek akun pangguno ko',
+'action-minoredit' => 'tandoi sabagai suntiangan ketek',
 
 # Recent changes
-'nchanges' => '$1 {{PLURAL:$1|parubahan|parubahan}}',
+'nchanges' => '$1 {{PLURAL:$1|parubahan}}',
 'recentchanges' => 'Parubahan baru',
 'recentchanges-legend' => 'Pilihan parubahan baru',
 'recentchanges-summary' => 'Manjajak parubahan terbaru dalam wiki di laman ko.',
 'recentchanges-feed-description' => 'Temukan parubahan baru dalam umpan wiki ko',
-'recentchanges-label-newpage' => 'Suntiang ko mambuek laman baru',
-'recentchanges-label-minor' => 'Iko disuntiang saketek',
+'recentchanges-label-newpage' => 'Suntiangan ko mambuek laman baru',
+'recentchanges-label-minor' => 'Iko suntiangan ketek',
 'recentchanges-label-bot' => 'Suntiang ko dibuek dek bot',
-'recentchanges-label-unpatrolled' => 'Suntiangan ko alun tajago',
-'rcnote' => "Berikut ko {{PLURAL:$1|'''1'''|'''$1'''}} parubahan dalam {{PLURAL:$2|hari|'''$2''' hari}} terakhir, sampai $5, pukul $4.",
-'rcnotefrom' => "Di bawah ko ado parubahan sejak '''$2''' (sampai '''$1''' parubahan).",
-'rclistfrom' => 'Tampilkan parubahan baru sejak $1',
+'recentchanges-label-unpatrolled' => 'Suntiangan ko alun dipatroli',
+'rcnote' => "Berikuik ko {{PLURAL:$1|'''$1'''}} parubahan dalam {{PLURAL:$2|'''$2''' hari}} tarakhia, sampai $4, pukul $5.",
+'rcnotefrom' => "Di bawah ko ado parubahan mulai dari '''$2''' (sampai '''$1''' parubahan).",
+'rclistfrom' => 'Tampilkan parubahan baru mulai dari $1',
 'rcshowhideminor' => '$1 suntingan ketek',
 'rcshowhidebots' => '$1 bot',
 'rcshowhideliu' => '$1 pangguno masuak log',
 'rcshowhideanons' => '$1 pangguno anon',
 'rcshowhidepatr' => '$1 suntiangan nan tajago',
 'rcshowhidemine' => '$1 suntingan denai',
-'rclinks' => 'Tampilkan $1 parubahan baru dalam $2 hari terakhir<br />$3',
+'rclinks' => 'Tampilkan $1 parubahan tabaru dalam $2 hari tarakhir<br />$3',
 'diff' => 'bedo',
 'hist' => 'sijarah',
 'hide' => 'Suruakkan',
@@ -965,7 +1145,7 @@ Alamaik surek elektronik awak ang tu indak kan katahuan dek urang lain nan mangh
 'minoreditletter' => 'k',
 'newpageletter' => 'B',
 'boteditletter' => 'b',
-'rc-enhanced-expand' => 'Tampilkan rincian (perlu JavaScript)',
+'rc-enhanced-expand' => 'Tampilkan rincian (paralu JavaScript)',
 'rc-enhanced-hide' => 'Suruakkan rincian',
 
 # Recent changes linked
@@ -973,58 +1153,67 @@ Alamaik surek elektronik awak ang tu indak kan katahuan dek urang lain nan mangh
 'recentchangeslinked-toolbox' => 'Parubahan takaik',
 'recentchangeslinked-title' => 'Parubahan nan takaik jo "$1"',
 'recentchangeslinked-noresult' => 'Indak ado parubahan pado laman nan tapauik salamo periode nan ditantuan',
-'recentchangeslinked-summary' => "Iko adolah daftar parubahan tarakhir pado laman nan tahubuang dari laman tatantu (atau anggota dari suatu kategori tatantu).
-Halaman pada [[Special:Watchlist|your watchlist]] ditondai dangan '''cetak taba''",
+'recentchangeslinked-summary' => "Iko dafta parubahan tarakhir pado laman nan tahubuang dari laman tatantu (atau anggota dari kategori tatantu).
+Laman pado [[Special:Watchlist|pantauan Sanak]] ditandoi jo '''cetak taba'''.",
 'recentchangeslinked-page' => 'Namo laman:',
-'recentchangeslinked-to' => 'Tampilkan parubahan dari laman yang takaik jo laman yang disajikan',
+'recentchangeslinked-to' => 'Tampilkan parubahan dari laman nan takaik jo laman nan ko',
 
 # Upload
 'upload' => 'Muek berkas',
 'uploadlogpage' => 'Log unggah',
 'filedesc' => 'Ringkasan',
-'uploadedimage' => 'unggah "[[$1]]"',
+'uploadedimage' => 'muek "[[$1]]"',
 
 'license' => 'Lisensi:',
 'license-header' => 'Lisensi',
 
+# Special:ListFiles
+'listfiles_user' => 'Pangguno',
+'listfiles_size' => 'Ukuran',
+'listfiles_description' => 'Katarangan',
+'listfiles_count' => 'Versi',
+
 # File description page
 'file-anchor-link' => 'Berkas',
 'filehist' => 'Riwayaik berkas',
 'filehist-help' => 'Klik pado tanggal/waktu untuak malihek berkas pado maso tu',
-'filehist-revert' => 'kembalikan',
+'filehist-revert' => 'baliakkan',
 'filehist-current' => 'kini ko',
 'filehist-datetime' => 'Tanggal/Waktu',
 'filehist-thumb' => 'Miniatur',
 'filehist-thumbtext' => 'Miniatur untuak versi per $1',
+'filehist-nothumb' => 'Miniatur indak ado',
 'filehist-user' => 'Pangguno',
 'filehist-dimensions' => 'Dimensi',
-'filehist-comment' => 'Ulasan',
+'filehist-filesize' => 'Ukuran berkas',
+'filehist-comment' => 'Komen',
+'filehist-missing' => 'Berkas indak ado',
 'imagelinks' => 'Panggunoan berkas',
-'linkstoimage' => 'Berikut ko ado {{PLURAL:$1|laman nan takaik|$1 laman nan takaik}} jo berkas ko:',
-'nolinkstoimage' => 'Indak ado laman nan ado batauik ka berkas ko.',
+'linkstoimage' => 'Barikuik ko {{PLURAL:$1|$1 laman nan takaik}} jo berkas:',
+'nolinkstoimage' => 'Indak ado laman nan batauik ka berkas ko.',
 'sharedupload' => 'Berkas ko barasal dari $1 dan mungkin digunoan oleh berbagai proyek lain.',
 'sharedupload-desc-here' => 'Berkas ko dari $1 dan mungkin digunoan untuak proyek-proyek lain.
-Deskripsi dari [$2 laman deskripsi berkas] ditampilkan di bawah.',
+Katarangan dari [$2 laman kataranagn berkas] ditampilkan di bawah.',
 'uploadnewversion-linktext' => 'Unggah versi baru dari berkas ko',
 
 # Random page
-'randompage' => 'Laman sambarangan',
+'randompage' => 'Laman sumbarang',
 
 # Statistics
 'statistics' => 'Statistik',
 
-'disambiguationspage' => 'Template:disambig',
+'disambiguationspage' => 'Template:sanamo',
 
 # Miscellaneous special pages
-'nbytes' => '$1 {{PLURAL:$1|bait|bait}}',
-'nmembers' => '$1 {{PLURAL:$1|anggota|anggota}}',
-'prefixindex' => 'Semua laman jo awalan',
+'nbytes' => '$1 {{PLURAL:$1|bita}}',
+'nmembers' => '$1 {{PLURAL:$1|anggota}}',
+'prefixindex' => 'Sado laman jo awalan',
 'usercreated' => '{{GENDER:$3|Dibuek}} pado $1 pukua $2',
 'newpages' => 'Laman baru',
-'move' => 'Pindahan',
+'move' => 'Pindah',
 'movethispage' => 'Pindahan laman ko',
-'pager-newer-n' => '{{PLURAL:$1|labiah baru 1|labiah baru $1}}',
-'pager-older-n' => '{{PLURAL:$1|labiah lamo 1|labiah lamo $1}}',
+'pager-newer-n' => '{{PLURAL:$1|$1 labiah baru}}',
+'pager-older-n' => '{{PLURAL:$1|$1 labiah lamo}}',
 
 # Book sources
 'booksources' => 'Sumber buku',
@@ -1035,8 +1224,8 @@ Deskripsi dari [$2 laman deskripsi berkas] ditampilkan di bawah.',
 'log' => 'Log',
 
 # Special:AllPages
-'allpages' => 'Semua laman',
-'alphaindexline' => '$1 hinggo $2',
+'allpages' => 'Kasado laman',
+'alphaindexline' => '$1 sampai $2',
 'prevpage' => 'Laman sabalunnyo ($1)',
 'allpagesfrom' => 'Tampilkan laman mulai dari:',
 'allpagesto' => 'Tampilkan laman hinggo:',
@@ -1051,14 +1240,14 @@ Deskripsi dari [$2 laman deskripsi berkas] ditampilkan di bawah.',
 'linksearch-line' => '$1 tapauik dari $2',
 
 # Special:ListGroupRights
-'listgrouprights-members' => '(senarai anggota)',
+'listgrouprights-members' => '(dafta anggota)',
 
 # E-mail user
-'emailuser' => 'E-mail pangguno',
+'emailuser' => 'Kirim surel pangguno ko',
 
 # Watchlist
-'watchlist' => 'Senarai pantauan denai',
-'mywatchlist' => 'Dafta pantauan denai',
+'watchlist' => 'Daftapantau',
+'mywatchlist' => 'Daftapantau',
 'watchlistfor2' => 'Untuak $1 $2',
 'addedwatchtext' => "Laman \"[[:\$1]]\" lah ditambahkan ka [[Special:Watchlist|senarai pantauan awak]].
 Parubahan laman ko tamasuak laman otanyo akan ditampilkan dalam '''cetak taba''' pado [[Special:RecentChanges|senarai parubahan]] agar lebih mudah manjagonyo.",
@@ -1066,9 +1255,9 @@ Parubahan laman ko tamasuak laman otanyo akan ditampilkan dalam '''cetak taba'''
 'watch' => 'Pantau',
 'watchthispage' => 'Pantau laman ko',
 'unwatch' => 'Batal pantau',
-'watchlist-details' => '{{PLURAL:$1|$1 laman|$1 laman}} dalam senarai pantauan awak, indak tamasuak laman ota.',
-'wlshowlast' => 'Tampilkan $1 jam $2 hari terakhir $3',
-'watchlist-options' => 'Pilihan senarai pantauan',
+'watchlist-details' => '{{PLURAL:$1|$1 laman}} dalam daftapantau awak, indak tamasuak laman diskusi.',
+'wlshowlast' => 'Tampilkan $1 jam $2 hari tarakhia $3',
+'watchlist-options' => 'Piliahan daftapantau',
 
 # Displayed when you click the "watch" button and it is in the process of watching
 'watching' => 'Mamantau...',
@@ -1078,11 +1267,11 @@ Parubahan laman ko tamasuak laman otanyo akan ditampilkan dalam '''cetak taba'''
 'deletepage' => 'Hapuih laman',
 'confirmdeletetext' => 'Awak akan mahapuih laman atau berkas basamo riwayatnyo.
 Pastikan awak mainginkannyo, dan awak lah tahu sagalo akibatnyo dan sasuai jo [[{{MediaWiki:Policy-url}}|kebijakan]] yang balaku.',
-'actioncomplete' => 'Proses selesai',
-'actionfailed' => 'Aksi gagal',
+'actioncomplete' => 'Proses salasai',
+'actionfailed' => 'Proses gagal',
 'deletedtext' => '"$1" lah dihapuih.
 Caliak $2 untuak rakam jajak laman nan lah dihapuih.',
-'dellogpage' => 'Log penghapusan',
+'dellogpage' => 'Log penghapuihan',
 'deletecomment' => 'Alasan:',
 'deleteotherreason' => 'Alasan lain/tambahan:',
 'deletereasonotherlist' => 'Alasan lain',
@@ -1091,8 +1280,8 @@ Caliak $2 untuak rakam jajak laman nan lah dihapuih.',
 'rollbacklink' => 'baliakkan',
 
 # Protect
-'protectlogpage' => 'Log perlindungan',
-'protectedarticle' => 'melindungi "[[$1]]"',
+'protectlogpage' => 'Log palinduangan',
+'protectedarticle' => 'malinduangkan "[[$1]]"',
 'modifiedarticleprotection' => 'maubah tingkek perlindungan "[[$1]]"',
 'protectcomment' => 'Alasan:',
 'protectexpiry' => 'Kadaluwarsa:',
@@ -1127,23 +1316,23 @@ Awak dapek maubah tingkek perlindungannyo, walaupun indak pangaruah pado perlind
 'blanknamespace' => '(Utamo)',
 
 # Contributions
-'contributions' => 'Kontribusi {{GENDER:$1|pangguno}}',
+'contributions' => 'Jariah {{GENDER:$1|pangguno}}',
 'contributions-title' => 'Jariah pangguno untuak $1',
-'mycontris' => 'Jariah denai',
+'mycontris' => 'Jariah',
 'contribsub2' => 'Untuak $1 ($2)',
-'uctop' => '(atas)',
-'month' => 'Sajak bulan (dan sabalunnyo):',
-'year' => 'Sajak taun (dan sabalunnyo):',
+'uctop' => '(ateh)',
+'month' => 'Dari bulan (dan sabalunnyo):',
+'year' => 'Dari taun (dan sabalunnyo):',
 
-'sp-contributions-newbies' => 'Tampilkan jariah pangguno baru',
-'sp-contributions-blocklog' => 'log pambalokiran',
+'sp-contributions-newbies' => 'Tampilkan jariah pangguno baru sajo',
+'sp-contributions-blocklog' => 'log pamblokiran',
 'sp-contributions-deleted' => 'kontribusi pangguno nan lah batiadoan',
 'sp-contributions-uploads' => 'muek',
 'sp-contributions-logs' => 'log',
-'sp-contributions-talk' => 'kecek',
+'sp-contributions-talk' => 'maota',
 'sp-contributions-search' => 'Cari jariah',
 'sp-contributions-username' => 'Alamat IP atau namo pangguno:',
-'sp-contributions-toponly' => 'Hanyo manampilan suntiangan nan taakhia',
+'sp-contributions-toponly' => 'Hanyo manampilan suntiangan nan tarakhia',
 'sp-contributions-submit' => 'Cari',
 
 # What links here
@@ -1152,7 +1341,7 @@ Awak dapek maubah tingkek perlindungannyo, walaupun indak pangaruah pado perlind
 'whatlinkshere-page' => 'Laman:',
 'linkshere' => "Laman-laman ko bakaik ka '''[[:$1]]''':",
 'nolinkshere' => "Indak ado laman nan punyo tautan ka '''[[:$1]]'''.",
-'isredirect' => 'laman pengalihan',
+'isredirect' => 'laman pengaliahan',
 'istemplate' => 'transklusi',
 'isimage' => 'tautan berkas',
 'whatlinkshere-prev' => '{{PLURAL:$1|sabalunnyo|sabalunnyo $1}}',
@@ -1162,20 +1351,20 @@ Awak dapek maubah tingkek perlindungannyo, walaupun indak pangaruah pado perlind
 'whatlinkshere-hidetrans' => '$1 transklusi',
 'whatlinkshere-hidelinks' => '$1 pranala',
 'whatlinkshere-hideimages' => '$1 pahubuang berkas',
-'whatlinkshere-filters' => 'Penapis',
+'whatlinkshere-filters' => 'Panapiah',
 
 # Block/unblock
 'blockip' => 'Blokir pangguno',
-'ipboptions' => '2 jam:2 hours,1 hari:1 day,3 hari:3 days,1 minggu:1 week,2 minggu:2 weeks,1 bulan:1 month,3 bulan:3 months,6 bulan:6 months,1 tahun:1 year,salamonyo:infinite',
+'ipboptions' => '2 jam:2 hours,1 hari:1 day,3 hari:3 days,1 minggu:1 week,2 minggu:2 weeks,1 bulan:1 month,3 bulan:3 months,6 bulan:6 months,1 taun:1 year,salamonyo:infinite',
 'ipblocklist' => 'Pangguno tablokir',
 'blocklink' => 'balokir',
-'unblocklink' => 'hilangkan balokir',
+'unblocklink' => 'hilangkan blokir',
 'change-blocklink' => 'ubah balokir',
 'contribslink' => 'jariah',
-'blocklogpage' => 'Log pambalokiran',
-'blocklogentry' => 'memblokir [[$1]] dalam maso berlaku $2 $3',
+'blocklogpage' => 'Log pamblokiran',
+'blocklogentry' => 'mamblokir [[$1]] dalam maso $2 $3',
 'unblocklogentry' => 'mahilangkan blokir $1',
-'block-log-flags-nocreate' => 'cipta akun dimatikan',
+'block-log-flags-nocreate' => 'mambuek akun dimatikan',
 
 # Move page
 'movepagetext' => "Formulir di bawah ko digunoan untuak maubah namo suatu laman dan mamindahkan semua data riwayat ka namo baru. Judul lamo tu akan manjadi laman peralihan manuju judul yang baru. Pranala ka judul lamo indak akan baubah. Pastikan diperiksa laman yang [[Special:DoubleRedirects|peralihan ganda]] atau [[Special:BrokenRedirects|peralihan rusak]]. Awak bertanggungjawab untuak memastikan bahwa pranala tu terus manyambuang ka laman yang seharusnyo.
@@ -1183,12 +1372,12 @@ Awak dapek maubah tingkek perlindungannyo, walaupun indak pangaruah pado perlind
 Perhatikan bahwa laman '''indak''' akan dipindah apobilo lah ado laman yang manggunokan judul yang baru, kecuali bilo laman tu kosong atau marupokan laman peralihan dan indak punyo riwayat suntingan. Maksudnyo awak dapek maubah namo laman seperti samulo apobilo ado kesalahan, dan awak indak dapek manimpo laman yang lah ado.
 
 '''Peringatan:''' Iko dapek maakibatkan parubahan yang tak diduga pado laman yang populer. Jadi pastikan awak paham akibat tindakan ko sabalun melanjutkannyo.",
-'movepagetalktext' => "Laman ota yang bakaitan akan dipindahkan sacaro otomatis '''kecuali apobilo:'''
+'movepagetalktext' => "Laman diskusi nan bakaitan akan dipindahkan sacaro otomatis '''kacuali apobilo:'''
 
-*Sebuah laman ota yang indak kosong lah ado pado judul baru, atau
-*Awak indak memberi tando pado kotak di bawahnyo
+*Sabuah laman diskusi nan indak kosong lah ado pado judul baru, atau
+*Angku indak mangagiah tando pado kotak di bawah.
 
-Dalam kasus tu, apobilo diinginkan, awak dapek mamindahkan atau manggabuangkan laman sacaro manual.",
+Dalam kasus tu, kok amuah Angku dapek mamindahkan ataupun manggabuangkan laman sacaro manual.",
 'movearticle' => 'Pindahkan laman',
 'newtitle' => 'Ka judul baru:',
 'move-watch' => 'Pantau laman ko',
@@ -1212,62 +1401,65 @@ Dalam kasus tu, apobilo diinginkan, awak dapek mamindahkan atau manggabuangkan l
 
 # Thumbnails
 'thumbnail-more' => 'Pagadang',
-'thumbnail_error' => 'Gagal mambuek thumbnail : $1',
+'thumbnail_error' => 'Gagal mambuek miniatur: $1',
 
 # Tooltip help for the actions
 'tooltip-pt-userpage' => 'Laman pangguno sanak',
-'tooltip-pt-mytalk' => 'Laman ota sanak',
-'tooltip-pt-preferences' => 'Preferensi denai',
-'tooltip-pt-watchlist' => 'Daftar laman nan denai pantau.',
+'tooltip-pt-anonuserpage' => 'Laman pangguno IP Sanak',
+'tooltip-pt-mytalk' => 'Laman diskusi sanak',
+'tooltip-pt-anontalk' => 'Diskusi tantang suntiangan dari alamat IP ko',
+'tooltip-pt-preferences' => 'Pangaturan denai',
+'tooltip-pt-watchlist' => 'Dafta laman nan dipantau.',
 'tooltip-pt-mycontris' => 'Daftar jariah Sanak',
-'tooltip-pt-login' => 'Sanak disarankan untuak masuak log; musiki, hal tu indak diwajibkan',
+'tooltip-pt-login' => 'Sanak disaranan untuak masuak log; walaupun indak wajib',
 'tooltip-pt-logout' => 'Kalua log',
 'tooltip-ca-talk' => 'Parudiangan tantang isi laman',
-'tooltip-ca-edit' => 'Sanak dapek manyuntiang laman iko. Silakan gunokan tombol pratonton sabalun manyimpan',
+'tooltip-ca-edit' => 'Angku dapek manyuntiang laman ko. Silakan gunoan tombol pratonton sabalun manyimpan',
 'tooltip-ca-addsection' => 'Mulai bagian baru',
 'tooltip-ca-viewsource' => 'Laman ko dilinduangi.
-Sanak hanyo buliah caliak sumbernyo sajo',
-'tooltip-ca-history' => 'Pabaiakkan sabalunnyo dari laman ko',
-'tooltip-ca-protect' => 'Lindungi laman ko',
-'tooltip-ca-delete' => 'Hapuih laman iko',
+Sanak hanyo buliah mancaliak sumbernyo sajo',
+'tooltip-ca-history' => 'Revisi sabalunnyo dari laman ko',
+'tooltip-ca-protect' => 'Linduangi laman ko',
+'tooltip-ca-delete' => 'Hapuih laman ko',
 'tooltip-ca-move' => 'Pindahan laman ko',
-'tooltip-ca-watch' => 'Tambahkan laman ko ka daftar pantauan sanak',
-'tooltip-ca-unwatch' => 'Kaluaan laman ko dari senarai pantauan awak',
+'tooltip-ca-watch' => 'Tambahkan laman ko ka dafta pantauan sanak',
+'tooltip-ca-unwatch' => 'Kaluaan laman ko dari daftapantau',
 'tooltip-search' => 'Cari {{SITENAME}}',
-'tooltip-search-go' => 'Cari suatu laman dengan namo yang samo jiko tasadio',
-'tooltip-search-fulltext' => 'Cari laman untuak teks iko',
-'tooltip-p-logo' => 'Kunjuangi laman utamo',
-'tooltip-n-mainpage' => 'Kunjuangi laman Utamo',
-'tooltip-n-mainpage-description' => 'Kunjuangi laman utamo',
-'tooltip-n-portal' => 'Tantang proyek, apa nan dapek Sanak lakukan, dima untuak manamukan sasuatu',
-'tooltip-n-currentevents' => 'Tamukan informasi manganai latar balakang kajadian kini ko',
-'tooltip-n-recentchanges' => 'Daftar panyuntiangan baru dalam wiki',
-'tooltip-n-randompage' => 'Muek sambarang laman',
+'tooltip-search-go' => 'Cari laman jo namo nan samo jikok ado',
+'tooltip-search-fulltext' => 'Cari laman untuak teks ko',
+'tooltip-p-logo' => 'Kunjuangi palanta',
+'tooltip-n-mainpage' => 'Kunjuangi palanta',
+'tooltip-n-mainpage-description' => 'Kunjuangi palanta',
+'tooltip-n-portal' => 'Tantang proyek, nan dapek Sanak buek, dima ka basobok',
+'tooltip-n-currentevents' => 'Cari informasi manganai latar balakang kajadian ko',
+'tooltip-n-recentchanges' => 'Dafta parubahan baru dalam wiki',
+'tooltip-n-randompage' => 'Muek sumbarang laman',
 'tooltip-n-help' => 'Tampek mancari bantuan',
-'tooltip-t-whatlinkshere' => 'Daftar dari kasado laman wiki nan tahubuang kasiko',
-'tooltip-t-recentchangeslinked' => 'Parubahan baru halaman nan bakaik jo laman ko',
+'tooltip-t-whatlinkshere' => 'Dafta dari sado laman wiki nan tahubuang kasiko',
+'tooltip-t-recentchangeslinked' => 'Parubahan baru laman nan bakaik jo laman ko',
 'tooltip-feed-rss' => 'Umpan RSS untuak laman ko',
 'tooltip-feed-atom' => 'Umpan Atom untuak laman ko',
 'tooltip-t-contributions' => 'Caliak dafta jariah pangguno ko',
-'tooltip-t-emailuser' => 'Kirimkan e-mail ka pangguno ko',
+'tooltip-t-emailuser' => 'Kirim surel ka pangguno ko',
 'tooltip-t-upload' => 'Muek berkas',
-'tooltip-t-specialpages' => 'Daftar dari kasado laman istimewa',
+'tooltip-t-specialpages' => 'Dafta dari sado laman istimewa',
 'tooltip-t-print' => 'Versi cetak dari laman ko',
-'tooltip-t-permalink' => 'Pranala parmanen untuak pabaiakkan laman ko',
+'tooltip-t-permalink' => 'Pranala permanen untuak revisi laman ko',
 'tooltip-ca-nstab-main' => 'Caliak isi laman',
 'tooltip-ca-nstab-user' => 'Caliak laman pangguno',
-'tooltip-ca-nstab-special' => 'Iko adolah laman istimewa, awak indak buliah manyuntiangnyo',
+'tooltip-ca-nstab-media' => 'Caliak laman media',
+'tooltip-ca-nstab-special' => 'Laman istimewa, indak dapek disuntiang',
 'tooltip-ca-nstab-project' => 'Caliak laman proyek',
 'tooltip-ca-nstab-image' => 'Caliak laman berkas',
 'tooltip-ca-nstab-template' => 'Caliak templat',
 'tooltip-ca-nstab-help' => 'Caliak laman bantuan',
 'tooltip-ca-nstab-category' => 'Caliak laman kategori',
-'tooltip-minoredit' => 'Tandoi iko sabagai suntingan ketek',
-'tooltip-save' => 'Simpan yang awak ubah ko',
-'tooltip-preview' => 'Pratonton parubahan, harap gunokan iko sabalun disimpan',
+'tooltip-minoredit' => 'Tandoi iko sabagai suntiangan ketek',
+'tooltip-save' => 'Simpan nan diubah',
+'tooltip-preview' => 'Caliak dulu nan diubah, gunokan ko sabalun manyimpan',
 'tooltip-diff' => 'Caliak parubahan nan alah awak buek tu',
 'tooltip-compareselectedversions' => 'Caliak pabedoan antaro duo revisi pilihan laman ko',
-'tooltip-watch' => 'Tambahkan laman ko ka senarai pantauan awak',
+'tooltip-watch' => 'Tambahkan laman ko ka daftapantau',
 'tooltip-recreate' => 'Buek baliak laman walaupun sabananyo pernah dihapuih',
 'tooltip-upload' => 'Mulai mamuek',
 'tooltip-rollback' => '"Baliakkan" uruangkan suntiang laman ko pado kontribusi tarakhir dalam sakali klik',
@@ -1278,30 +1470,126 @@ Sanak hanyo buliah caliak sumbernyo sajo',
 # Metadata
 'notacceptable' => 'Layanan wiki indak manyadioan data dalam format yang dapek dibaco dek pelanggan awak.',
 
+# Attribution
+'anonymous' => '{{PLURAL:$1|Pangguno}} anonim {{SITENAME}}',
+'siteuser' => 'pangguno {{SITENAME}} $1',
+'anonuser' => 'pangguno anonim {{SITENAME}} $1',
+'siteusers' => '{{PLURAL:$2|pangguno}} {{SITENAME}} $1',
+'anonusers' => '{{PLURAL:$2|pangguno}} anonim {{SITENAME}} $1',
+'creditspage' => 'Panghargaan laman',
+
+# Info page
+'pageinfo-title' => 'Informasi untuak "$1"',
+'pageinfo-header-basic' => 'Informasi dasar',
+'pageinfo-header-edits' => 'Riwayaik suntiangan',
+'pageinfo-header-restrictions' => 'Palinduangan laman',
+'pageinfo-header-properties' => 'Properti laman',
+'pageinfo-display-title' => 'Judua tampilan',
+'pageinfo-length' => 'Panjang laman (dalam bita)',
+'pageinfo-article-id' => 'ID Laman',
+'pageinfo-firstuser' => 'Pambuek laman',
+
+# Skin names
+'skinname-standard' => 'Klasik',
+'skinname-nostalgia' => 'Nostalgia',
+'skinname-cologneblue' => 'Biru Köln',
+'skinname-monobook' => 'MonoBook',
+'skinname-myskin' => 'MySkin',
+'skinname-chick' => 'Chick',
+'skinname-simple' => 'Sadarano',
+'skinname-modern' => 'Moderen',
+'skinname-vector' => 'Vektor',
+
 # Browsing diffs
 'previousdiff' => '← Revisi sabalunnyo',
 'nextdiff' => 'Revisi salanjuiknyo →',
 
 # Media information
+'thumbsize' => 'Ukuran miniatur:',
+'widthheight' => '$1 × $2',
+'widthheightpage' => '$1 × $2, $3 {{PLURAL:$3|laman}}',
+'file-info' => 'ukuran berkas: $1, tipe MIME: $2',
 'file-info-size' => '$1 × $2 piksel, ukuran berkas: $3, tipe MIME: $4',
-'file-nohires' => 'Indak tasadio resolusi yang labiah tinggi.',
-'svg-long-desc' => 'SVG berkas, nominal $1 × $2 piksel, ukuran berkas: $3',
-'show-big-image' => 'Resolusi penuh',
+'file-info-size-pages' => '$1 × $2 piksel, ukuran berkas: $3, tipe MIME: $4, $5 {{PLURAL:$5|laman}}',
+'file-nohires' => 'Indak tasadio resolusi nan labiah gadang.',
+'svg-long-desc' => 'Berkas SVG, $1 × $2 piksel, ukuran berkas: $3',
+'svg-long-desc-animated' => 'Berkas anmasi SVG, $1 × $2 piksel, ukuran berkas: $3',
+'show-big-image' => 'Resolusi panuah',
+'show-big-image-preview' => 'Ukuran pratonton ko: $1',
+'show-big-image-other' => '{{PLURAL:$2|Resolusi}} lainnyo: $1.',
+'show-big-image-size' => '$1 × $2 piksel',
+'file-info-gif-looped' => 'ulang',
+'file-info-gif-frames' => '$1 {{PLURAL:$1|bingkai}}',
+'file-info-png-looped' => 'ulang',
+'file-info-png-repeat' => 'dimainkan $1 {{PLURAL:$1|kali}}',
+'file-info-png-frames' => '$1 {{PLURAL:$1|bingkai}}',
+
+# Special:NewFiles
+'newimages-legend' => 'Panyaring',
+'newimages-label' => 'Namo berkas (atau sabagian darinyo):',
+'showhidebots' => '($1 bot)',
+'noimages' => 'Indak ado nan dicaliak.',
+'ilsubmit' => 'Cari',
+'bydate' => 'jo tanggal',
+'sp-newimages-showfrom' => 'Tampilkan berkas baru mulai dari $2, $1',
+
+# Video information, used by Language::formatTimePeriod() to format lengths in the above messages
+'video-dims' => '$1, $2 × $3',
+'seconds-abbrev' => '$1 d',
+'minutes-abbrev' => '$1 min',
+'hours-abbrev' => '$1 j',
+'days-abbrev' => '$1 h',
+'seconds' => '{{PLURAL:$1|$1 detik}}',
+'minutes' => '{{PLURAL:$1|$1 minik}}',
+'hours' => '{{PLURAL:$1|$1 jam}}',
+'days' => '{{PLURAL:$1|$1 hari}}',
+'ago' => '$1 nan lalu',
 
 # Bad image list
 'bad_image_list' => 'Ukurannyo adolah sabagai barikuik:
 
-Hanyo daftar butia (barih nan dimulai jo tando *) nan dianggap.
-Pranala patamo pado barih musiti pranala ka berkas buruak.
+Hanyo dafta butia (barih nan dimulai jo tando *) nan dianggap.
+Pranala patamo pado barih musti pranala ka berkas buruak.
 Satiok pranala salanjuiknyo pado barih nan samo dianggap pangacualian, yaitu laman dima berkas tasabuik bisa tajadi sajajar.',
 
+/*
+Short names for language variants used for language conversion links.
+To disable showing a particular link, set it to 'disable', e.g.
+'variantname-zh-sg' => 'disable',
+Variants for Chinese language
+*/
+'variantname-zh-hans' => 'hans',
+'variantname-zh-hant' => 'hant',
+'variantname-zh-cn' => 'cn',
+'variantname-zh-tw' => 'tw',
+'variantname-zh-hk' => 'hk',
+'variantname-zh-mo' => 'mo',
+'variantname-zh-sg' => 'sg',
+'variantname-zh-my' => 'my',
+'variantname-zh' => 'zh',
+
+# Variants for Gan language
+'variantname-gan-hans' => 'hans',
+'variantname-gan-hant' => 'hant',
+'variantname-gan' => 'gan',
+
+# Variants for Serbian language
+'variantname-sr-ec' => 'sr-ec',
+'variantname-sr-el' => 'sr-el',
+'variantname-sr' => 'sr',
+
+# Variants for Kazakh language
+'variantname-kk-kz' => 'kk-kz',
+'variantname-kk-tr' => 'kk-tr',
+'variantname-kk-cn' => 'kk-cn',
+
 # Metadata
 'metadata' => 'Metadata',
-'metadata-help' => 'Berkas ko mengandung informasi tambahan yang mungkin ditambahkan dek kamera digital atau pemindai yang digunokan untuak mambuek atau mendigitalisasi berkas. Jiko berkas ko lah mangalami modifikasi, rincian yang ado mungkin indak sacaro penuh merefleksikan modifikasi berkas tu.',
+'metadata-help' => 'Berkas ko ado informasi tambahan nan mungkin ditambahkan dek kamera digital atau pemindai yang digunokan untuak mambuek atau mendigitalisasi berkas. Jikok berkas ko lah mangalami modifikasi, rincian nan ado mungkin indak sacaro panuah merefleksi modifikasi dari berkas tu.',
 'metadata-expand' => 'Tampilkan rincian tambahan',
 'metadata-collapse' => 'Suruakkan rincian tambahan',
-'metadata-fields' => 'Tapak metadata gambar nan disenaraikan dalam pasan ko akan di masuakan pado tampilan laman gambar katiko tabel metadata disuruakkan. 
-Nan lainnyo akan tasuruak sacaro default.
+'metadata-fields' => 'Tapak metadata gamba nan didata dalam pasan ko akan di masuakan pado tampilan laman gambar katiko tabel metadata disuruakkan. 
+Nan lainnyo akan tasuruak sacaro baku.
 * make
 * model
 * datetimeoriginal
@@ -1316,25 +1604,64 @@ Nan lainnyo akan tasuruak sacaro default.
 * gpslongitude
 * gpsaltitude',
 
+# EXIF tags
+'exif-imagewidth' => 'Leba',
+'exif-imagelength' => 'Tinggi',
+'exif-bitspersample' => 'Bita per komponen',
+'exif-compression' => 'Skema kompresi',
+'exif-photometricinterpretation' => 'Komposisi piksel',
+'exif-orientation' => 'Orientasi',
+'exif-samplesperpixel' => 'Jumlah komponen',
+'exif-planarconfiguration' => 'Pangaturan data',
+'exif-imagedescription' => 'Judua gamba',
+'exif-make' => 'Produsen kamera',
+'exif-model' => 'Model kamera',
+'exif-software' => 'Parangkaik lunak',
+'exif-artist' => 'Pambuek',
+'exif-copyright' => 'Nan punyo hak cipta',
+'exif-exifversion' => 'Versi Exif',
+'exif-flashpixversion' => 'Dukuangan versi Flashpix',
+'exif-colorspace' => 'Ruang warna',
+'exif-componentsconfiguration' => 'Arti tiok komponen',
+'exif-compressedbitsperpixel' => 'Mode kompresi gamba',
+'exif-pixelydimension' => 'Leba gamba',
+'exif-pixelxdimension' => 'Tinggi gamba',
+'exif-usercomment' => 'Komen pangguno',
+'exif-relatedsoundfile' => 'Berkas audio nan bahubuangan',
+
 # External editor support
 'edit-externally' => 'Suntiang berkas ko dengan aplikasi lua',
 'edit-externally-help' => '(Caliak [//www.mediawiki.org/wiki/Manual:External_editors instruksi pangaturan] untuak informasi lanjuiknyo)',
 
 # 'all' in various places, this might be different for inflected languages
-'watchlistall2' => 'semua',
-'namespacesall' => 'semua',
-'monthsall' => 'sado',
+'watchlistall2' => 'kasadonyo',
+'namespacesall' => 'sadonyo',
+'monthsall' => 'sadonyo',
 
 # Watchlist editing tools
 'watchlisttools-view' => 'Tampilkan parubahan takaik',
-'watchlisttools-edit' => 'Tampilkan dan suntiang senarai pantauan',
-'watchlisttools-raw' => 'Suntiang senarai pantauan mentah',
+'watchlisttools-edit' => 'Tampilkan sarato suntiang daftapantau',
+'watchlisttools-raw' => 'Suntiang pantauan mantah',
+
+# Signatures
+'signature' => '[[{{ns:user}}:$1|$2]] ([[{{ns:user_talk}}:$1|maota]])',
 
 # Core parser functions
-'duplicate-defaultsort' => '\'\'\'Peringatan:\'\'\' Kunci panguruitan default "$2" sabalunnyo maabaikan kunci panguruitan default "$1".',
+'duplicate-defaultsort' => '\'\'\'Peringatan:\'\'\' Kunci panguruitan default "$2" sabalunnyo mangabaikan kunci panguruitan default "$1".',
+
+# Special:Version
+'version-skins' => 'Kulik',
+'version-other' => 'Lain-lain',
+'version-license' => 'Lisensi',
+'version-entrypoints-articlepath' => '[https://www.mediawiki.org/wiki/Manual:$wgArticlePath Artikel path]',
+'version-entrypoints-scriptpath' => '[https://www.mediawiki.org/wiki/Manual:$wgScriptPath Skrip path]',
+
+# Special:FilePath
+'filepath-page' => 'Berkas:',
 
 # Special:FileDuplicateSearch
 'fileduplicatesearch-result-n' => 'Berkas "$1" punyo {{PLURAL:$2|1 duplikat identik|$2 duplikat identik}}.',
+'fileduplicatesearch-noresults' => 'Indak basobok berkas banamo "$1".',
 
 # Special:SpecialPages
 'specialpages' => 'Laman istimewa',
@@ -1350,7 +1677,18 @@ Nan lainnyo akan tasuruak sacaro default.
 #Latakan sado fragmen regex di bawah barih ko. Bia se barih apo adonyo</pre>',
 
 # Special:Tags
-'tag-filter' => '[[Special:Tags|Tag]] bateh:',
+'tag-filter' => '[[Special:Tags|Tag]] sariang:',
+'tag-filter-submit' => 'Sariang',
+'tags-title' => 'Tag',
+'tags-tag' => 'Namo tag',
+'tags-edit' => 'suntiang',
+'tags-hitcount' => '$1 {{PLURAL:$1|parubahan}}',
+
+# New logging system
+'logentry-newusers-newusers' => 'Akun pangguno $1 lah dibuek',
+'logentry-newusers-create' => '$1 mambuek akun pangguno',
+'logentry-newusers-create2' => 'Akun pangguno $3 dibuek jo $1',
+'logentry-newusers-autocreate' => 'Akun $1 dibuek sacaro otomatis',
 
 # Search suggestions
 'searchsuggest-search' => 'Cari',
index 3ac29b3..0ebf2f3 100644 (file)
@@ -1410,7 +1410,7 @@ $1",
 'search-interwiki-default' => 'Најдено на $1:',
 'search-interwiki-more' => '(уште)',
 'search-relatedarticle' => 'Поврзано',
-'mwsuggest-disable' => 'Оневозможи AJAX-предлози',
+'mwsuggest-disable' => 'Оневозможи предлози во пребарувањето',
 'searcheverything-enable' => 'Барај во сите именски простори',
 'searchrelated' => 'поврзано',
 'searchall' => 'сè',
@@ -3233,6 +3233,7 @@ $1',
 'pageinfo-robot-noindex' => 'Не се индексира',
 'pageinfo-views' => 'Број на посети',
 'pageinfo-watchers' => 'Број на набљудувачи',
+'pageinfo-few-watchers' => 'Помалку од $1 {{PLURAL:$1|набљудувач|набљудувачи}}',
 'pageinfo-redirects-name' => 'Пренасочувања кон страницата',
 'pageinfo-redirects-value' => '$1',
 'pageinfo-subpages-name' => 'Потстраници на страницата',
index 356937b..bb9dfb9 100644 (file)
@@ -341,7 +341,7 @@ $messages = array(
 'tog-hidepatrolled' => 'റോന്തുചുറ്റിയ തിരുത്തുകൾ പുതിയമാറ്റങ്ങളിൽ പ്രദർശിപ്പിക്കാതിരിക്കുക',
 'tog-newpageshidepatrolled' => 'റോന്തുചുറ്റിയ താളുകൾ പുതിയതാളുകളുടെ പട്ടികയിൽ പ്രദർശിപ്പിക്കാതിരിക്കുക',
 'tog-extendwatchlist' => 'ഏറ്റവും പുതിയവ മാത്രമല്ല, എല്ലാ മാറ്റങ്ങളും ദൃശ്യമാകുന്ന വിധത്തിൽ ശ്രദ്ധിക്കുന്ന താളുകളുടെ പട്ടിക വികസിപ്പിക്കുക.',
-'tog-usenewrc' => 'സമീപകാല മാറ്റങ്ങൾ താളിലും ശ്രദ്ധിക്കുന്നവയുടെ പട്ടികയിലും മാറ്റങ്ങൾ താളിനനുസരിച്ച് ഗണമായി പ്രദർശിപ്പിക്കുക (ജാവാസ്ക്രിപ്റ്റ് ആവശ്യമാണ്)',
+'tog-usenewrc' => 'സമീപകാല മാറ്റങ്ങൾ, ശ്രദ്ധിക്കുന്നവയുടെ പട്ടിക എന്നീ താളുകളിലെ വിവരങ്ങൾ താളുകൾക്കനുസരിച്ചുള്ള കൂട്ടങ്ങളായി ഒതുക്കി പ്രദർശിപ്പിക്കുക (ജാവാസ്ക്രിപ്റ്റ് ആവശ്യമാണ്)',
 'tog-numberheadings' => 'ഉപവിഭാഗങ്ങൾക്ക് ക്രമസംഖ്യ കൊടുക്കുക',
 'tog-showtoolbar' => 'തിരുത്തൽ റ്റൂൾബാർ  പ്രദർശിപ്പിക്കുക (ജാവാസ്ക്രിപ്റ്റ്)',
 'tog-editondblclick' => 'താളുകളിൽ ഇരട്ട ക്ലിക്ക് ചെയ്യുമ്പോൾ തിരുത്താനനുവദിക്കുക (ജാവാസ്ക്രിപ്റ്റ്)',
index 056cd0d..f863d34 100644 (file)
@@ -2027,7 +2027,7 @@ URL нь зөв болон сайт ажиллагаатай байгаа эсэ
 'usermessage-template' => 'МедиаВики:ХэрэглэгчийнМэдээ',
 
 # Watchlist
-'watchlist' => 'Ð\9cиний Ñ\85Ñ\8fнаж Ð±Ñ\83й Ñ\85Ñ\83Ñ\83дÑ\81Ñ\83Ñ\83д',
+'watchlist' => 'Ð¥Ñ\8fнаÑ\85 Ð¶Ð°Ð³Ñ\81аалÑ\82',
 'mywatchlist' => 'Хяналтын хуудсын жагсаалт',
 'watchlistfor2' => 'Хэрэглэгч: $1 $2',
 'nowatchlist' => 'Танд хянаж буй зүйл байхгүй.',
index 83607c2..84b1507 100644 (file)
@@ -629,7 +629,7 @@ Jangan lupa untuk mengubah [[Special:Preferences|keutamaan anda di {{SITENAME}}]
 'gotaccount' => "Sudah mempunyai akaun? '''$1'''.",
 'gotaccountlink' => 'Log masuk',
 'userlogin-resetlink' => 'Lupa nama pengguna/kata laluan anda?',
-'createaccountmail' => 'melalui e-mel',
+'createaccountmail' => 'Gunakan kata laluan rawak yang sementara dan hantarnya ke alamat e-mel yang dinyatakan di bawah',
 'createaccountreason' => 'Sebab:',
 'badretype' => 'Sila ulangi kata laluan dengan betul.',
 'userexists' => 'Nama pengguna yang diisikan telah pun digunakan.
@@ -914,10 +914,10 @@ disalin daripada domain awam atau mana-mana sumber bebas lain (lihat $1 untuk bu
 '''JANGAN KIRIM KARYA HAK CIPTA ORANG LAIN TANPA KEBENARAN!'''",
 'longpageerror' => "'''Ralat: Teks yang anda serahkan itu panjangnya {{PLURAL:$1|1|$1}} kilobait, iaitu lebih panjang daripada had maksimum {{PLURAL:$2|1|$2}} kilobait.'''
 Oleh itu, ia tidak boleh disimpan.",
-'readonlywarning' => "'''AMARAN: Pangkalan data telah dikunci untuk penyenggaraan. Justeru, anda tidak boleh menyimpan suntingan anda pada masa sekarang.
-Anda boleh menyalin teks anda ke dalam komputer anda terlebih dahulu dan simpan teks tersebut di sini pada masa akan datang.'''
+'readonlywarning' => "'''Amaran: Pangkalan data ini dikunci untuk tujuan penyelenggaraan , maka anda tidak akan dapat menyimpan suntingan anda buat sekarang.'''
+Anda boleh menyalin tampal teks anda pada fail teks dan menyimpannya untuk lain kali.
 
-Yang berikut ialah penjelasan yang diberikan: $1",
+Penyelia yang menguncinya memberikan penjelasan ini: $1",
 'protectedpagewarning' => "'''Amaran: Laman ini telah dikunci supaya hanya mereka yang mempunyai keistimewaan penyelia boleh menyuntingnya.'''
 Masukan log terakhir ditunjukkan di bawah untuk rujukan:",
 'semiprotectedpagewarning' => "'''Nota:''' Laman ini telah dikunci agar hanya pengguna berdaftar sahaja boleh menyuntingnya.
@@ -2121,7 +2121,7 @@ Memerlukan sekurang-kurangnya satu domain peringkat tinggi, cth. "*.org".<br />
 # Special:ActiveUsers
 'activeusers' => 'Senarai pengguna aktif',
 'activeusers-intro' => 'Yang berikut ialah senarai pengguna yang bergiat sejak {{PLURAL:$1|semalam|$1 hari lalu}}.',
-'activeusers-count' => '$1 {{PLURAL:$1|suntingan|suntingan}} sejak {{PLURAL:$3|semalam|$3 hari lalu}}',
+'activeusers-count' => '$1 tindakan sejak {{PLURAL:$3|semalam|$3 hari lalu}}',
 'activeusers-from' => 'Tunjukkan pengguna bermula pada:',
 'activeusers-hidebots' => 'Sorokkan bot',
 'activeusers-hidesysops' => 'Sorokkan pentadbir',
@@ -2351,9 +2351,9 @@ Ini adalah tetapan semasa bagi laman '''$1''':",
 Ini adalah tetapan semasa bagi laman '''$1''':",
 'protect-cascadeon' => 'Laman ini dilindungi kerana ia terkandung dalam {{PLURAL:$1|laman|laman-laman}} berikut, yang dilindungi secara melata. Anda boleh menukar peringkat perlindunan laman ini, akan tetapi ia tidak akan menjejaskan perlindungan melata tersebut.',
 'protect-default' => 'Benarkan semua pengguna',
-'protect-fallback' => 'Perlukan keizinan "$1"',
-'protect-level-autoconfirmed' => 'Sekat pengguna baru dan pengguna tidak berdaftar',
-'protect-level-sysop' => 'Pentadbir sahaja',
+'protect-fallback' => 'Benarkan pengguna yang berizin "$1" sahaja',
+'protect-level-autoconfirmed' => 'Benarkan pengguna yang diautosahkan sahaja',
+'protect-level-sysop' => 'Benarkan pentadbir sahaja',
 'protect-summary-cascade' => 'melata',
 'protect-expiring' => 'sehingga $1 (UTC)',
 'protect-expiring-local' => 'luput $1',
@@ -2652,13 +2652,18 @@ sahkan bahawa anda betul-betul mahu melakukan tindakan ini.',
 # Move page
 'move-page' => 'Pindahkan $1',
 'move-page-legend' => 'Pindahkan laman',
-'movepagetext' => "Gunakan borang di bawah untuk menukar nama laman dan memindahkan semua maklumat sejarahnya ke nama baru. Tajuk yang lama akan dijadikan lencongan ke tajuk yang baru. Anda juga boleh mengemaskinikan semua lencongan yang menuju ke tajuk asal supaya menuju ke tajuk baru. Sebaliknya, anda boleh menyemak sekiranya terdapat [[Special:DoubleRedirects|lencongan berganda]] atau [[Special:BrokenRedirects|lencongan rosak]]. Anda bertanggungjawab memastikan semua pautan bersambung ke laman yang sepatutnya.
+'movepagetext' => "Menggunakan borang di bawah akan menukar nama halaman dan memindahkan segala sejarahnya kepada nama baru itu.
 
-Sila ambil perhatian bahawa laman tersebut '''tidak''' akan dipindahkan sekiranya laman dengan tajuk yang baru tadi telah wujud, melainkan apabila
-laman tersebut kosong atau merupakan laman lencongan dan tidak mempunyai sejarah penyuntingan. Ini bermakna anda boleh menukar semula nama sesebuah
-laman kepada nama yang asal jika anda telah melakukan kesilapan, dan anda tidak boleh menulis ganti laman yang telah wujud.
+Tajuk yang lama akan menjadi halaman lencongan kepada tajuk baru.
+Anda boleh mengemaskinikan lencongan yang menghala ke tajuk asal secara automatik.
+Jika anda memilih untuk tidak berbuat demikian, tolong semak untuk mencari lencongan [[Special:DoubleRedirects|berganda]] atau [[Special:BrokenRedirects|terputus]].
+Anda dipertanggungjawabkan untuk memastikan agar semua pautan tetap menghala ke tempat yang sepatutnya.
 
-'''AMARAN!''' Tindakan ini boleh menjadi perubahan yang tidak dijangka dan drastik bagi laman popular. Oleh itu, sila pastikan anda faham akibat yang mungkin timbul sebelum meneruskannya.",
+Sila ingat bahasa halaman '''tidak''' akan dipindahkan jika tajuk barunya sudah diambil oleh halaman yang sedia ada, melainkan halaman yang sedia ada tersebut merupakan lencongan tanpa sebarang sejarah suntingan.
+Ertinya, anda boleh menukar kembali nama halaman ke nama yang sebelumnya jika anda terbuat silap, tetapi anda tidak boleh menulis ganti halaman yang sedia ada.
+
+'''Amaran!'''
+Tindakan ini boleh mendatangkan perubahan yang drastik dan tidak dijangka untuk halaman yang popular; sila pasti bahawa anda memahami akibatnya sebelum meneruskan.",
 'movepagetext-noredirectfixer' => "Borang di bawah akan menamakan semula sesebuah laman, memindahkan kesemua sejarahnya ke nama baru.
 Nama lamanya akan menjadi sebuah laman lencongan ke laman baru tadi.
 Pastikan [[Special:DoubleRedirects|lencongan berganda]] atau [[Special:BrokenRedirects|rosak]] sudah diperiksa.
@@ -2979,6 +2984,7 @@ Simpan dalam komputer anda dan muat naiknya di sini.',
 'pageinfo-robot-noindex' => 'Tidak boleh diindekskan',
 'pageinfo-views' => 'Bilangan kunjungan',
 'pageinfo-watchers' => 'Bilangan pemantau halaman',
+'pageinfo-few-watchers' => 'Kurang daripada $1 orang pemantau',
 'pageinfo-redirects-name' => 'Lencongan ke halaman ini',
 'pageinfo-subpages-name' => 'Subhalaman untuk halaman ini',
 'pageinfo-subpages-value' => '$1 ($2 lencongan; $3 bukan lencongan)',
@@ -3762,7 +3768,7 @@ Imej ditunjuk dalam leraian penuh, jenis fail yang lain dibuka dengan atur cara
 'specialpages-group-highuse' => 'Laman popular',
 'specialpages-group-pages' => 'Senarai laman',
 'specialpages-group-pagetools' => 'Alatan laman',
-'specialpages-group-wiki' => 'Data dan alatan wiki',
+'specialpages-group-wiki' => 'Data dan peralatan',
 'specialpages-group-redirects' => 'Laman khas yang melencong',
 'specialpages-group-spam' => 'Alatan spam',
 
@@ -3859,6 +3865,7 @@ Imej ditunjuk dalam leraian penuh, jenis fail yang lain dibuka dengan atur cara
 'logentry-newusers-newusers' => 'Akaun pengguna $1 dibuka',
 'logentry-newusers-create' => 'Akaun pengguna $1 dibuka',
 'logentry-newusers-create2' => 'Akaun pengguna $3 dibuka oleh $1',
+'logentry-newusers-byemail' => 'Akaun pengguna $3 dibuka oleh $1 dan kata laluannya dihantar melalui e-mel',
 'logentry-newusers-autocreate' => 'Akaun $1 dibuka secara automatik',
 'logentry-rights-rights' => '$1 menukar keahlian kumpulan untuk $3 dari $4 ke $5',
 'logentry-rights-rights-legacy' => '$1 menukar keahlian kumpulan untuk $3',
@@ -3917,6 +3924,7 @@ Ataupun, anda boleh menggunakan borang yang mudah di bawah. Ulasan anda akan dic
 'api-error-ok-but-empty' => 'Ralat dalaman: tiada gerak balas dari pelayan.',
 'api-error-overwrite' => 'Menulis ganti fail yang telah wujud adalah tidak dibenarkan.',
 'api-error-stashfailed' => 'Ralat dalaman: pelayan tidak dapat menyimpan fail sementara.',
+'api-error-publishfailed' => 'Ralat dalaman: Pelayan tidak dapat menerbitkan fail sementara.',
 'api-error-timeout' => 'Pelayan tidak bergerak balas dalam tempoh yang diharapkan.',
 'api-error-unclassified' => 'Berlakunya ralat yang tidak diketahui',
 'api-error-unknown-code' => 'Ralat tidak diketahui: "$1"',
index 1294e51..448f4d3 100644 (file)
@@ -3708,7 +3708,7 @@ Stampi huwa mogħrija b'risoluzzjoni sħiħa, tipi tal-fajl oħrajn jibdew bil-p
 * Paġni speċjali normali.
 * <span class="mw-specialpagerestricted">Paġni speċjali riservati.</span>
 * <span class="mw-specialpagecached">Paġni speċjali disponibbli f\'verżjoni cache (jistgħu jkunu skaduti).</span>',
-'specialpages-group-maintenance' => 'Rapporti tal-manteniment',
+'specialpages-group-maintenance' => "Rapporti ta' manutenzjoni",
 'specialpages-group-other' => 'Paġni speċjali oħrajn',
 'specialpages-group-login' => 'Idħol / oħloq kont',
 'specialpages-group-changes' => 'L-Aħħar modifiki u reġistri',
index 8f63d34..28834b3 100644 (file)
@@ -1,5 +1,5 @@
 <?php
-/** Norwegian Bokmål (norsk (bokmål)‎)
+/** Norwegian Bokmål (norsk bokmål)
  *
  * See MessagesQqq.php for message documentation incl. usage of parameters
  * To improve a translation please visit http://translatewiki.net
index 81c4b42..0417459 100644 (file)
@@ -1427,7 +1427,7 @@ Probeer een andere zoekopdracht.',
 'search-interwiki-default' => '$1 resultaten:',
 'search-interwiki-more' => '(meer)',
 'search-relatedarticle' => 'Gerelateerd',
-'mwsuggest-disable' => 'Suggesties via AJAX uitschakelen',
+'mwsuggest-disable' => 'Zoekuggesties uitschakelen',
 'searcheverything-enable' => 'In alle naamruimten zoeken',
 'searchrelated' => 'gerelateerd',
 'searchall' => 'alle',
@@ -3260,6 +3260,7 @@ Meestal wordt dit door een externe koppeling op een zwarte lijst veroorzaakt.',
 'pageinfo-robot-noindex' => 'Niet indexeerbaar',
 'pageinfo-views' => 'Aantal weergaven',
 'pageinfo-watchers' => 'Aantal paginavolgers',
+'pageinfo-few-watchers' => 'Minder dan  {{PLURAL:$1|één volger|$1 volgers}}',
 'pageinfo-redirects-name' => 'Doorverwijzingen naar deze pagina',
 'pageinfo-subpages-name' => "Subpagina's van deze pagina",
 'pageinfo-subpages-value' => '$1 ($2 {{PLURAL:$2|doorverwijzing|doorverwijzingen}}; $3 {{PLURAL:$3|niet-doorverwijzing|niet-doorverwijzingen}})',
index d96f7ad..1bbceb6 100644 (file)
@@ -1,5 +1,5 @@
 <?php
-/** Norwegian Nynorsk (norsk (nynorsk)‎)
+/** Norwegian Nynorsk (norsk nynorsk)
  *
  * See MessagesQqq.php for message documentation incl. usage of parameters
  * To improve a translation please visit http://translatewiki.net
@@ -434,9 +434,9 @@ $messages = array(
 'category-subcat-count' => 'Kategorien har {{PLURAL:$2|berre denne underkategorien|{{PLURAL:$1|denne underkategorien|desse $1 underkategoriane}}, av totalt $2}}.',
 'category-subcat-count-limited' => 'Kategorien har {{PLURAL:$1|denne underkategorien|desse $1 underkategoriane}}.',
 'category-article-count' => 'Kategorien inneheld {{PLURAL:$2|berre denne sida|{{PLURAL:$1|denne sida|desse $1 sidene}}, av totalt $2}}.',
-'category-article-count-limited' => 'Følgjande {{PLURAL:$1|side|$1 sider}} er i denne kategorien.',
+'category-article-count-limited' => '{{PLURAL:$1|Denne sida|Desse $1 sidene}} er i kategorien.',
 'category-file-count' => 'Kategorien inneheld {{PLURAL:$2|berre den følgjande fila|dei følgjande {{PLURAL:$1|fil|$1 filene}}, av totalt $2}}.',
-'category-file-count-limited' => 'Følgjande {{PLURAL:$1|fil|$1 filer}} er i denne kategorien.',
+'category-file-count-limited' => '{{PLURAL:$1|Denne fila|Desse $1 filene}} er i kategorien.',
 'listingcontinuesabbrev' => 'vidare',
 'index-category' => 'Indekserte sider',
 'noindex-category' => 'Ikkje-indekserte sider',
@@ -2051,7 +2051,7 @@ Ei side vert handsama som ei fleirtydingsside om ho nyttar ein mal som er lenkja
 'double-redirect-fixer' => 'Omdirigeringsfiksar',
 
 'brokenredirects' => 'Blindvegsomdirigeringar',
-'brokenredirectstext' => 'Dei følgjande omdirigeringane viser til ei side som ikkje finst:',
+'brokenredirectstext' => 'Desse omdirigeringane viser til sider som ikkje finst:',
 'brokenredirects-edit' => 'endre',
 'brokenredirects-delete' => 'slett',
 
@@ -2214,7 +2214,7 @@ Det er påkravt med eit toppnivådomene, til dømes «*.org».<br />
 
 # Special:ListGroupRights
 'listgrouprights' => 'Rettar for brukargrupper',
-'listgrouprights-summary' => 'Følgjande liste viser brukargruppene som er definert på denne wikien, og kvar rettar dei har. Meir informasjon om dei ulike rettane ein kan ha finn ein [[{{MediaWiki:Listgrouprights-helppage}}|her]].',
+'listgrouprights-summary' => 'Detter ei liste som viser brukargruppene som er definerte på wikien, og kva rettar dei har. Det kan finnast [[{{MediaWiki:Listgrouprights-helppage}}|meir informasjon]]  om dei ulike rettane.',
 'listgrouprights-key' => '* <span class="listgrouprights-granted">Innvilga rettar</span>
 * <span class="listgrouprights-granted">Tilbaketrukne rettar</span>',
 'listgrouprights-group' => 'Gruppe',
@@ -2465,7 +2465,7 @@ Her er dei noverande innstillingane for sida '''$1''':",
 # Undelete
 'undelete' => 'Sletta sider',
 'undeletepage' => 'Sletta sider',
-'undeletepagetitle' => "'''Følgjande innhald er sletta versjonar av [[:$1]]'''.",
+'undeletepagetitle' => "'''Dette innhaldet er sletta versjonar av [[:$1]]'''.",
 'viewdeletedpage' => 'Sjå sletta sider',
 'undeletepagetext' => '{{PLURAL:$1|Den følgjande sida er sletta, men ho|Dei følgjande $1 sidene er sletta, men dei}} finst enno i arkivet og kan attopprettast. Arkivet blir periodevis sletta.',
 'undelete-fieldset-title' => 'Attenderull endringar',
@@ -2713,7 +2713,7 @@ Den gamle tittelen vil verta ei omdirigeringsside til den nye.
 Du kan oppdatera omdirigeringar som peikar til den opphavlege tittelen automatisk.
 Vel du å ikkje gjera dette, pass på å sjå etter [[Special:DoubleRedirects|doble]] eller [[Special:BrokenRedirects|øydelagde omdirigeringar]].
 
-Merk at sida '''ikkje''' vert flytt dersom det alt finst ei side med den nye tittelen, minder ho er ei omdirigering og ikkje har nokon endringshistorikk. Detter tyder at du kan omdøypa ei side attende til der ho vart omdøypt frå om du gjorde eit mistak, og du kan ikkje skriva over sider som finst.
+Merk at sida '''ikkje''' vert flytt dersom det alt finst ei side med den nye tittelen, minder målsida er ei omdirigering og ikkje har nokon endringshistorikk. Detter tyder at du kan omdøypa ei side attende til der ho vart omdøypt frå om du gjorde eit mistak, og du kan ikkje skriva over sider som finst.
 
 '''ÅTVARING!'''
 Dette kan vera ei drastisk og uventa endring for ei populær side; ver viss på at du skjøner konsekvensane av dette før du held fram.",
index ed778b7..2aed84b 100644 (file)
@@ -517,12 +517,12 @@ $1',
 
 'ok' => 'ଠିକ ଅଛି',
 'retrievedfrom' => '"$1" ରୁ ଅଣାଯାଇଅଛି',
-'youhavenewmessages' => 'ଆପଣଙ୍କର $1 ($2).',
-'newmessageslink' => 'ନà­\82à¬\86 à¬®à­\87ସà­\87à¬\9c',
+'youhavenewmessages' => 'ଆପଣଙ୍କ ପାଇଁ $1 ($2)।',
+'newmessageslink' => 'ନà­\82à¬\86 à¬¸à¬¨à­\8dଦà­\87ଶ',
 'newmessagesdifflink' => 'ଶେଷ ବଦଳ',
 'youhavenewmessagesfromusers' => 'ଆପଣଙ୍କର {{PLURAL:$3|another user|$3 users}} ($2)ରୁ $1 ଅଛି ।',
 'youhavenewmessagesmanyusers' => 'ଆପଣଙ୍କର ବହୁତ ବ୍ୟବହାରକାରୀ($2)ମାନଙ୍କଠାରୁ $1 ଅଛି ।',
-'newmessageslinkplural' => '{{PLURAL:$1|a new message|ନୂଆ ମେସେଜ}}',
+'newmessageslinkplural' => '{{PLURAL:$1|ଏକ ନୂଆ ସନ୍ଦେଶ|ନୂଆ ସନ୍ଦେଶ}}',
 'newmessagesdifflinkplural' => 'ଶେଷ{{PLURAL:$1|change|changes}}',
 'youhavenewmessagesmulti' => '$1 ତାରିଖରେ ନୂଆ ଚିଠିଟିଏ ଆସିଛି',
 'editsection' => 'ସମ୍ପାଦନା',
@@ -691,7 +691,7 @@ $2',
 'gotaccount' => 'ଆଗରୁ ଖାତାଟିଏ ଅଛି କି? $1.',
 'gotaccountlink' => 'ଲଗ ଇନ',
 'userlogin-resetlink' => 'ଲଗଇନ ତଥ୍ୟ ସବୁ ଭୁଲିଗେଲେକି?',
-'createaccountmail' => 'à¬\87-ମà­\87ଲ à¬°ୁ',
+'createaccountmail' => 'à¬\97à­\8bà¬\9fିà¬\8f à¬¸à¬¾à¬®à­\9fିà¬\95 à¬\9cାହିତାହି à¬ªà¬¾à¬¸à­±à¬¾à¬°à­\8dଡ à¬¬à­\8dà­\9fବହାର à¬\95ରନà­\8dତà­\81 à¬\8fବà¬\82 à¬\8fହାà¬\95à­\81 à¬¤à¬³à­\87 à¬¦à¬¿à¬\86ଯାà¬\87ଥିବା à¬\87-ମà­\87ଲ à¬ à¬¿à¬\95ଣାà¬\95à­\81 à¬ªà¬ à­\87à¬\87 à¬¦à¬¿à¬\85ନà­\8dତୁ',
 'createaccountreason' => 'କାରଣ:',
 'badretype' => 'ଆପଣ ଦେଇଥିବା ପାସବାର୍ଡ଼ଟି ମେଳଖାଉନାହିଁ ।',
 'userexists' => 'ଆପଣ ଦେଇଥିବା ଇଉଜର ନାମ ଆଗରୁ ଅଛି ।
@@ -1009,8 +1009,8 @@ $1 ଦ୍ଵାରା ପ୍ରତିରୋଧ କରାଯାଇଛି
 '''ଅନୁମତି ବିନା ସତ୍ଵାଧିକାର ଥିବା କାମ ଏଠାରେ ଦିଅନ୍ତୁ ନାହିଁ !'''",
 'longpageerror' => "'''ଭୁଲ: ଆପଣ ଦେଇଥିବା ଲେଖାଟି {{PLURAL:$1|କିଲୋବାଇଟ|$1 କିଲୋବାଇଟ}} ଲମ୍ବା, ଯାହାକି ସବୁଠାରୁ ଅଧିକ {{PLURAL:$2|କିଲୋବାଇଟ|$2 କିଲୋବାଇଟ}} ଠାରୁ ବି ଅଧିକ ।'''
 ଏହା ସାଇତାଯାଇପାରିବ ନାହିଁ ।",
-'readonlywarning' => "'''ସୂଚନା: ଏହି ଡାଟାବେସଟି ରକ୍ଷଣାବେକ୍ଷଣା ପାଇଁ କିଳାଯାଇଛି । ତେଣୁ ଆପଣ ଆପଣା ସମ୍ପାଦନା ଏବେ ସାଇତି ପାରିବେ ନାହିଁ ।'''
-à¬\86ପଣ à¬²à­\87à¬\96ାସବà­\81 à¬\8fà¬\95 à¬\9fà­\87à¬\95à­\8dସà¬\9f à¬«à¬¾à¬\87ଲରà­\87 à¬¨à¬\95ଲ à¬\95ରି ପେଷ୍ଟ କରି ଆଗକୁ ବ୍ୟବହାର କରିବା ପାଇଁ ସାଇତି ପାରିବେ ।
+'readonlywarning' => "ସୂଚନା: ଏହି ଡାଟାବେସଟି ରକ୍ଷଣାବେକ୍ଷଣା ପାଇଁ କିଳାଯାଇଛି । ତେଣୁ ଆପଣ ଆପଣା ସମ୍ପାଦନା ଏବେ ସାଇତି ପାରିବେ ନାହିଁ ।'''
+à¬\86ପଣ à¬²à­\87à¬\96ାସବà­\81 à¬\8fà¬\95 à¬\9fà­\87à¬\95à­\8dସà¬\9f à¬«à¬¾à¬\87ଲରà­\87 à¬¨à¬\95ଲ à¬\8fବà¬\82 ପେଷ୍ଟ କରି ଆଗକୁ ବ୍ୟବହାର କରିବା ପାଇଁ ସାଇତି ପାରିବେ ।
 
 ଏହାକୁ କିଳିଥିବା ପରିଛା ଏହି କଇଫତ ଦେଇଛନ୍ତି: $1",
 'protectedpagewarning' => "'''ଚେତାବନୀ: ଏହି ପୃଷ୍ଠାଟିକୁ କିଳାଯାଇଅଛି ଯାହା ଫଳରେ କେବଳ ପରିଛାମାନେ ହିଁ ଏହାକୁ ବଦଳାଇ ପାରିବେ ।'''
@@ -1317,7 +1317,7 @@ $1",
 'search-interwiki-default' => '$1 ଫଳାଫଳ:',
 'search-interwiki-more' => '(ଅଧିକ)',
 'search-relatedarticle' => 'ଯୋଡ଼ା',
-'mwsuggest-disable' => 'AJAX ମତାମତକୁ ଅଚଳ କରାଇବେ',
+'mwsuggest-disable' => 'ଖୋଜା ମତାମତକୁ ଅଚଳ କରାଇବେ',
 'searcheverything-enable' => 'ସବୁଗୁଡ଼ିକ ନେମସ୍ପେସରେ ଖୋଜିବେ',
 'searchrelated' => 'ଯୋଡ଼ା',
 'searchall' => 'ସବୁ',
@@ -2229,7 +2229,7 @@ URLଟି ଠିକ ଅଚିକି କି ନାଁ ଓ ସାଇଟଟି ସ
 # Special:ActiveUsers
 'activeusers' => 'ସଚଳ ସଭ୍ୟଙ୍କ ତାଲିକା',
 'activeusers-intro' => 'ବିଗତ $1 {{PLURAL:$1|ଦିନ|ଦିନ}} ଭିତରେ କିଛି ପ୍ରକାରର କାମ କରିଥିବା ସଭ୍ୟମାନଙ୍କର ତାଲିକା ।',
-'activeusers-count' => 'ବିଗତ {{PLURAL:$3|ଦିନ|$3 ଦିନରେ}}ରେ $1ଟି {{PLURAL:$1|ସମ୍ପାଦନା|ସମ୍ପାଦନା}}',
+'activeusers-count' => 'ବିଗତ {{PLURAL:$3|ଦିନ|$3 ଦିନରେ}}ରେ $1ଟି {{PLURAL:$1|ସମ୍ପାଦନା|ସମ୍ପାଦନାଗୁଡିକ}}',
 'activeusers-from' => 'ଏହି ନାମରେ ଆରମ୍ଭ ହେଉଥିବା ସଭ୍ୟମାନଙ୍କୁ ଦେଖାଇବେ:',
 'activeusers-hidebots' => 'ଆପେଆପେ ଚାଳିତ ସଭ୍ୟମାନଙ୍କୁ ଲୁଚାନ୍ତୁ',
 'activeusers-hidesysops' => 'ପରିଚାଳକମାନଙ୍କୁ ଲୁଚାଇବେ',
@@ -2292,7 +2292,7 @@ URLଟି ଠିକ ଅଚିକି କି ନାଁ ଓ ସାଇଟଟି ସ
 'usermessage-editor' => 'ସିଷ୍ଟମ ଦୂତ',
 
 # Watchlist
-'watchlist' => 'ଦେଖାତାଲିକା',
+'watchlist' => 'ଦà­\87à¬\96ଣାତାଲିà¬\95ା',
 'mywatchlist' => 'ଦେଖଣାତାଲିକା',
 'watchlistfor2' => '$1 $2 ପାଇଁ',
 'nowatchlist' => 'ଆପଣଙ୍କ ଦେଖଣା ତାଲିକାରେ କିଛି ବି ଜିନିଷ ନାହିଁ ।',
@@ -2457,9 +2457,9 @@ $2ଙ୍କ ଦେଇ ଶେଷଥର ହୋଇଥିବା ସଂସ୍କର
 'protect-cascadeon' => 'ଏହି ପୃଷ୍ଠାଟି ଏବେ ପାଇଁ କିଳାଯାଇଛି {{PLURAL:$1|ପୃଷ୍ଠା, ଯେଉଁଥିରେ|ପୃଷ୍ଠମାନ, ଯେଉଁସବୁରେ}} କାସକେଡ଼କରା ସୁରକ୍ଷା ସଚଳ ଥିଲା ।
 ଆପଣ ପୃଷ୍ଠାଟିର ପ୍ରତିରକ୍ଷା ସ୍ତର ବଦଳାଇ ପାରିବେ, କିନ୍ତୁ ଏହା କାସକେଡ଼ ପ୍ରତିରକ୍ଷାକୁ ପ୍ରଭାବିତ କରିନଥାଏ ।',
 'protect-default' => 'ସବୁ ଇଉଜରଙ୍କୁ ଅନୁମତି ଦିଅନ୍ତୁ',
-'protect-fallback' => '"$1" ବାଲା ଅନୁମତି ଦରକାର',
-'protect-level-autoconfirmed' => 'ନà­\81à¬\86 à¬\93 à¬¨à¬¾à¬\86à¬\81 à¬²à­\87à¬\96ାà¬\87 à¬¨ à¬¥à¬¿à¬¬à¬¾ à¬\87à¬\89à¬\9cରମାନà¬\95à­\81 à¬\85à¬\9fà¬\95ାà¬\81ତà­\81',
-'protect-level-sysop' => 'à¬\95à­\87ବଳ à¬ªà¬°à¬¿à¬\9bାମାନà¬\81à¬\95 à¬ªà¬¾à¬\87à¬\81',
+'protect-fallback' => 'କେବଳ "$1" ଅନୁମତି ଥିବା ବ୍ୟବହାରକାରୀ ମାନଙ୍କୁ ଛାଡିବେ',
+'protect-level-autoconfirmed' => 'à¬\95à­\87ବଳ à¬\86ପà­\87 à¬\86ପà­\87 à¬¸à¬¹à¬®à¬¤ à¬¹à­\8bà¬\87ଥିବା à¬¬à­\8dà­\9fବହାରà¬\95ାରà­\80 à¬®à¬¾à¬¨à¬\99à­\8dà¬\95à­\81 à¬\9bାଡିବà­\87',
+'protect-level-sysop' => 'à¬\95à­\87ବଳ à¬ªà¬°à¬¿à¬\9bାମାନà¬\99à­\8dà¬\95à­\81 à¬\9bାଡିବà­\87',
 'protect-summary-cascade' => 'କାସକେଡ଼ ହୋଇଥିବା',
 'protect-expiring' => '$1 (ଇଉଟିସି)ରେ ଅଚଳ ହୋଇଯିବ',
 'protect-expiring-local' => '$1ରେ ଅଚଳ ହୋଇଯିବ',
@@ -2768,7 +2768,7 @@ $1ର ଅଟକ ପାଇଁ ଦିଆଯାଇଥିବା କାରଣଟି 
 
 ଲିଙ୍କସବୁ କେଉଁଠିକୁ ଯାଉଛି ତାହା ପାଇଁ ଆପଣ ଦାୟୀ ନୁହନ୍ତି ।
 
-ମନà­\87 à¬°à¬\96ନà­\8dତà­\81, à¬\86à¬\97ରà­\81 à¬\8fହି à¬\8fà¬\95ା à¬¨à¬¾à¬\86à¬\81ରà­\87 à¬ªà­\83ଷà­\8dଠାà¬\9fିà¬\8f à¬¥à¬¿à¬²à­\87 à¬\8fହି à¬ªà­\83ଷà­\8dଠାà¬\9fି '''à¬\98à­\81à¬\9eà­\8dà¬\9aିବ à¬¨à¬¾à¬¹à¬¿à¬\81''' à¬¯à­\87ତà­\87 à¬¯à¬¾à¬\8fà¬\81 à¬¤à¬¾à¬¹à¬¾ à¬\96ାଲି à¬¨à¬¾à¬¹à¬¿à¬\81 à¬¬à¬¾ à¬\86à¬\97 à¬ªà­\83ଷà­\8dଠାà¬\9fିର à¬\95à­\8cଣସି à¬¬à¬¦à¬³ à¬\87ତିହାସ à¬¨à¬¾à¬¹à¬¿à¬\81 à¬¸à­\87ତà­\87 à¬¬à­\87ଳ à¬¯à¬¾à¬\8fà¬\81 à¬\8fହା à¬\8fମିତି à¬°à¬¹à¬¿à¬¬ à¥¤ à¬\8fହାର à¬®à¬¾à¬¨à­\87 à¬¹à­\87à¬\89à¬\9bି, à¬\86ପଣ à¬\97à­\8bà¬\9fିà¬\8f à¬ªà­\83ଷà­\8dଠାର à¬¨à¬¾à¬\86à¬\81à¬\95à­\81 à¬¤à¬¾à¬° à¬ªà­\81ରà­\81ଣା à¬¨à¬¾à¬\86à¬\81 à¬¦à­\87à¬\87ପାରିବà­\87, à¬\95ିନà­\8dତà­\81 à¬\86à¬\97ରà­\81 à¬¥à¬¿à¬¬à¬¾ à¬ªà­\83ଷà­\8dଠାà¬\9fି à¬\89ପରà­\87 à¬¨à­\82à¬\86 à¬ªà­\83ଷà­\8dଠାà¬\9fିà¬\8f à¬\9aାପି à¬¦à­\87à¬\87ପାରିବà­\87 à¬¨à¬¾à¬¹à¬¿à¬\81 à¥¤
+ମନେ ରଖନ୍ତୁ, ଆଗରୁ ଏହି ଏକା ନାଆଁରେ ପୃଷ୍ଠାଟିଏ ଥିଲେ ଏହି ପୃଷ୍ଠାଟି '''ଘୁଞ୍ଚିବ ନାହିଁ''' ଯେତେ ଯାଏଁ ଆଗ ପୃଷ୍ଠାଟିର କୌଣସି ବଦଳ ଇତିହାସ ନାହିଁ ସେତେ ବେଳ ଯାଏଁ ଏହା ଏମିତି ରହିବ । ଏହାର ମାନେ ହେଉଛି, ଆପଣ ଗୋଟିଏ ପୃଷ୍ଠାର ନାଆଁକୁ ତାର ପୁରୁଣା ନାଆଁ ଦେଇପାରିବେ, କିନ୍ତୁ ଆଗରୁ ଥିବା ପୃଷ୍ଠାଟି ଉପରେ ନୂଆ ପୃଷ୍ଠାଟିଏ ଚାପି ଦେଇପାରିବେ ନାହିଁ ।
 
 '''ଜାଣି ରଖନ୍ତୁ!'''
 ଏହା ଏକ ଜଣାଶୁଣା ପୃଷ୍ଠାରେ ଆମୂଳଚୂଳ ଓ ଅଜଣା ବଦଳ କରିପାରେ;
@@ -3090,6 +3090,7 @@ MediaWiki ବ୍ୟବହାର କରି [[Special:Import|ପୃଷ୍ଠା 
 'pageinfo-robot-noindex' => 'ସୂଚୀପତ୍ର କରିହେଉନଥିବା',
 'pageinfo-views' => 'ଦେଖଣା ସଂଖ୍ୟା',
 'pageinfo-watchers' => 'ପୃଷ୍ଠା ଦେଖଣାହାରି ସଂଖ୍ୟା',
+'pageinfo-few-watchers' => '$1ରୁ କମ {{PLURAL:$1|ଦେଖଣାକାରୀ|ଦେଖଣାକାରୀଗଣ}}',
 'pageinfo-redirects-name' => 'ଏହି ପୃଷ୍ଠାକୁ ଲେଉଟାଣି ଅଛି',
 'pageinfo-subpages-name' => 'ଏହି ପୃଷ୍ଠାରେ ଥିବା ଉପପୃଷ୍ଠା',
 'pageinfo-subpages-value' => '$1 ($2 {{PLURAL:$2|redirect|redirects}}; $3 {{PLURAL:$3|non-redirect|non-redirects}})',
@@ -3849,7 +3850,7 @@ MediaWiki ଉପଯୋଗୀ ହେବା ଲକ୍ଷରେ ବଣ୍ଟାଯ
 'specialpages-group-highuse' => 'ଅଧିକ ବ୍ୟବହାର ହେଉଥିବା ପୃଷ୍ଠା',
 'specialpages-group-pages' => 'ପୃଷ୍ଠାମାନଙ୍କର ତାଲିକା',
 'specialpages-group-pagetools' => 'ପୃଷ୍ଠା ଉପକରଣ',
-'specialpages-group-wiki' => 'à¬\89à¬\87à¬\95ି à¬¡à¬¾à¬\9fା ଓ ଉପକରଣ',
+'specialpages-group-wiki' => 'ତଥà­\8dà­\9f ଓ ଉପକରଣ',
 'specialpages-group-redirects' => 'ବିଶେଷ ପୃଷ୍ଠାକୁ ପୁନପ୍ରେରଣ କରିବା',
 'specialpages-group-spam' => 'ଅଯଥା ଉପକରଣ',
 
@@ -3947,6 +3948,7 @@ MediaWiki ଉପଯୋଗୀ ହେବା ଲକ୍ଷରେ ବଣ୍ଟାଯ
 'logentry-newusers-newusers' => 'ସଭ୍ୟ ଖାତା $1 ତିଆରି କରାଗଲା',
 'logentry-newusers-create' => 'ସଭ୍ୟ ଖାତା $1 ତିଆରି କରାଗଲା',
 'logentry-newusers-create2' => 'ସଭ୍ୟ ଖାତା $3ଟି $1 ଦ୍ଵାରା ତିଆରି କରାଗଲା',
+'logentry-newusers-byemail' => '$1ଙ୍କ ଦ୍ଵାରା $3 ବ୍ୟବହାରକାରୀ ଖାତାଟି ଖୋଳାଗଲା ଏବଂ ପାସୱାର୍ଡଟି ଇ-ମେଲ ଦ୍ଵାରା ପଠାଗଲା',
 'logentry-newusers-autocreate' => '$1 ଖାତାଟି ଆପେଆପେ ତିଆରିହେଲା',
 'logentry-rights-rights' => '$1, $3 ପାଇଁ $4ରୁ $5କୁ ସଭ୍ୟପଦ ବଦଳାଇଲେ',
 'logentry-rights-rights-legacy' => '$1, $3 ପାଇଁ ଗୋଷ୍ଠୀ ସଭ୍ୟପଦ ବଦଳାଇଛି',
@@ -4006,6 +4008,7 @@ MediaWiki ଉପଯୋଗୀ ହେବା ଲକ୍ଷରେ ବଣ୍ଟାଯ
 'api-error-ok-but-empty' => 'ଭିତର ଅସୁବିଧା: ସର୍ଭର ଠାରୁ କିଛି ଖବର ନାହିଁ ।',
 'api-error-overwrite' => 'ଆଗରୁଥିବା ଏକ ଫାଇଲ ଉପରେ ମଡ଼ାଇବା ଅନୁମୋଦିତ ନୁହେଁ ।',
 'api-error-stashfailed' => 'ଭିତର ଅସୁବିଧା: ସର୍ଭର ଅସ୍ଥାୟୀ ଫାଇଲକୁ ସାଇତି ପାରିଲା ନାହିଁ ।',
+'api-error-publishfailed' => 'ଭିତର ଅସୁବିଧା: ସର୍ଭର ଅସ୍ଥାୟୀ ଫାଇଲକୁ ପ୍ରକାଶ କରିପାରିଲା ନାହିଁ ।',
 'api-error-timeout' => 'ସର୍ଭର ଏକ ସୀମିତ କାଳ ଭିତରେ ଉତ୍ତର ଦେଲାନାହିଁ ।',
 'api-error-unclassified' => 'ଏକ ଅଜଣା ଅସୁବିଧା ଘଟିଲା ।',
 'api-error-unknown-code' => 'ଅଜଣା ତୃଟି: "$1"',
index 774c331..06a3205 100644 (file)
@@ -16,6 +16,7 @@
  * @author Guglani
  * @author Kaganer
  * @author Raj Singh
+ * @author Saurabh123
  * @author Sukh
  * @author Surinder.wadhawan
  * @author TariButtar
@@ -327,6 +328,7 @@ Manual:External_editors ਹੋਰ ਜਾਣਕਾਰੀ।])',
 'newwindow' => '(ਨਵੀਂ ਵਿੰਡੋ ਵਿੱਚ ਖੁੱਲ੍ਹਦੀ ਹੈ)',
 'cancel' => 'ਰੱਦ ਕਰੋ',
 'moredotdotdot' => 'ਹੋਰ...',
+'morenotlisted' => 'ਹੋਰ ਨਹੀ ਹੈਗੇ',
 'mypage' => 'ਪੰਨਾ',
 'mytalk' => 'ਚਰਚਾ',
 'anontalk' => 'ਇਸ IP ਲਈ ਗੱਲ-ਬਾਤ',
@@ -549,6 +551,11 @@ $1',
 ਇਸਨੇ ਕੋਈ ਕਾਰਨ ਨਹੀਂ ਦੱਸਿਆ।',
 'badtitle' => 'ਗਲਤ ਸਿਰਲੇਖ',
 'badtitletext' => 'ਤੁਹਾਡਾ ਦਰਖਾਸਤਸ਼ੁਦਾ ਸਿਰਲੇਖ ਨਾਕਾਬਿਲ, ਖਾਲੀ ਜਾਂ ਗਲਤ ਜੁੜਿਆ ਹੋਇਆ inter-languagd ਜਾਂ inter-wiki ਸਿਰਲੇਖ ਹੈ। ਇਹ ਵੀ ਹੋ ਸਕਦਾ ਹੈ ਕਿ ਇਸ ਵਿੱਚ ਇਕ-ਦੋ ਅੱਖਰ ਐਸੇ ਹੋਣ ਜੋ ਸਿਰਲੇਖ ਵਿੱਚ ਵਰਤੇ ਨਹੀਂ ਜਾ ਸਕਦੇ।',
+'querypage-no-updates' => 'ਇਸ ਪੇਜ  ਦਾ ਆਧੁਨੀਕਰਣ ਵਰਜਿਤ ਹੈ।
+ਆਂਕੜੇ ਹੱਲੇ ਤਾਜ਼ੇ ਨਹੀ ਹੋ ਸਕਦੇ ।',
+'wrong_wfQuery_params' => ' wfQuery()<br /> ਨੂ ਲਤ ਰਾਸ਼ੀ ਮਿਲੇ ਹੋਯੇ ਨੇ
+ ਫੁਨ੍ਕ੍ਤਿਓਂ:$1<br />
+ ਪ੍ਰਸ਼ਨ: $2',
 'viewsource' => 'ਸਰੋਤ ਵੇਖੋ',
 'viewsource-title' => '$1 ਲਈ ਸਰੋਤ ਵੇਖੋ',
 'actionthrottled' => 'ਕਾਰਜ ਬੰਦ ਕਰ ਦਿੱਤਾ ਗਿਆ ਹੈ',
@@ -560,6 +567,7 @@ $1',
 'protectedinterface' => 'ਇਹ ਪੰਨਾ ਸਾਫ਼ਟਵੇਅਰ ਇੰਟਰਫ਼ੇਸ ਦਾ ਮੂਲ ਪਾਠ ਹੈ ,ਅਤੇ ਦੁਰਵਰਤੌਂ ਤੌਂ ਬਚਾਅ ਲਈ ਰਾਖਵਾਂ ਕੀਤਾ ਗਿਆ ਹੈ।',
 'editinginterface' => "'''ਚਿਤਾਵਨੀ''' ਤੁਸੀਂ ਐਸੇ ਪੰਨੇ ਨੂੰ ਬਦਲ ਰਹੇ ਹੋ ਜੋ ਸਾਫ਼ਟਵੇਅਰ ਇੰਟਰਫ਼ੇਸ ਦੇ ਮੂਲ ਪਾਠ ਲਈ ਵਰਤਿਆ ਗਿਆ ਹੈ।
 ਇਸ ਪੰਨੇ ਦੇ ਬਦਲਾਅ ਦੁਸਰੇ ਵਰਤੋਂ ਕਰਣ ਵਾਲਿਆਂ ਲਈ ਵਰਤੇ ਜਾਣ ਵਾਲੇ ਇੰਟਰਫਲੇਸ ਦੀ ਸ਼ਕਲ ਤੇ ਅਸਰ ਪਾ ਦੇਣਗੇ।ਅਨੁਵਾਦ ਕਰਣ ਲਈ ,ਕਿਰਪਾ ਕਰਕੇ [//translatewiki.net/wiki/Main_Page?setlang=pa ਟ੍ਰਾਂਸਲੇਟਵਿਕੀ.ਨੈਟ] ਦੀ ਵਰਤੌਂ ਕਰੋ,ਇਹ ਮੀਡੀਆਵਿਕੀ ਦੀ ਸਥਾਨਕੀਕਰਣ ਯੋਜਨਾ ਹੈ।",
+'sqlhidden' => '(SQL ਪ੍ਰਸ਼ਨ ਚੁਪ੍ਪੇ ਹੁਏ ਨੇ)',
 'cascadeprotected' => 'ਇਹ ਪੰਨਾ ਸੁਰੱਖਿਅਤ ਹੈ, ਕਿਉਂਕਿ ਇਹ ਨਿੱਚੇ ਲਿਖੇ {{PLURAL:$1|ਪੰਨਾ|ਪੰਨੇ}} ਦੀ ਸੁਰੱਖਿਆ-ਸੀੜੀ ਵਿੱਚ ਸ਼ਾਮਲ ਹੈ:
 $2',
 'namespaceprotected' => "ਤੁਹਾਨੂੰ '''$1''' ਥਾਂ-ਨਾਮ ਵਾਲ਼ੇ ਸਫ਼ਿਆਂ ਵਿਚ ਫੇਰ-ਬਦਲ ਕਰਨ ਦੀ ਇਜਾਜ਼ਤ ਨਹੀਂ ਹੈ।",
@@ -1066,6 +1074,10 @@ $3|'''1''' ਨਤੀਜਾ|'''$3''' ਨਤੀਜੇ}} ਵਖਾਓ।",
 # Quickbar
 'qbsettings' => 'ਤੁਰੰਤ ਬਾਰ',
 'qbsettings-none' => 'ਕੋਈ ਨਹੀਂ',
+'qbsettings-fixedleft' => 'ਕਾਬ੍ਬ੍ਹੇ ਨੂ ਸਥਾਪਿਤ',
+'qbsettings-fixedright' => 'ਸੱਜੇ ਨੂ ਸਥਾਪਿਤ',
+'qbsettings-floatingleft' => 'ਕਾਬ੍ਬ੍ਹੇ ਨੂ ਰੁਲਦੀ',
+'qbsettings-floatingright' => 'ਸੱਜੇ ਨੂ ਰੁਲਦੀ',
 
 # Preferences page
 'preferences' => 'ਮੇਰੀ ਪਸੰਦ',
@@ -2214,4 +2226,15 @@ delete|ਹਟਾਉਣ ਦਾ ਚਿੱਠਾ]] ਵੇਖੋ।',
 # Search suggestions
 'searchsuggest-search' => 'ਖੋਜ',
 
+# Durations
+'duration-seconds' => '$1 {{PLURAL:$1|ਸੇਕੋੰਡ|ਵਧੇਰੇ ਸੇਕੋੰਡ}}',
+'duration-minutes' => '$1 {{PLURAL:$1|ਮਿਨੁਟ |ਵਧੇਰੇ ਮਿਨੁਟ }}',
+'duration-hours' => '$1 {{PLURAL:$1|ਘੰਟੇ |ਵਧੇਰੇ ਘੰਟੇ }}',
+'duration-days' => '$1 {{PLURAL:$1|ਦਿਨ |ਵਧੇਰੇ ਦਿਨ }}',
+'duration-weeks' => '$1 {{PLURAL:$1|ਹਫ਼ਤੇ |ਵਧੇਰੇ ਹਫ਼ਤੇ }}',
+'duration-years' => '$1 {{PLURAL:$1|ਸਾਲ |ਵਧੇਰੇ ਸਾਲ }}',
+'duration-decades' => '$1 {{PLURAL:$1|ਦਸ਼ਕ  |ਵਧੇਰੇ ਦਸ਼ਕ }}',
+'duration-centuries' => '$1 {{PLURAL:$1|ਸ਼ਤਾਬਦੀ |ਵਧੇਰੇ ਸ਼ਤਾਬਦੀ }}',
+'duration-millennia' => '$1 {{PLURAL:$1|ਸਾਹਸ਼ਤਾਬਦੀ  |ਵਧੇਰੇ ਸਾਹਸ਼ਤਾਬਦੀ  }}',
+
 );
index e22c428..8b58dcb 100644 (file)
@@ -774,7 +774,7 @@ Vir apré ([$2 pache]).",
 # Delete
 'deletepage' => "Défacer l'pache",
 'confirmdeletetext' => "Vos alez défacer eune pache ou un fichié aveuc toutes chés antieusses vérchons.<br /> Confreumer éq ch'est cho éq vos voulez foaire, éq vos conprindez chés consécanches et pi éq ch'est bin s'lon el [[{{MediaWiki:Policy-url}}|politique éd MédiaWiki]].",
-'actioncomplete' => 'Plònne acchon',
+'actioncomplete' => 'Accion toute piéte',
 'actionfailed' => "L’action n'a poin réussi",
 'deletedtext' => "« $1 » o té défacé.
 Vir $2 pou eune lisse d'chés darinnes défachons.",
index 9bed623..2cea497 100644 (file)
@@ -20,6 +20,7 @@
  * @author Holek
  * @author Jwitos
  * @author Kaganer
+ * @author Kaligula
  * @author Karol007
  * @author Lajsikonik
  * @author Lampak
@@ -1996,9 +1997,9 @@ Więcej informacji odnajdziesz na [$2 stronie opisu pliku].',
 'sharedupload-desc-here' => 'Ten plik znajduje się w $1 i może być używany w innych projektach.
 Poniżej znajdują się informacje ze [$2 strony opisu] tego pliku.',
 'sharedupload-desc-edit' => 'Plik ten pochodzi z $1 i może być wykorzystany w innych projektach.
-Być może zechcesz zmienić opis na tej [$2 stronie opisu pliku].',
+Jeżeli chcesz zmienić opis, zrób to na [$2 stronie opisu pliku].',
 'sharedupload-desc-create' => 'Plik ten pochodzi z $1 i może być wykorzystany w innych projektach.
-Być może zechcesz zmienić opis na tej [$2 stronie opisu pliku].',
+Jeżeli chcesz zmienić opis, zrób to na [$2 stronie opisu pliku].',
 'filepage-nofile' => 'Plik o tej nazwie nie istnieje.',
 'filepage-nofile-link' => 'Plik o tej nazwie nie istnieje, ale możesz go [$1 przesłać].',
 'uploadnewversion-linktext' => 'Załaduj nowszą wersję tego pliku',
@@ -2243,7 +2244,7 @@ Zobacz również [[Special:WantedCategories|brakujące kategorie]].',
 'linksearch-ok' => 'Szukaj',
 'linksearch-text' => 'Można użyć symboli wieloznacznych jak „*.wikipedia.org”.
 Wymaga podania co najmniej domeny najwyższego poziomu np. „*.org”.<br />
-Obsługiwane protokoły: <code>$1</code> (jeśli nie podano, domyślny to http://).',
+{{PLURAL:$2|Obsługiwany protokół|Obsługiwane protokoły}}: <code>$1</code> (jeśli nie podano, domyślny to http://).',
 'linksearch-line' => '$1 link na stronie $2',
 'linksearch-error' => 'Symbolu wieloznacznego można użyć wyłącznie na początku nazwy hosta.',
 
@@ -2338,7 +2339,7 @@ Każda zmiana treści tej strony lub związanej z nią strony dyskusji zostanie
 'notanarticle' => 'To nie jest artykuł',
 'notvisiblerev' => 'Wersja została usunięta',
 'watchnochange' => 'Żadna z obserwowanych stron nie była edytowana w podanym okresie.',
-'watchlist-details' => 'Na liście obserwowanych {{PLURAL:$1|jest 1 strona|są $1 strony|jest $1 stron}}, nie licząc stron dyskusji.',
+'watchlist-details' => 'Lista obserwowanych przez Ciebie stron zawiera {{PLURAL:$1|$1 pozycję|$1 pozycje|$1 pozycji}}, nie licząc stron dyskusji.',
 'wlheader-enotif' => '* Wysyłanie powiadomień na adres e‐mail jest włączone.',
 'wlheader-showupdated' => "* '''Wytłuszczone''' zostały strony, które zostały zmodyfikowane od Twojej ostatniej na nich wizyty.",
 'watchmethod-recent' => 'poszukiwanie ostatnich zmian wśród obserwowanych stron',
@@ -2362,7 +2363,7 @@ Każda zmiana treści tej strony lub związanej z nią strony dyskusji zostanie
 'enotif_subject_moved' => 'Strona projektu {{SITENAME}} o nazwie $1 została przeniesiona przez {{gender:$2|$2}}',
 'enotif_subject_restored' => 'Strona projektu {{SITENAME}} o nazwie $1 została przywrócona przez {{gender:$2|$2}}',
 'enotif_subject_changed' => 'Strona projektu {{SITENAME}} o nazwie $1 została zmieniona przez {{gender:$2|$2}}',
-'enotif_body_intro_deleted' => 'Strona projektu {{SITENAME}} o nazwie $1 została usunięta $PAGEEDITDATE przez {{gender:$2|$2}}, zobacz aktualną wersję na: $3',
+'enotif_body_intro_deleted' => 'Strona projektu {{SITENAME}} o nazwie $1 została usunięta $PAGEEDITDATE przez {{gender:$2|$2}}, zobacz: $3',
 'enotif_body_intro_created' => 'Strona projektu {{SITENAME}} o nazwie $1 została stworzona $PAGEEDITDATE przez {{gender:$2|$2}}, zobacz aktualną wersję na: $3',
 'enotif_body_intro_moved' => 'Strona projektu {{SITENAME}} o nazwie $1 została przeniesiona $PAGEEDITDATE przez {{gender:$2|$2}}, zobacz aktualną wersję na: $3',
 'enotif_body_intro_restored' => 'Strona projektu {{SITENAME}} o nazwie $1 została przywrócona $PAGEEDITDATE przez {{gender:$2|$2}}, zobacz aktualną wersję na: $3',
@@ -2457,8 +2458,8 @@ Naciśnij „wstecz” w przeglądarce, przeładuj stronę, po czym ponownie wyd
 'protectlogpage' => 'Zabezpieczone',
 'protectlogtext' => 'Poniżej znajduje się lista zmian w zabezpieczeniu pojedynczych stron.
 Wszystkie aktywne zabezpieczenia odnajdziesz na liście [[Special:ProtectedPages|zabezpieczonych stron]].',
-'protectedarticle' => 'zabezpieczył [[$1]]',
-'modifiedarticleprotection' => 'zmienił poziom zabezpieczenia [[$1]]',
+'protectedarticle' => '{{GENDER:$2|zabezpieczył|zabezpieczyła}} [[$1]]',
+'modifiedarticleprotection' => '{{GENDER:$2|zmienił|zmieniła}} poziom zabezpieczenia [[$1]]',
 'unprotectedarticle' => 'odbezpieczył [[$1]]',
 'movedarticleprotection' => 'przeniósł ustawienia zabezpieczeń z [[$2]] do [[$1]]',
 'protect-title' => 'Zmiana poziomu zabezpieczenia „$1”',
@@ -2466,6 +2467,7 @@ Wszystkie aktywne zabezpieczenia odnajdziesz na liście [[Special:ProtectedPages
 'prot_1movedto2' => 'stronę [[$1]] przeniósł do [[$2]]',
 'protect-badnamespace-title' => 'Przestrzeń nazw, w której nie można zabezpieczać stron',
 'protect-badnamespace-text' => 'Stron w tej przestrzeni nazw nie można zabezpieczać.',
+'protect-norestrictiontypes-text' => 'Ta strona nie może być chroniona, gdyż nie ma dla niej żadnych dostępnych typów ograniczeń.',
 'protect-norestrictiontypes-title' => 'Nieblokowalna strona',
 'protect-legend' => 'Potwierdź zabezpieczenie',
 'protectcomment' => 'Powód',
@@ -2717,12 +2719,12 @@ Przyczyna blokady $1 to: „$2”',
 'blocklogpage' => 'Historia blokad',
 'blocklog-showlog' => '{{GENDER:$1|Ten użytkownik był|Ta użytkowniczka była}} już wcześniej {{GENDER:$1|blokowany|blokowana}}. Poniżej znajduje się rejestr blokad:',
 'blocklog-showsuppresslog' => '{{GENDER:$1|Ten użytkownik był|Ta użytkowniczka była}} już wcześniej {{GENDER:$1|blokowany oraz ukrywany|blokowana oraz ukrywana}}. Poniżej znajduje się rejestr ukrywania:',
-'blocklogentry' => 'blokuje [[$1]], czas blokady: $2 $3',
-'reblock-logentry' => 'zmienia ustawienia blokady dla [[$1]], czas blokady: $2 $3',
+'blocklogentry' => 'zablokował(a) [[$1]], czas blokady: $2 $3',
+'reblock-logentry' => '{{GENDER:$2|zmienił|zmieniła}} ustawienia blokady dla [[$1]], czas blokady: $2 $3',
 'blocklogtext' => 'Poniżej znajduje się lista blokad założonych i zdjętych z poszczególnych adresów IP.
 Na liście nie znajdą się adresy IP, które zablokowano w sposób automatyczny.
 By przejrzeć listę obecnie aktywnych blokad, przejdź na stronę [[Special:BlockList|zablokowanych adresów i użytkowników]].',
-'unblocklogentry' => 'zdejmuje blokadę $1',
+'unblocklogentry' => '{{GENDER:$2|zdjął|zdjęła}} blokadę $1',
 'block-log-flags-anononly' => 'tylko anonimowi',
 'block-log-flags-nocreate' => 'blokada tworzenia konta',
 'block-log-flags-noautoblock' => 'automatyczne blokowanie wyłączone',
@@ -2785,7 +2787,7 @@ Blokowanie i odblokowywanie bazy danych, wymaga by plik mógł być zapisywany p
 Pod starym tytułem zostanie umieszczona strona przekierowująca.
 Możesz automatycznie zaktualizować przekierowania wskazujące na tytuł przed zmianą.
 Jeśli nie wybierzesz tej opcji, upewnij się po przeniesieniu strony, czy nie powstały [[Special:DoubleRedirects|podwójne]] lub [[Special:BrokenRedirects|zerwane przekierowania]].
-Jesteś odpowiedzialny za to, by linki w dalszym ciągu pokazywały tam, gdzie powinny.
+Jesteś odpowiedzialny za to, by linki w dalszym ciągu prowadziły tam, gdzie powinny.
 
 Strona '''nie''' zostanie przeniesiona, jeśli strona o nowej nazwie już istnieje, chyba że jest pusta lub jest przekierowaniem i ma pustą historię edycji.
 To oznacza, że błędną operację zmiany nazwy można bezpiecznie odwrócić, zmieniając nową nazwę strony na poprzednią, i że nie można nadpisać istniejącej strony.
@@ -2978,9 +2980,9 @@ Brak katalogu dla plików tymczasowych.',
 # Import log
 'importlogpage' => 'Rejestr importu',
 'importlogpagetext' => 'Rejestr przeprowadzonych importów stron z innych serwisów wiki.',
-'import-logentry-upload' => 'importuje [[$1]] przez przesłanie pliku',
+'import-logentry-upload' => '{{GENDER:$2|zaimportował|zaimportowała}} [[$1]] przez przesłanie pliku',
 'import-logentry-upload-detail' => '$1 {{PLURAL:$1|wersja|wersje|wersji}}',
-'import-logentry-interwiki' => 'importuje $1 używając transwiki',
+'import-logentry-interwiki' => '{{GENDER:$2|zaimportował|zaimportowała}} $1 używając transwiki',
 'import-logentry-interwiki-detail' => '$1 {{PLURAL:$1|wersja|wersje|wersji}} z $2',
 
 # JavaScriptTest
@@ -4038,7 +4040,7 @@ Grafiki są pokazywane w pełnej rozdzielczości. Inne typy plików są otwieran
 'logentry-delete-restore' => '$1 {{GENDER:$2|odtworzył|odtworzyła}} stronę $3',
 'logentry-delete-event' => '$1 {{GENDER:$2|zmienił|zmieniła}} widoczność {{PLURAL:$5|zdarzenia|$5 zdarzeń}} w rejestrze $3, wykonano następujące operacje: $4',
 'logentry-delete-revision' => '$1 {{GENDER:$2|zmienił|zmieniła}} widoczność {{PLURAL:$5|wersji|$5 wersji}} strony $3, wykonano następujące operacje: $4',
-'logentry-delete-event-legacy' => '$1 {{GENDER:$2|zmienił|zmieniła}} widoczność zdarzeń w rejestrze $3',
+'logentry-delete-event-legacy' => '$1 {{GENDER:$2|zmienił|zmieniła}} widoczność zdarzeń w rejestrze strony $3',
 'logentry-delete-revision-legacy' => '$1 {{GENDER:$2|zmienił|zmieniła}} widoczność wersji strony $3',
 'logentry-suppress-delete' => '$1 ukrywa stronę $3',
 'logentry-suppress-event' => '$1 potajemnie zmienia widoczność {{PLURAL:$5|zdarzenia|$5 zdarzeń}} w $3, wykonano następujące operacje: $4',
@@ -4057,8 +4059,8 @@ Grafiki są pokazywane w pełnej rozdzielczości. Inne typy plików są otwieran
 'logentry-move-move-noredirect' => '$1 {{GENDER:$2|przeniósł|przeniosła}} stronę $3 na $4, bez pozostawienia przekierowania pod starym tytułem',
 'logentry-move-move_redir' => '$1 {{GENDER:$2|przeniósł|przeniosła}} stronę $3 na $4 w miejsce przekierowania',
 'logentry-move-move_redir-noredirect' => '$1 {{GENDER:$2|przeniósł|przeniosła}} stronę $3 na $4 w miejsce przekierowania i bez pozostawienia przekierowania pod starym tytułem',
-'logentry-patrol-patrol' => '$1 {{GENDER:$2|odznaczył|odznaczyła}} wersję $4 strony $3 jako sprawdzoną',
-'logentry-patrol-patrol-auto' => '$1 automatycznie {{GENDER:$2|odznaczył|odznaczyła}} wersję $4 strony $3 jako sprawdzoną',
+'logentry-patrol-patrol' => '$1 {{GENDER:$2|oznaczył|oznaczyła}} wersję $4 strony $3 jako sprawdzoną',
+'logentry-patrol-patrol-auto' => '$1 automatycznie {{GENDER:$2|oznaczył|oznaczyła}} wersję $4 strony $3 jako sprawdzoną',
 'logentry-newusers-newusers' => 'Konto użytkownika $1 zostało utworzone',
 'logentry-newusers-create' => 'Konto użytkownika $1 zostało utworzone',
 'logentry-newusers-create2' => 'Konto użytkownika $3 zostało utworzone przez użytkownika $1',
@@ -4121,6 +4123,7 @@ W przeciwnym wypadku można użyć prostego formularza poniżej. Komentarz zosta
 'api-error-ok-but-empty' => 'Błąd wewnętrzny – brak odpowiedzi od serwera.',
 'api-error-overwrite' => 'Nadpisanie istniejącego pliku nie jest dopuszczalne.',
 'api-error-stashfailed' => 'Błąd wewnętrzny – serwer nie mógł zapisać pliku tymczasowego.',
+'api-error-publishfailed' => 'Błąd wewnętrzny: serwer nie mógł zapisać pliku tymczasowego.',
 'api-error-timeout' => 'Serwer nie odpowiedział w oczekiwanym czasie.',
 'api-error-unclassified' => 'Wystąpił nieznany błąd',
 'api-error-unknown-code' => 'Błąd nieznany – „$1”',
index 84407ef..b99fecd 100644 (file)
@@ -1973,7 +1973,7 @@ Ch'a bèica ëdcò [[Special:WantedCategories|le categorìe domandà]].",
 'linksearch-ok' => 'Sërché',
 'linksearch-text' => 'As peulo dovresse dij ciapatut com "*.wikipedia.org".
 A-i é dabzògn almanch d\'un domini a livel pi àut, për esempi "*.org".<br />
-{{PLURAL:$2|Protocòl|Protocòj}} ch\'as peulo dovresse: <code>$1</code> (predefinì http:// se gnun protocòj a son specificà).',
+{{PLURAL:$2|Protocòl|Protocòj}} ch\'as peulo dovresse: <code>$1</code> (predefinì http:// se gnun protocòl a l\'é specificà).',
 'linksearch-line' => "$1 a l'ha n'anliura ch'a-j riva dzora da $2",
 'linksearch-error' => 'Ij ciapatut as peulo butesse mach an prinsipi dël nòm dël sërvent.',
 
@@ -2050,7 +2050,7 @@ L'adrëssa ëd pòsta eletrònica ch'a l'ha butà ant ij [[Special:Preferences|s
 'usermessage-editor' => 'Mëssagerìa ëd sistema',
 
 # Watchlist
-'watchlist' => 'Ròba che im ten-o sot-euj',
+'watchlist' => 'Ròba che as ten sot euj',
 'mywatchlist' => 'Ròba che as ten sot euj',
 'watchlistfor2' => 'Për $1 $2',
 'nowatchlist' => "A l'ha ancó pa marcà dj'artìcoj coma ròba da tnì sot-euj.",
index 461303a..3b701cd 100644 (file)
@@ -308,7 +308,7 @@ $messages = array(
 'vector-action-addsection' => 'سرليکونه ورګډول',
 'vector-action-delete' => 'ړنګول',
 'vector-action-move' => 'لېږدول',
-'vector-action-protect' => 'پروژه',
+'vector-action-protect' => 'ژغورل',
 'vector-action-undelete' => 'ناړنګول',
 'vector-action-unprotect' => 'ژغورنه بدلول',
 'vector-view-create' => 'جوړول',
@@ -553,7 +553,7 @@ $1',
 'gotaccount' => 'آيا وار دمخې يو ګڼون لری؟ $1.',
 'gotaccountlink' => 'ننوتل',
 'userlogin-resetlink' => 'د ننوتلو مالومات مو هېر شوي؟',
-'createaccountmail' => 'د برېښليک له مخې',
+'createaccountmail' => 'يو لنډمهاله ناټاکلی پټنوم کارول او په لاندې ورکړل شوې برېښليک پته کې ورلېږل',
 'createaccountreason' => 'سبب:',
 'badretype' => 'دا پټنوم چې تاسې ليکلی د مخکني پټنوم سره ورته نه دی.',
 'userexists' => 'کوم کارن نوم چې تاسې ورکړی هغه بل چا کارولی.
index ddcb9e9..9cb8d8f 100644 (file)
@@ -12,6 +12,7 @@
  * @author Capmo
  * @author Crazymadlover
  * @author Daemorris
+ * @author Dicionarista
  * @author Francisco Leandro
  * @author Giro720
  * @author GoEThe
@@ -369,12 +370,12 @@ $messages = array(
 'editfont-serif' => 'Fonte serifada',
 
 # Dates
-'sunday' => 'Domingo',
-'monday' => 'Segunda-feira',
-'tuesday' => 'Terça-feira',
-'wednesday' => 'Quarta-feira',
-'thursday' => 'Quinta-feira',
-'friday' => 'Sexta-feira',
+'sunday' => 'domingo',
+'monday' => 'segunda-feira',
+'tuesday' => 'terça-feira',
+'wednesday' => 'quarta-feira',
+'thursday' => 'quinta-feira',
+'friday' => 'sexta-feira',
 'saturday' => 'Sábado',
 'sun' => 'Dom',
 'mon' => 'Seg',
@@ -383,18 +384,18 @@ $messages = array(
 'thu' => 'Qui',
 'fri' => 'Sex',
 'sat' => 'Sáb',
-'january' => 'Janeiro',
-'february' => 'Fevereiro',
-'march' => 'Março',
-'april' => 'Abril',
+'january' => 'janeiro',
+'february' => 'fevereiro',
+'march' => 'março',
+'april' => 'abril',
 'may_long' => 'Maio',
-'june' => 'Junho',
-'july' => 'Julho',
-'august' => 'Agosto',
-'september' => 'Setembro',
-'october' => 'Outubro',
-'november' => 'Novembro',
-'december' => 'Dezembro',
+'june' => 'junho',
+'july' => 'julho',
+'august' => 'agosto',
+'september' => 'setembro',
+'october' => 'outubro',
+'november' => 'novembro',
+'december' => 'dezembro',
 'january-gen' => 'Janeiro',
 'february-gen' => 'Fevereiro',
 'march-gen' => 'Março',
@@ -411,7 +412,7 @@ $messages = array(
 'feb' => 'Fev.',
 'mar' => 'Mar.',
 'apr' => 'Abr.',
-'may' => 'Maio',
+'may' => 'maio',
 'jun' => 'Jun.',
 'jul' => 'Jul.',
 'aug' => 'Ago.',
@@ -527,7 +528,7 @@ $messages = array(
 'otherlanguages' => 'Noutras línguas',
 'redirectedfrom' => '(Redireccionado de $1)',
 'redirectpagesub' => 'Página de redireccionamento',
-'lastmodifiedat' => 'Esta página foi modificada pela última vez às $2 de $1.',
+'lastmodifiedat' => 'Esta página foi modificada pela última vez à(s) $2 de $1.',
 'viewcount' => 'Esta página foi acedida {{PLURAL:$1|uma vez|$1 vezes}}.',
 'protectedpage' => 'Página protegida',
 'jumpto' => 'Ir para:',
@@ -1360,7 +1361,7 @@ Os detalhes podem ser encontrados no [{{fullurl:{{#Special:Log}}/delete|page={{F
 'search-interwiki-default' => 'Resultados de $1:',
 'search-interwiki-more' => '(mais)',
 'search-relatedarticle' => 'Relacionado',
-'mwsuggest-disable' => 'Desactivar sugestões AJAX',
+'mwsuggest-disable' => 'Desactivar sugestões de pesquisa',
 'searcheverything-enable' => 'Pesquisar em todos os espaços nominais',
 'searchrelated' => 'relacionados',
 'searchall' => 'todos',
@@ -1708,7 +1709,7 @@ Esta informação será pública.',
 'recentchangeslinked-feed' => 'Alterações relacionadas',
 'recentchangeslinked-toolbox' => 'Alterações relacionadas',
 'recentchangeslinked-title' => 'Alterações relacionadas com "$1"',
-'recentchangeslinked-noresult' => 'Não ocorreram alterações em páginas para as quais a página fornecida contém links, no intervalo de tempo escolhido.',
+'recentchangeslinked-noresult' => 'Nenhuma mudança nas páginas relacionadas durante o período.',
 'recentchangeslinked-summary' => "Lista das mudanças recentes a todas as páginas para as quais a página fornecida contém links (ou de todas as que pertencem à categoria fornecida).
 As suas [[Special:Watchlist|páginas vigiadas]] aparecem a '''negrito'''.",
 'recentchangeslinked-page' => 'Nome da página:',
@@ -2202,8 +2203,8 @@ No entanto, outros sites na internet podem ter links para um ficheiro através d
 'querypage-disabled' => 'Esta página especial está desactivada para não prejudicar o desempenho.',
 
 # Book sources
-'booksources' => 'Fontes de livros',
-'booksources-search-legend' => 'Procurar fontes de livros',
+'booksources' => 'Fontes bibliográficas',
+'booksources-search-legend' => 'Pesquisar referências bibliográficas',
 'booksources-go' => 'Prosseguir',
 'booksources-text' => 'É apresentada abaixo uma lista de links para outros sites na internet que vendem livros novos e usados e talvez possuam informações adicionais sobre os livros que procura:',
 'booksources-invalid-isbn' => 'O número ISBN fornecido não parece ser válido; verifique a existência de erros ao copiar da fonte original.',
@@ -2231,7 +2232,7 @@ Pode reduzir a lista escolhendo um tipo de registo, um nome de utilizador ou um
 'allnotinnamespace' => 'Todas as páginas (excepto as do espaço nominal $1)',
 'allpagesprev' => 'Anterior',
 'allpagesnext' => 'Próximo',
-'allpagessubmit' => 'Prosseguir',
+'allpagessubmit' => 'Ver',
 'allpagesprefix' => 'Apresentar páginas iniciadas por:',
 'allpagesbadtitle' => 'O título de página fornecido era inválido ou tinha um prefixo interlínguas ou interwikis.
 Talvez contenha um ou mais caracteres que não podem ser usados nos títulos.',
@@ -2262,9 +2263,9 @@ Veja também as [[Special:WantedCategories|categorias desejadas]].',
 'linksearch-pat' => 'Padrão de busca:',
 'linksearch-ns' => 'Espaço nominal:',
 'linksearch-ok' => 'Prosseguir',
-'linksearch-text' => 'É possível usar caracteres de substituição \'\'(wildcards)\'\', como por exemplo: "*.wikipedia.org".
+'linksearch-text' => 'É possível usar caracteres de substituição \'\'(wildcards)\'\', tais como "*.wikipedia.org".
 É necessário, pelo menos, um domínio de topo, por exemplo "*.org".<br />
-Protocolos suportados: <code>$1</code> (não adicione nenhum destes na sua pesquisa).',
+{{PLURAL:$2|Protocolo suportado|Protocolos suportados}}: <code>$1</code> (será utilizado http:// se não for especificado um protocolo).',
 'linksearch-line' => 'Link para $1 na página $2',
 'linksearch-error' => "Caracteres de substituição ''(wildcards)'' só podem ser usados no início do endereço.",
 
@@ -2277,7 +2278,7 @@ Protocolos suportados: <code>$1</code> (não adicione nenhum destes na sua pesqu
 # Special:ActiveUsers
 'activeusers' => 'Utilizadores activos',
 'activeusers-intro' => 'Esta é uma lista dos utilizadores com qualquer tipo de actividade {{PLURAL:$1|no último dia|nos últimos $1 dias}}.',
-'activeusers-count' => '$1 {{PLURAL:$1|edição recente|edições recentes}} {{PLURAL:$3|no último dia|nos últimos $3 dias}}',
+'activeusers-count' => '$1 {{PLURAL:$1|ação|ações}} {{PLURAL:$3|no último dia|nos últimos $3 dias}}',
 'activeusers-from' => 'Mostrar utilizadores começando por:',
 'activeusers-hidebots' => 'Esconder robôs',
 'activeusers-hidesysops' => 'Esconder administradores',
@@ -2497,7 +2498,7 @@ Esta é a configuração actual da página '''$1''':",
 'protect-cascadeon' => 'Esta página está protegida porque se encontra incluída {{PLURAL:$1|na página listada a seguir, protegida|nas páginas listadas a seguir, protegidas}} com protecção em cascata.
 Pode alterar o nível de protecção desta página, mas isso não afectará a protecção em cascata.',
 'protect-default' => 'Permitir todos os utilizadores',
-'protect-fallback' => 'É necessário o privilégio de "$1"',
+'protect-fallback' => 'Permitir apenas utilizadores com o privilégio de "$1"',
 'protect-level-autoconfirmed' => 'Bloquear utilizadores novos e não registados',
 'protect-level-sysop' => 'Apenas administradores',
 'protect-summary-cascade' => 'em cascata',
@@ -2627,7 +2628,7 @@ Para referência é apresentado abaixo o último registo de bloqueio:',
 'whatlinkshere-title' => 'Páginas que têm links para "$1"',
 'whatlinkshere-page' => 'Página:',
 'linkshere' => "As seguintes páginas têm links para '''[[:$1]]''':",
-'nolinkshere' => "Não existem links para '''[[:$1]]'''.",
+'nolinkshere' => "Não existem afluentes para '''[[:$1]]''' com as condições especificadas.",
 'nolinkshere-ns' => "Não existem links para '''[[:$1]]''' no espaço nominal seleccionado.",
 'isredirect' => 'página de redireccionamento',
 'istemplate' => 'inclusão',
@@ -3105,7 +3106,7 @@ Permite colocar uma justificação no resumo da edição.',
 'anonymous' => '{{PLURAL:$1|Utilizador anónimo|Utilizadores anónimos}} da {{SITENAME}}',
 'siteuser' => '$1 da {{SITENAME}}',
 'anonuser' => 'utilizador anónimo $1 da {{SITENAME}}',
-'lastmodifiedatby' => 'Esta página foi modificada pela última vez às $2 de $1 por $3.',
+'lastmodifiedatby' => 'Esta página foi modificada pela última vez à(s) $2 de $1 por $3.',
 'othercontribs' => 'Baseado no trabalho de $1.',
 'others' => 'outros',
 'siteusers' => '{{PLURAL:$2|um utilizador|$2 utilizadores}} da {{SITENAME}} ($1)',
@@ -3139,7 +3140,7 @@ Este bloqueio foi provavelmente causado por um link para um site externo que con
 'pageinfo-robot-noindex' => 'Não indexável',
 'pageinfo-views' => 'Número de visitas',
 'pageinfo-watchers' => 'Número de vigilantes da página',
-'pageinfo-redirects-name' => 'Redireciona para esta página',
+'pageinfo-redirects-name' => 'Redirecionamentos para esta página',
 'pageinfo-subpages-name' => 'Subpáginas desta página',
 'pageinfo-subpages-value' => '$1 ($2 {{PLURAL:$2|redirecionamento|redirecionamentos}}; $3 {{PLURAL:$3|não-redirecionamento|não-redirecionamentos}})',
 'pageinfo-firstuser' => 'Criador da página',
@@ -3158,6 +3159,10 @@ Este bloqueio foi provavelmente causado por um link para um site externo que con
 'pageinfo-contentpage' => 'Contada como página de conteúdo',
 'pageinfo-contentpage-yes' => 'Sim',
 'pageinfo-protect-cascading-yes' => 'Sim',
+'pageinfo-category-info' => 'Informações da categoria',
+'pageinfo-category-pages' => 'Número de páginas',
+'pageinfo-category-subcats' => 'Número de subcategorias',
+'pageinfo-category-files' => 'Número de ficheiros',
 
 # Skin names
 'skinname-standard' => 'Clássico',
@@ -4005,6 +4010,7 @@ Imagens serão apresentadas pelo browser na resolução máxima; ficheiros de ou
 'logentry-newusers-create2' => 'A conta de utilizador $3 foi criada por $1',
 'logentry-newusers-autocreate' => 'A conta $1 foi criada automaticamente',
 'logentry-rights-rights' => '$1 modificou os privilégios do utilizador  $3  de  $4  para $5',
+'logentry-rights-autopromote' => '$1 foi automaticamente {{GENDER:$2|promovido|promovida}} de $4 a $5',
 'rightsnone' => '(nenhum)',
 
 # Feedback
index fec9a45..45ba9b3 100644 (file)
@@ -19,6 +19,7 @@
  * @author Crazymadlover
  * @author Daemorris
  * @author Danielsouzat
+ * @author Dicionarista
  * @author Diego Queiroz
  * @author Eduardo.mps
  * @author Emufarmers
@@ -532,7 +533,7 @@ $messages = array(
 'otherlanguages' => 'Em outros idiomas',
 'redirectedfrom' => '(Redirecionado de $1)',
 'redirectpagesub' => 'Página de redirecionamento',
-'lastmodifiedat' => 'Esta página foi modificada pela última vez às $2 de $1.',
+'lastmodifiedat' => 'Esta página foi modificada pela última vez à(s) $2 de $1.',
 'viewcount' => 'Esta página foi acessada {{PLURAL:$1|uma vez|$1 vezes}}.',
 'protectedpage' => 'Página protegida',
 'jumpto' => 'Ir para:',
@@ -1358,7 +1359,7 @@ Os detalhes podem ser encontrados no [{{fullurl:{{#Special:Log}}/delete|page={{F
 'search-interwiki-default' => 'Resultados de $1:',
 'search-interwiki-more' => '(mais)',
 'search-relatedarticle' => 'Relacionado',
-'mwsuggest-disable' => 'Desativar sugestões AJAX',
+'mwsuggest-disable' => 'Desativar sugestões de pesquisa',
 'searcheverything-enable' => 'Procurar em todos os espaços nominais',
 'searchrelated' => 'relacionados',
 'searchall' => 'todos',
@@ -1429,7 +1430,7 @@ Note que os índices do sistema de busca externo poderão conter referências de
 'resultsperpage' => 'Resultados por página:',
 'stub-threshold' => 'Links para páginas de conteúdo aparecerão <a href="#" class="stub">desta forma</a> se elas possuírem menos de (bytes):',
 'stub-threshold-disabled' => 'Desabilitado',
-'recentchangesdays' => 'Dias a serem exibidos nas Mudanças recentes:',
+'recentchangesdays' => 'Dias a apresentar nas mudanças recentes:',
 'recentchangesdays-max' => '(máximo: $1 {{PLURAL:$1|dia|dias}})',
 'recentchangescount' => 'Número de edições a serem exibidas por padrão:',
 'prefs-help-recentchangescount' => 'Isto inclui mudanças recentes, histórico de páginas e registros.',
@@ -1672,7 +1673,7 @@ Caso decida fornecê-lo, este será utilizado para dar-lhe crédito pelo seu tra
 'recentchanges-feed-description' => 'Acompanhe neste feed as mudanças mais recentes do wiki.',
 'recentchanges-label-newpage' => 'Esta edição criou uma nova página',
 'recentchanges-label-minor' => 'Esta é uma edição menor',
-'recentchanges-label-bot' => 'Esta edição foi feita por um bot',
+'recentchanges-label-bot' => 'Esta edição foi feita por um robô',
 'recentchanges-label-unpatrolled' => 'Esta edição ainda não foi patrulhada',
 'rcnote' => "A seguir {{PLURAL:$1|está listada '''uma''' alteração ocorrida|estão listadas '''$1''' alterações ocorridas}} {{PLURAL:$2|no último dia|nos últimos '''$2''' dias}}, a partir das $5 de $4.",
 'rcnotefrom' => "Seguem as alterações desde as '''$4''' de '''$3''' (limitadas a '''$1''').",
@@ -1705,7 +1706,7 @@ Caso decida fornecê-lo, este será utilizado para dar-lhe crédito pelo seu tra
 'recentchangeslinked-feed' => 'Alterações relacionadas',
 'recentchangeslinked-toolbox' => 'Alterações relacionadas',
 'recentchangeslinked-title' => 'Alterações relacionadas com "$1"',
-'recentchangeslinked-noresult' => 'Não ocorreram alterações em páginas relacionadas no intervalo de tempo especificado.',
+'recentchangeslinked-noresult' => 'Nenhuma mudança nas páginas relacionadas durante o período.',
 'recentchangeslinked-summary' => "Esta página lista alterações feitas recentemente em páginas com links a uma em específico (ou de membros de uma categoria especificada).
 Páginas de sua [[Special:Watchlist|lista de páginas vigiadas]] são exibidas em '''negrito'''.",
 'recentchangeslinked-page' => 'Nome da página:',
@@ -2205,7 +2206,7 @@ Por favor note que outros websites podem apontar para um arquivo através de um
 
 # Book sources
 'booksources' => 'Fontes bibliográficas',
-'booksources-search-legend' => 'Procurar fontes bibliográficas',
+'booksources-search-legend' => 'Pesquisar referências bibliográficas',
 'booksources-go' => 'Ir',
 'booksources-text' => 'É exibida a seguir uma listagem de links para outros sites que vendem livros novos e usados e que possam possuir informações adicionais sobre os livros que você está pesquisando:',
 'booksources-invalid-isbn' => 'O número ISBN fornecido não parece ser válido; verifique se houve erros ao copiar da fonte original.',
@@ -2233,7 +2234,7 @@ Você pode diminuir a lista escolhendo um tipo de registro, um nome de usuário
 'allnotinnamespace' => 'Todas as páginas (excepto as do espaço nominal $1)',
 'allpagesprev' => 'Anterior',
 'allpagesnext' => 'Próximo',
-'allpagessubmit' => 'Ir',
+'allpagessubmit' => 'Ver',
 'allpagesprefix' => 'Exibir páginas com o prefixo:',
 'allpagesbadtitle' => 'O título de página fornecido encontrava-se inválido ou tinha um prefixo interlíngua ou inter-wiki. Ele poderá conter um ou mais caracteres que não podem ser utilizados em títulos.',
 'allpages-bad-ns' => '{{SITENAME}} não possui o espaço nominal "$1".',
@@ -2440,7 +2441,7 @@ Por favor, confirme que possui a intenção de fazer isto, que compreende as con
 Consulte $2 para um registro de eliminações recentes.',
 'dellogpage' => 'Registro de eliminação',
 'dellogpagetext' => 'Abaixo uma lista das eliminações mais recentes.',
-'deletionlog' => 'registro de eliminação',
+'deletionlog' => 'registro de eliminações',
 'reverted' => 'Revertido para versão anterior',
 'deletecomment' => 'Motivo:',
 'deleteotherreason' => 'Justificativa adicional:',
@@ -2618,7 +2619,7 @@ $1',
 'sp-contributions-newbies' => 'Mostrar apenas as contribuições das novas contas',
 'sp-contributions-newbies-sub' => 'Para contas novas',
 'sp-contributions-newbies-title' => 'Contribuições de contas novas',
-'sp-contributions-blocklog' => 'Registro de bloqueios',
+'sp-contributions-blocklog' => 'registro de bloqueios',
 'sp-contributions-deleted' => 'contribuições eliminadas',
 'sp-contributions-uploads' => 'envios',
 'sp-contributions-logs' => 'registros',
@@ -2637,7 +2638,7 @@ Segue, para referência, a entrada mais recente no registro de bloqueios:',
 'whatlinkshere-title' => 'Páginas que têm links para "$1"',
 'whatlinkshere-page' => 'Página:',
 'linkshere' => "As seguintes páginas possuem links para '''[[:$1]]''':",
-'nolinkshere' => "Não há links para '''[[:$1]]'''.",
+'nolinkshere' => "Não há afluentes para '''[[:$1]]''' com as condições especificadas.",
 'nolinkshere-ns' => "Não há links para '''[[:$1]]''' no espaço nominal selecionado.",
 'isredirect' => 'página de redirecionamento',
 'istemplate' => 'transclusão',
@@ -2723,7 +2724,7 @@ Consulte a [[Special:BlockList|lista de bloqueios]].',
 'expiringblock' => 'expira em $1 às $2',
 'anononlyblock' => 'anôn. apenas',
 'noautoblockblock' => 'bloqueio automático desabilitado',
-'createaccountblock' => 'criação de conta de usuário bloqueada',
+'createaccountblock' => 'criação de conta bloqueada',
 'emailblock' => 'impedido de enviar e-mail',
 'blocklist-nousertalk' => 'impossibilitado de editar a própria página de discussão',
 'ipblocklist-empty' => 'A lista de bloqueios encontra-se vazia.',
@@ -3102,7 +3103,7 @@ Permite colocar uma justificativa no sumário da edição.',
 'anonymous' => '{{PLURAL:$1|Usuário anônimo|Usuários anônimos}} da {{SITENAME}}',
 'siteuser' => '{{GENDER:$2|um utilizador|uma utilizadora|um utilizador}} da {{SITENAME}} ($1)',
 'anonuser' => 'usuário anônimo $1 da {{SITENAME}}',
-'lastmodifiedatby' => 'Esta página foi modificada pela última vez às $2 de $1 por $3.',
+'lastmodifiedatby' => 'Esta página foi modificada pela última vez à(s) $2 de $1 por $3.',
 'othercontribs' => 'Baseado no trabalho de $1.',
 'others' => 'outros',
 'siteusers' => '{{PLURAL:$2|um usuário|$2 usuários}} da {{SITENAME}} ($1)',
@@ -3137,9 +3138,9 @@ Tal bloqueio foi provavelmente causado por uma ligação para um ''website'' ext
 'pageinfo-robot-noindex' => 'Não indexável',
 'pageinfo-views' => 'Número de visitas',
 'pageinfo-watchers' => 'Número de vigilantes da página',
-'pageinfo-redirects-name' => 'Redireciona para esta página',
+'pageinfo-redirects-name' => 'Redirecionamentos para esta página',
 'pageinfo-subpages-name' => 'Subpáginas desta página',
-'pageinfo-subpages-value' => '$1 ($2 {{PLURAL:$2|redirecionamento|redirecionamentos}}; $3 {{PLURAL:$3|não-redirecionamento|não-redirecionamentos}})',
+'pageinfo-subpages-value' => '$1 ($2 {{PLURAL:$2|redirecionamento|redirecionamentos}}; $3 {{PLURAL:$3|não redirecionamento|não redirecionamentos}})',
 'pageinfo-firstuser' => 'Criador da página',
 'pageinfo-firsttime' => 'Data de criação da página',
 'pageinfo-lastuser' => 'Último editor',
@@ -3151,7 +3152,7 @@ Tal bloqueio foi provavelmente causado por uma ligação para um ''website'' ext
 'pageinfo-magic-words' => '{{PLURAL:$1|Palavra mágica|Palavras mágicas}} ($1)',
 'pageinfo-hidden-categories' => '{{PLURAL:$1|Categoria oculta|Categorias ocultas}} ($1)',
 'pageinfo-templates' => '{{PLURAL:$1|Predefinição transcluída|Predefinições transcluídas ($1)}}',
-'pageinfo-transclusions' => '{{PLURAL:$1|Página incluída |Páginas incluídas}} ($1)',
+'pageinfo-transclusions' => '{{PLURAL:$1|Página em que é transcluída|Páginas em que é transcluída ($1)}}',
 'pageinfo-toolboxlink' => 'Informações da página',
 'pageinfo-redirectsto' => 'Redireciona para',
 'pageinfo-redirectsto-info' => 'informações',
index bb0e151..64589be 100644 (file)
@@ -92,6 +92,7 @@
  * @author Octahedron80
  * @author Od1n
  * @author Onecountry
+ * @author Opraco
  * @author OsamaK
  * @author PhiLiP
  * @author Piangpha
@@ -3769,7 +3770,8 @@ See also:
 'statistics-header-pages' => 'Used in [[Special:Statistics]]',
 'statistics-header-edits' => 'Used in [[Special:Statistics]]',
 'statistics-header-views' => 'Used in [[Special:Statistics]]',
-'statistics-header-users' => 'Used in [[Special:Statistics]]',
+'statistics-header-users' => 'Used in [[Special:Statistics]].
+{{Identical|User statistics}}',
 'statistics-header-hooks' => 'Header of a section on [[Special:Statistics]] containing data provided by MediaWiki extensions',
 'statistics-articles' => "Used in [[Special:Statistics]].
 
@@ -6439,7 +6441,7 @@ Parameters:
 This message is the variable $3 in the message {{msg-mw|lastmodifiedatby}}. This message only appears if the user is anonymous. The variable $1 in this message is a link to the user's contributions.
 
 See also {{msg-mw|Anonusers}} and {{msg-mw|Siteuser}}.",
-'lastmodifiedatby' => "This message is shown when viewing the credits of a page (example: {{fullurl:Main Page|action=credits}}). Note that this action is disabled by default (currently enabled on translatewiki.net).
+'lastmodifiedatby' => "This message is shown when viewing the credits of a page (example: [{{fullurl:Main Page|action=credits}}]). Note that this action is disabled by default (currently enabled on translatewiki.net).
 * $1: date
 * $2: time
 * $3: if the user has entered his 'real name' in his preferences then this variable is his 'real name'. If the user has not entered his 'real name' in his preferences then this variable is the message [[Mediawiki:siteuser/{{SUBPAGENAME}}]], which includes his username.
@@ -6522,6 +6524,7 @@ See also:
 'pageinfo-robot-noindex' => 'An indication that the page is not indexable (that is, is not listed on the results page of a search engine).',
 'pageinfo-views' => 'The number of times the page has been viewed.',
 'pageinfo-watchers' => 'The number of users watching the page.',
+'pageinfo-few-watchers' => 'Message displayed when there are fewer than $wgUnwatchedPageThreshold watchers. $1 is the value of $wgUnwatchedPageThreshold.',
 'pageinfo-redirects-name' => "The number of redirects to the page.
 
 Used as link text, linked to '{{int:Whatlinkshere-title}}' page ([[Special:WhatLinksHere]]).",
index 183e193..fd1c171 100644 (file)
@@ -1341,7 +1341,7 @@ Detalii se pot găsi în [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE
 'search-interwiki-default' => '$1 rezultate:',
 'search-interwiki-more' => '(mai mult)',
 'search-relatedarticle' => 'Relaționat',
-'mwsuggest-disable' => 'Dezactivează sugestiile AJAX',
+'mwsuggest-disable' => 'Dezactivează sugestiile de căutare',
 'searcheverything-enable' => 'Caută în toate spațiile de nume',
 'searchrelated' => 'relaționat',
 'searchall' => 'toate',
@@ -3114,6 +3114,7 @@ Permite adăugarea unui motiv în descrierea modificărilor',
 'pageinfo-robot-noindex' => 'Neindexabilă',
 'pageinfo-views' => 'Număr de vizualizări',
 'pageinfo-watchers' => 'Număr de utilizatori care urmăresc pagina',
+'pageinfo-few-watchers' => 'Mai puțin de {{PLURAL:$1|un urmăritor|$1 urmăritori|$1 de urmăritori}}',
 'pageinfo-redirects-name' => 'Redirecționări către această pagină',
 'pageinfo-subpages-name' => 'Subpagini ale acestei pagini',
 'pageinfo-subpages-value' => '$1 ($2 {{PLURAL:$2|redirecționare|redirecționări|de redirecționări}}; $3 {{PLURAL:$3|non-redirecționare|non-redirecționări|de non-redirecționări}})',
index 6ec2d0b..80d4285 100644 (file)
@@ -2097,7 +2097,7 @@ L'indirizze e-mail ca tu è 'nzerite jndr'à le [[Special:Preferences|preferenze
 'usermessage-template' => 'MediaWiki:UserMessage',
 
 # Watchlist
-'watchlist' => 'Pàggene condrollete',
+'watchlist' => 'Pàggene condrollate',
 'mywatchlist' => 'Pàggene condrollate',
 'watchlistfor2' => 'Pe $1 $2',
 'nowatchlist' => "Non ge tine pàggene jndr'à liste de le pàggene condrollete.",
@@ -2580,7 +2580,7 @@ Tu puè aggiornà 'u ridirezionamende ca apponde a 'u titole origgenale automati
 Ce tu no ste scacchie, sta secure de condrollà [[Special:DoubleRedirects|doppie ridirezionaminde]] o [[Special:BrokenRedirects|ridirezionaminde scuasciate]].
 Tu si 'u responsabbile de quidde ca cumbine, assicurate ca 'u collegamende condinue a appondà addò avessa scè.
 
-Vide Bbuene ca 'a pàgene '''non''' g'avene spustate ce esiste n'otra pàgene cu 'u titole nuéve, a mene ca jè vacande o jè 'na pàgene de ridirezionamende senza storie.
+Vide Bbuene ca 'a pàgene '''non''' g'avène spustate ce esiste n'otra pàgene cu 'u titole nuéve, a mene ca jè vacande o jè 'na pàgene de ridirezionamende senza storie.
 Quieste significhe ca tu puè fà turnà 'u vecchie nome 'a pàgene ce jedde ha state renomenate e t'è rese conde ca è fatte 'na studecarije sovrascrevènne 'na pàgene esistende.
 
 '''ATTENZIONE!'''
@@ -2938,6 +2938,7 @@ Stu fatte ha state causate da 'nu collegamende a 'nu site esterne ca appartene a
 'pageinfo-robot-noindex' => 'None indicizzabbele',
 'pageinfo-views' => 'Numere de visite',
 'pageinfo-watchers' => "Numere de visitature d'a pàgene",
+'pageinfo-few-watchers' => 'Mene de $1 {{PLURAL:$1|visitatore|visitature}}',
 'pageinfo-redirects-name' => 'Redirezionaminde a sta pàgene',
 'pageinfo-redirects-value' => '$1',
 'pageinfo-subpages-name' => 'Sottopàggene de sta pàgene',
@@ -3911,7 +3912,7 @@ Le immaggine sonde fatte vedè jndr'à resoluziona megghie, otre tipe de file re
 'specialpages-group-highuse' => 'Pàggene ausete assaje proprie',
 'specialpages-group-pages' => 'Liste de le pàggene',
 'specialpages-group-pagetools' => 'Pàgene de le struminde',
-'specialpages-group-wiki' => 'Date e struminde de Uicchi',
+'specialpages-group-wiki' => 'Date e struminde',
 'specialpages-group-redirects' => 'Redirezionaminde de le pàggene speciele',
 'specialpages-group-spam' => "Struminde p'u spam",
 
@@ -4008,6 +4009,7 @@ Le immaggine sonde fatte vedè jndr'à resoluziona megghie, otre tipe de file re
 'logentry-newusers-newusers' => "'U cunde utende $1 ha state ccrejate",
 'logentry-newusers-create' => "'U cunde utende $1 ha state ccrejate",
 'logentry-newusers-create2' => "$1 {{GENDER:$2|ccrejate}} {{GENDER:$4|'nu cunde utende}} $3",
+'logentry-newusers-byemail' => "'U cunde utende $3 ha state ccrejate da $1 e 'a passuord ha state mannate pe e-mail",
 'logentry-newusers-autocreate' => "'U cunde utende $1 ha state ccrejate automaticamende",
 'logentry-rights-rights' => "$1 membre d'u gruppe cangiate pe $3 da $4 a $5",
 'logentry-rights-rights-legacy' => "$1 ave cangiate 'u membre d'u gruppe pe $3",
index 77e591b..48d8dbe 100644 (file)
@@ -20,6 +20,7 @@
  * @author Anonim.one
  * @author Askarmuk
  * @author Assele
+ * @author Biathlon
  * @author Bouron
  * @author Chilin
  * @author Claymore
@@ -838,7 +839,7 @@ $2',
 'gotaccount' => "Вы уже зарегистрированы? '''$1'''.",
 'gotaccountlink' => 'Представьтесь',
 'userlogin-resetlink' => 'Забыли данные для входа?',
-'createaccountmail' => 'Ð\92Ñ\8bÑ\81лаÑ\82Ñ\8c Ð¿Ð°Ñ\80олÑ\8c Ð¿Ð¾ Ñ\8dл. Ð¿Ð¾Ñ\87Ñ\82е',
+'createaccountmail' => 'Ð\98Ñ\81полÑ\8cзоваÑ\82Ñ\8c Ñ\81генеÑ\80иÑ\80ованнÑ\8bй Ñ\81лÑ\83Ñ\87айнÑ\8bм Ð¾Ð±Ñ\80азом Ð²Ñ\80еменнÑ\8bй Ð¿Ð°Ñ\80олÑ\8c Ð¸ Ð²Ñ\8bÑ\81лаÑ\82Ñ\8c Ð¼Ð½Ðµ ÐµÐ³Ð¾ Ð½Ð° Ñ\83казаннÑ\8bй Ð½Ð¸Ð¶Ðµ Ð°Ð´Ñ\80еÑ\81 Ñ\8dлекÑ\82Ñ\80онной Ð¿Ð¾Ñ\87Ñ\82Ñ\8b:',
 'createaccountreason' => 'Причина:',
 'badretype' => 'Введённые вами пароли не совпадают.',
 'userexists' => 'Введённое имя участника уже используется.
@@ -2359,7 +2360,7 @@ $1',
 # Special:ActiveUsers
 'activeusers' => 'Список активных участников',
 'activeusers-intro' => 'Это список участников, совершавших какие-либо действия за {{PLURAL:$1|последний $1 день|последние $1 дня|последние $1 дней}}.',
-'activeusers-count' => '$1 {{PLURAL:$1|правка|правки|правок}} за {{PLURAL:$3|последний $3 день|последние $3 дня|последние $3 дней}}',
+'activeusers-count' => '$1 {{PLURAL:$1|правка|правки|правок}} за {{PLURAL:$3|$3 последний день|последние $3 дня|последние $3 дней}}',
 'activeusers-from' => 'Показать участников, начиная с:',
 'activeusers-hidebots' => 'Скрыть ботов',
 'activeusers-hidesysops' => 'Скрыть администраторов',
@@ -4103,7 +4104,7 @@ MediaWiki распространяется в надежде, что она бу
 'specialpages-group-highuse' => 'Интенсивно используемые страницы',
 'specialpages-group-pages' => 'Списки страниц',
 'specialpages-group-pagetools' => 'Инструменты для страниц',
-'specialpages-group-wiki' => 'Ð\92ики-данные и инструменты',
+'specialpages-group-wiki' => 'Ð\94анные и инструменты',
 'specialpages-group-redirects' => 'Перенаправляющие служебные страницы',
 'specialpages-group-spam' => 'Инструменты против спама',
 
@@ -4200,6 +4201,7 @@ MediaWiki распространяется в надежде, что она бу
 'logentry-newusers-newusers' => 'Создана учётная запись $1',
 'logentry-newusers-create' => 'Создана учётная запись $1',
 'logentry-newusers-create2' => '$1 {{GENDER:$2|создал|создала}} учётную запись для $3',
+'logentry-newusers-byemail' => 'Учетная запись пользователя $3 была создана $1 и пароль был отправлен по электронной почте',
 'logentry-newusers-autocreate' => 'Автоматически создана учётная запись $1',
 'logentry-rights-rights' => '$1 {{GENDER:$1|изменил|изменила}} членство в группах для $3 с $4 на $5',
 'logentry-rights-rights-legacy' => '$1 {{GENDER:$1|изменил|изменила}} членство в группах для $3',
index bd21606..67b8110 100644 (file)
@@ -2293,7 +2293,32 @@ See https://www.mediawiki.org/wiki/Manual:Image_Authorization.',
 'enotif_lastvisited' => 'भवतः पूवसन्दर्शनस्य पश्चात् सवृत्तपरिवर्तनार्थं $1 पश्यतु ।',
 'enotif_lastdiff' => 'एतत्परिवर्तनं दृष्टुं $1 पश्यतु ।',
 'enotif_anon_editor' => 'अनामकः योजकः $1',
-'enotif_body' => 'आत्मीय $ अवलोकनबन्धो',
+'enotif_body' => 'Dear $WATCHINGUSERNAME,
+
+$PAGEINTRO $NEWPAGE
+
+Editor\'s summary: $PAGESUMMARY $PAGEMINOREDIT
+
+Contact the editor:
+mail: $PAGEEDITOR_EMAIL
+wiki: $PAGEEDITOR_WIKI
+
+There will be no other notifications in case of further activity unless you visit this page. You could also reset the notification flags for all your watched pages on your watchlist.
+
+                        Your friendly {{SITENAME}} notification system
+
+--
+To change your e-mail notification settings, visit
+{{canonicalurl:{{#special:Preferences}}}}
+
+To change your watchlist settings, visit
+{{canonicalurl:{{#special:EditWatchlist}}}}
+
+To delete the page from your watchlist, visit
+$UNWATCHURL
+
+Feedback and further assistance:
+{{canonicalurl:{{MediaWiki:Helppage}}}}',
 'created' => 'सृष्टम् ।',
 'changed' => 'परिवर्तितम् ।',
 
@@ -3015,6 +3040,9 @@ $2 इति प्रकारस्य अवरोधं कर्तुं 
 'pageinfo-protect-cascading' => 'अतस्तु संरक्षणविधिः सोपानवत् गच्छति',
 'pageinfo-protect-cascading-yes' => 'आम्',
 'pageinfo-protect-cascading-from' => 'अधोलिखितेभ्यः संरक्षणविधिः सोपानवत् गच्छति',
+'pageinfo-category-info' => 'वर्गविषयकसूचना',
+'pageinfo-category-pages' => 'पृष्ठानां सङ्ख्या',
+'pageinfo-category-subcats' => 'उपवर्गानां सङ्ख्या',
 
 # Skin names
 'skinname-standard' => 'पूर्व',
index f7b9b1a..ab74e45 100644 (file)
@@ -176,6 +176,7 @@ $messages = array(
 'newwindow' => '(атын түннүккэ арыллар)',
 'cancel' => 'Алҕас',
 'moredotdotdot' => 'Өссө...',
+'morenotlisted' => 'Атын суох...',
 'mypage' => 'Сирэй',
 'mytalk' => 'Кэпсэтэр сирим',
 'anontalk' => 'Бу IP-га ырытыы',
@@ -475,7 +476,7 @@ $2',
 'gotaccount' => "Бэлиэтэммитиҥ дуо? '''$1'''.",
 'gotaccountlink' => 'Аатыҥ',
 'userlogin-resetlink' => 'Киирэр тылгын умнубуккун дуо?',
-'createaccountmail' => 'e-mail-ынан',
+'createaccountmail' => 'Быстах киирии тылы туһаныы уонна ону email-ынан ыытыы',
 'createaccountreason' => 'Төрүөтэ:',
 'badretype' => 'Киирии тылларыҥ сөп түбэспэтилэр.',
 'userexists' => 'Суруйбут аатыҥ бэлиэр баар.
@@ -549,6 +550,7 @@ $2',
 # E-mail sending
 'php-mail-error-unknown' => 'mail() PHP-функциятыгар туох эрэ алҕас тахсыбыт',
 'user-mail-no-addy' => 'Сурук аадырыһа суох ыыттылла сатаабыт',
+'user-mail-no-body' => 'Кураанах эбэтэр суолтата суох кылгас тиэкистээх суругу ыыта сатаабыт.',
 
 # Change password dialog
 'resetpass' => 'Киирии тылы уларытыы',
@@ -776,10 +778,10 @@ IP-аадырыһа эрэ көстөр.
 'copyrightwarning2' => "Болҕой, эн суруйбут матырыйаалгын ким баҕарар уларытар уонна суох гынар бырааптаах. Суруйбуккун уларыталларын сөбүлээбэт буоллаххына манна суруйума.<br />
 Эбиитин манна суруйдаххына, уларытыы ааптара мин буолабын, эбэтэр көҥүл туһанары уонна уларытары көҥүллүүр сиртэн ыллым диэн бигэргэтэҕин (маны көр $1).<br /> '''КИМ ЭРЭ БАС БИЛИИТИН МАННА КИНИТТЭН КӨҤҮЛЭ СУОХ УГУМА!'''",
 'longpageerror' => "'''Алҕас: Суруйар кэрчиккит {{PLURAL:$1|биир килобаайт|$1 килобаайт}} ыйааһыннаах, онтуккут көҥүллэммит {{PLURAL:$2|биир килобаайты|$2 килобайты}} килобаайты куоһарар. Онон сирэй бигэргэтиллэр кыаҕа суох.'''",
-'readonlywarning' => "'''СЭРЭТИИ: Сиэрбэргэ техническай үлэ бара турар, онон киллэрбит уларытыыларыҥ тута хаалар кыахтара суох.
\91илигин Ñ\83лаÑ\80Ñ\8bÑ\82Ñ\8bÑ\8bгÑ\8bн Ð±Ñ\8dйÑ\8dÒ¥ Ð´Ð¸Ð¸Ñ\81кÑ\8dÒ\95Ñ\8dÑ\80 Ñ\85ааллаÑ\80ан Ð±Ð°Ñ\80ан, ÐºÑ\8dлин Ð¼Ð°Ð½Ð½Ð° Ñ\83ган Ð±Ð¸Ñ\8dÑ\80иÑ\8dÑ\85Ñ\85ин Ñ\81өп.'''
+'readonlywarning' => "'''Сэрэтии: Сиэрбэргэ техническай үлэ бара турар, онон киллэрбит уларытыыларыҥ тута бигэргэнэр кыахтара суох.'''
\9eнон Ñ\83лаÑ\80Ñ\8bÑ\82Ñ\8bÑ\8bгÑ\8bн Ñ\82иÑ\8dкиÑ\81Ñ\82Ñ\8dÑ\8dÑ\85 Ð±Ð¸Ð»Ñ\8dÒ\95Ñ\8d Ñ\83ган Ð±Ð°Ñ\80ан, ÐºÑ\8dлин Ð¼Ð°Ð½Ð½Ð° ÐºÐ¸Ð»Ð»Ñ\8dÑ\80иÑ\8dÑ\85Ñ\85ин Ñ\81өп.
 
\94Ñ\8cаһабÑ\8bл Ð¼Ð°Ð½Ð½Ñ\8bк Ð±Ñ\8bһаарбыт: $1",
¥Ð°Ð°Ñ\87Ñ\87аÒ\95Ñ\8b Ñ\82Ñ\83Ñ\80Ñ\83оÑ\80бÑ\83Ñ\82 Ð´Ñ\8cаһабÑ\8bл Ð¼Ð°Ð½Ð½Ñ\8bк Ð±Ñ\8bһааÑ\80Ñ\8bÑ\8bнÑ\8b Ñ\85аалларбыт: $1",
 'protectedpagewarning' => "'''Сэрэтии:  Бу сирэй хатанан турар, администратор бырааптаах эрэ кыттааччылар уларытар кыахтаахтар.'''
 Аллара сурунаал бүтэһик суруга көрдөрүлүннэ:",
 'semiprotectedpagewarning' => "'''Биллэрии:''' Бу сирэй хатанан турар; ааттарын билиһиннэрбит эрэ кыттааччылар уларытар кыахтаахтар.
@@ -818,6 +820,7 @@ IP-аадырыһа эрэ көстөр.
 'edit-already-exists' => 'Саҥа сирэйи оҥорор табыллыбат.
 Маннык сирэй баар эбит.',
 'defaultmessagetext' => 'Туспа этиллибэтэҕинэ суруллар тиэкис',
+'content-failed-to-parse' => '$2 иһинээҕитэ $1 көрүҥэр сөп түбэспэт: $3.',
 'invalid-content-data' => 'Алҕастаах дааннайдар',
 'content-not-allowed-here' => '[[$2]] сирэйгэ "$1" туттуллуо суохтаах',
 
@@ -845,6 +848,7 @@ IP-аадырыһа эрэ көстөр.
 'node-count-exceeded-warning' => 'Сирэй түмүгүн ахсаана таһынан барбыт',
 'expansion-depth-exceeded-category' => 'Аһыллыытын дириҥэ куоһарыллыбыт сирэйдэр',
 'expansion-depth-exceeded-warning' => 'Сирэйгэ угуллубут билэлэр аһара элбээбиттэр',
+'parser-unstrip-loop-warning' => 'Сабыллыбатах pre көһүннэ',
 'parser-unstrip-recursion-limit' => 'Рекурсия ахсаана таһынан барбыт ($1)',
 'converter-manual-rule-error' => 'Тылы уларытыы быраабылатын алҕаһа таҕыста',
 
@@ -1985,7 +1989,7 @@ $1',
 # Special:ActiveUsers
 'activeusers' => 'Көхтөөх кыттааччылар тиһиктэрэ',
 'activeusers-intro' => 'Бу кэлиҥҥи $1 {{PLURAL:$1|күҥҥэ|күннэргэ}} тугу эмэ гыммыт кыттааччылар тиһиктэрэ.',
-'activeusers-count' => '$1 бүтэһик $3 күҥҥэ саҥа {{PLURAL:$1|көннөрүүлээх|көннөрүүлээх эбит}}',
+'activeusers-count' => 'Кэнники $3 күҥҥэ саҥа $1 көннөрүү киирбит',
 'activeusers-from' => 'Мантан саҕалаан кыттааччылары көрүү:',
 'activeusers-hidebots' => 'Руобаттары көрдөрүмэ',
 'activeusers-hidesysops' => 'Дьаһабыллары көрдөрүмэ',
@@ -2049,7 +2053,7 @@ $1',
 'usermessage-editor' => 'Тиһилик биллэрээччитэ',
 
 # Watchlist
-'watchlist' => 'Ð\9cин ÐºÑ\8dÑ\82Ñ\8dÑ\8dһиним',
+'watchlist' => 'Ð\9aÑ\8dÑ\82Ñ\8dбилим Ñ\82иһигÑ\8d',
 'mywatchlist' => 'Кэтэбил тиһигэ',
 'watchlistfor2' => '$1 $2 аналлаах',
 'nowatchlist' => 'Эн кэтиир сирэйдэриҥ суохтар.',
@@ -2057,8 +2061,8 @@ $1',
 'watchnologin' => 'Бэйэҕин билиһиннэр',
 'watchnologintext' => 'Бэйэҕин [[Special:UserLogin|билиһиннэрдэххинэ]] кэтэбил сирэйгин уларытыаххын сөп.',
 'addwatch' => 'Кэтэбил тиһигэр киллэр',
-'addedwatchtext' => "«[[:$1]]» сирэй [[Special:Watchlist|кэтэбилгэ]] киирдэ.
-Сирэй уларытыылара уонна кинини кытта ситимнээх ырытыы сирэйин уларытыылара бүгүҥҥүттэн онно көстөр буолуохтара. Эбиитин [[Special:RecentChanges|саҥа уларытыы тиһигэр]] '''модьу''' бичигинэн бэлиэтэнэн көстүөхтэрэ.",
+'addedwatchtext' => '«[[:$1]]» сирэй [[Special:Watchlist|кэтэбил тиһигэр]] киирдэ.
+Сирэй уларытыылара уонна кинини кытта ситимнээх ырытыы сирэйин уларытыылара бүгүҥҥүттэн онно көстөр буолуохтара.',
 'removewatch' => 'Кэтэбил тиһигиттэн сот',
 'removedwatchtext' => '[[:$1]]" сирэй [[Special:Watchlist|кэтэбилиҥ тиһигиттэн]] сотулунна.',
 'watch' => 'Кэтээ',
@@ -2200,9 +2204,9 @@ $UNWATCHURL
 '''$1''' сирэй уларыыттын таһыма билиҥҥи туругунан маннык:",
 'protect-cascadeon' => 'Бу сирэй уларытыыттан көмүскэммит {{PLURAL:$1|сирэй бөлөҕөр|сирэйдэр бөлөхтөрүгэр}} (каскааднай көмүскэл) киирэр буолан эмиэ көмүскэммит. Эн көмүскэнии таһымын уларытыаххын сөп, ол каскаднай көмүскэли уларыппат.',
 'protect-default' => 'Барыларыгар көҥүллэнэр',
-'protect-fallback' => '"$1" көҥүллэ көрдөө',
-'protect-level-autoconfirmed' => 'Саҥа Ñ\83онна Ð±Ñ\8dлиÑ\8dÑ\82Ñ\8dммÑ\8dÑ\82Ñ\8dÑ\85 ÐºÑ\8bÑ\82Ñ\82ааÑ\87Ñ\87Ñ\8bлаÑ\80 Ñ\83лаÑ\80Ñ\8bппаÑ\82Ñ\82аÑ\80Ñ\8bн ÐºÑ\83Ñ\80дÑ\83к Ð¾Ò¥Ð¾р',
-'protect-level-sysop' => 'Дьаһабыллар эрэ',
+'protect-fallback' => '"$1" кыттааччылар эрэ маны оҥорор кыахтаахтар',
+'protect-level-autoconfirmed' => 'Ð\90пÑ\82амааÑ\82Ñ\8bнан Ð±Ð¸Ð³Ñ\8dÑ\80гÑ\8dммиÑ\82 ÐºÑ\8bÑ\82Ñ\82ааÑ\87Ñ\87Ñ\8bлаÑ\80га Ñ\8dÑ\80Ñ\8d ÐºÓ©Ò¥Ò¯Ð»Ð»Ñ\8dнÑ\8dр',
+'protect-level-sysop' => 'Дьаһабылларга эрэ көҥүллэнэр',
 'protect-summary-cascade' => 'каскадтаах',
 'protect-expiring' => 'болдьоҕо $1 (UTC)',
 'protect-expiring-local' => 'болдьоҕо баччаҕа бүтэр: $1',
@@ -2498,15 +2502,15 @@ $1',
 'movepagetext' => "Манна баар форманы туһанан сирэй аатын уларытыаххын сөп.
 Бу түбэлтэҕэ уларытыы сурунаала саҥа сиргэ көһөр.
 Урукку аат саҥа сирэйгэ утаарар сирэйгэ кубулуйар.
-Урукку аакка ыйынньыктар уларыйбаттар;
-бука диэн [[Special:DoubleRedirects|хос ыйынньыктар]] уонна [[Special:BrokenRedirects|быстыбыт сигэниилэр]] баалларын-суохтарын көр.
+Урукку аакка ыйынньыктары аптамаатынан уларытыаххын сөп.
\98ннÑ\8cÑ\8d Ð³Ñ\8bммаÑ\82 Ð±Ñ\83оллаÑ\85Ñ\85Ñ\8bна, Ð±Ñ\83ка Ð´Ð¸Ñ\8dн [[Special:DoubleRedirects|Ñ\85оÑ\81 Ñ\8bйÑ\8bннÑ\8cÑ\8bкÑ\82аÑ\80]] Ñ\83онна [[Special:BrokenRedirects|бÑ\8bÑ\81Ñ\82Ñ\8bбÑ\8bÑ\82 Ñ\81игÑ\8dниилÑ\8dÑ\80]] Ð±Ð°Ð°Ð»Ð»Ð°Ñ\80Ñ\8bн-Ñ\81Ñ\83оÑ\85Ñ\82аÑ\80Ñ\8bн ÐºÓ©Ñ\80.
 Сиэр быһыытынан ыйынньыктар сөпкө сигэнэллэрин эн ситиһиэхтээххин.
 
 Өскө маннык ааттаах сирэй номнуо баар буоллаҕына сирэй аата '''уларыйыа суоҕа''', арай ол сирэй кураанах эбэтэр утаарар сирэй буолбатах буоллаҕына.
-Ол аата эн сирэй аатын сыыһа уларыппыт буоллаххына төттөрү урукку аатыгар төннөрүөххүн сөп гынан баран баар сирэйи алҕас сотор кыаҕыҥ суох.
+Ол аата эн сирэй аатын сыыһа уларыппыт буоллаххына төттөрү урукку аатыгар төннөрүөххүн сөп, ол гынан баран баар сирэйи алҕас сотор кыаҕыҥ суох.
 
-'''СЭРЭТИИ!'''
-Сирэй аатын уларытыы улахан уонна эрдэттэн өйдөммөтөх содуллаах буолуон сөп.
+'''Сэрэтии!'''
+Сирэй аатын уларытыы бөдөҥ уонна эрдэттэн өйдөммөтөх содуллаах буолуон сөп.
 Онон, бука диэн салгыаҥ иннинэ үчүгэйдик толкуйдаа.",
 'movepagetext-noredirectfixer' => "Манна баар форманы туһанан сирэй аатын уларытыаххын сөп.
 Бу түбэлтэҕэ уларытыы сурунаала саҥа сиргэ көһөр.
@@ -2841,6 +2845,7 @@ $1',
 'pageinfo-recent-authors' => 'Бу сирэйи уларыппыт киһи ахсаана',
 'pageinfo-magic-words' => 'Аптаах {{PLURAL:$1|тыл|тыллар}} ($1)',
 'pageinfo-hidden-categories' => 'Кистэммит {{PLURAL:$1|категория|категориялар}} ($1)',
+'pageinfo-templates' => '$1 халыыптаах ($1)',
 'pageinfo-contentpage-yes' => 'Сөп',
 'pageinfo-protect-cascading' => 'Каскаадынан көмүскэл мантан',
 'pageinfo-protect-cascading-yes' => 'Сөп',
@@ -3579,7 +3584,7 @@ MediaWiki туһалаах буоллун диэн тарҕатыллар, ол
 'specialpages-group-highuse' => 'Элбэхтик туттуллар сирэйдэр',
 'specialpages-group-pages' => 'Сирэйдэр тиһиктэрэ',
 'specialpages-group-pagetools' => 'Сирэйдэр үнүстүрүмүөннэрэ',
-'specialpages-group-wiki' => 'Wiki дааннайдара уонна үнүстүрүмүөннэр',
+'specialpages-group-wiki' => 'Дааннайдара уонна тэриллэрэ',
 'specialpages-group-redirects' => 'Утаарар аналлаах сирэйдэр',
 'specialpages-group-spam' => 'Спаамы утары үнүстүрүмүөннэр',
 
@@ -3675,7 +3680,7 @@ MediaWiki туһалаах буоллун диэн тарҕатыллар, ол
 'logentry-patrol-patrol-auto' => '$1 $3 сирэй $4 барылын аптамаатынан ботуруулламмыт курдук бэлиэтээбит',
 'logentry-newusers-newusers' => '$1 диэн кыттааччы бэлиэтэннэ',
 'logentry-newusers-create' => '$1 диэн кыттааччы бэлиэтэннэ',
-'logentry-newusers-create2' => '$3 кыттааччыны $1 бэлиэтээбит',
+'logentry-newusers-create2' => '$3 кыттааччы аатын $1 бэлиэтээбит',
 'logentry-newusers-autocreate' => 'Маннык аат $1 аптамаатынан бэлиэтэнилиннэ',
 'rightsnone' => '(суох)',
 
index 31bd8ea..95d0344 100644 (file)
@@ -121,6 +121,8 @@ $magicWords = array(
        'numberofarticles'          => array( '1', 'ARTIHKKALIIDMEARRI', 'NUMBEROFARTICLES' ),
 );
 
+$separatorTransformTable = array( ',' => "\xc2\xa0", '.' => ',' );
+
 $linkTrail = '/^(:?[a-zàáâçčʒǯđðéèêëǧǥȟíìîïıǩŋñóòôõßšŧúùûýÿüžþæøåäö]+)(.*)$/sDu';
 
 $messages = array(
index d3f2c4b..ce5cac7 100644 (file)
@@ -624,7 +624,7 @@ Ne pozabite si prilagoditi vaših [[Special:Preferences|nastavitev {{GRAMMAR:rod
 'gotaccount' => 'Račun že imate? $1.',
 'gotaccountlink' => 'Prijavite se',
 'userlogin-resetlink' => 'Ste pozabili svoje prijavne podatke?',
-'createaccountmail' => 'Po e-pošti',
+'createaccountmail' => 'Ustvari začasno naključno geslo in ga pošlji na spodaj navedeni e-poštni naslov',
 'createaccountreason' => 'Razlog:',
 'badretype' => 'Gesli, ki ste ju vnesli, se ne ujemata.',
 'userexists' => 'Uporabniško ime, ki ste ga vnesli, je že zasedeno.
@@ -1241,7 +1241,7 @@ Podrobnosti lahko najdete v [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENA
 'search-interwiki-default' => '$1 zadetkov:',
 'search-interwiki-more' => '(več)',
 'search-relatedarticle' => 'Podobno',
-'mwsuggest-disable' => 'Onemogoči predloge Ajax',
+'mwsuggest-disable' => 'Onemogoči iskalne predloge',
 'searcheverything-enable' => 'Iskanje po vseh imenskih prostorih',
 'searchrelated' => 'povezano',
 'searchall' => 'vse',
@@ -3023,6 +3023,7 @@ Omogoča vnos pojasnila v povzetku urejanja.',
 'pageinfo-robot-noindex' => 'Ni na voljo za indeksiranje',
 'pageinfo-views' => 'Število ogledov',
 'pageinfo-watchers' => 'Število spremljevalcev strani',
+'pageinfo-few-watchers' => 'Manj kot $1 {{PLURAL:$1|spremljevalec|spremljevalca|spremljevalci|spremljevalcev}}',
 'pageinfo-redirects-name' => 'Preusmeritve na stran',
 'pageinfo-subpages-name' => 'Podstrani strani',
 'pageinfo-subpages-value' => '$1 ($2 {{PLURAL:$2|preusmeritev|preusmeritvi|preusmeritve|preusmeritev}}; $3 {{PLURAL:$3|nepreusmeritev|nepreusmeritvi|nepreusmeritve|nepreusmeritev}})',
@@ -3897,6 +3898,7 @@ Ta stran se sooča s tehničnimi težavami.',
 'logentry-newusers-newusers' => '$1 je ustvaril(-a) uporabniški račun',
 'logentry-newusers-create' => '$1 je ustvaril(-a) uporabniški račun',
 'logentry-newusers-create2' => '$1 je ustvaril(-a) uporabniški račun $3',
+'logentry-newusers-byemail' => '$1 je {{GENDER:$2|ustvaril|ustvarila|ustvaril(-a)}} uporabniški račun $3; geslo je bilo poslano po e-pošti',
 'logentry-newusers-autocreate' => 'Račun $1 je bil samodejno ustvarjen',
 'logentry-rights-rights' => '$1 je spremenil(-a) članstvo skupine $3 z $4 na $5',
 'logentry-rights-rights-legacy' => '$1 je spremenil(-a) članstvo skupine $3',
index 1c6af03..6767d65 100644 (file)
@@ -829,6 +829,7 @@ E-mailkaada mala sheegaayo markii ee dadka kale kula soo xiriirayaan.',
 # User rights
 'saveusergroups' => 'Kaydi kooxaha isticmaalayaasha',
 'userrights-groupsmember' => 'Ka mid ah:',
+'userrights-reason' => 'Sababta:',
 
 # Groups
 'group' => 'Koox:',
index 9e9b72d..bee87f8 100644 (file)
@@ -1575,7 +1575,7 @@ Om du väljer att ange ditt riktiga namn, kommer det att användas för att till
 'right-bot' => 'Behandlas som en automatisk process',
 'right-nominornewtalk' => 'Mindre ändringar på diskussionssidor ger inte besked om nya meddelanden',
 'right-apihighlimits' => 'Använda högre gränser i API-frågor',
-'right-writeapi' => 'Använda skriv-API:t',
+'right-writeapi' => 'Använda skriv-API:et',
 'right-delete' => 'Radera sidor',
 'right-bigdelete' => 'Radera sidor med stor historik',
 'right-deletelogentry' => 'Radera och återställ specifika loggposter',
@@ -3918,7 +3918,7 @@ Bilder visas i full upplösning, andra filtyper öppnas direkt i de program som
 'specialpages-group-highuse' => 'Sidor som används mycket',
 'specialpages-group-pages' => 'Listor över sidor',
 'specialpages-group-pagetools' => 'Sidverktyg',
-'specialpages-group-wiki' => 'Information och verktyg för wikin',
+'specialpages-group-wiki' => 'Data och verktyg',
 'specialpages-group-redirects' => 'Omdirigerande specialsidor',
 'specialpages-group-spam' => 'Spamverktyg',
 
@@ -4015,6 +4015,7 @@ Bilder visas i full upplösning, andra filtyper öppnas direkt i de program som
 'logentry-newusers-newusers' => 'Användarkonto $1 skapades',
 'logentry-newusers-create' => 'Användarkonto $1 skapades',
 'logentry-newusers-create2' => 'Användarkonto $3 skapades av $1',
+'logentry-newusers-byemail' => 'Användarkontot $3 skapades av $1 och lösenordet skickades via e-post',
 'logentry-newusers-autocreate' => 'Kontot $1 skapades automatiskt',
 'logentry-rights-rights' => '$1 ändrade gruppmedlemskap för $3 från $4 till $5',
 'logentry-rights-rights-legacy' => '$1 ändrade gruppmedlemskap för $3',
index 227ae41..f2ead23 100644 (file)
@@ -1099,7 +1099,7 @@ Tazama [[Special:BlockList|IP block orodha ya uzuio wa IP]] kuona orodha ya zuio
 'search-interwiki-default' => 'Matokeo toka $1:',
 'search-interwiki-more' => '(zaidi)',
 'search-relatedarticle' => 'Zingine zinazofanana',
-'mwsuggest-disable' => 'Kutoonyesha mapendekezo ya AJAX',
+'mwsuggest-disable' => 'Kutoonyesha mapendekezo ya kutafuta',
 'searcheverything-enable' => 'Tafuta katika maeneo yote ya wiki',
 'searchrelated' => 'zingine zinazofanana',
 'searchall' => 'zote',
@@ -1981,7 +1981,7 @@ Anwani yako ya barua pepe ulioitaja katika [[Special:Preferences|mapendekezo yak
 'usermessage-editor' => 'Jumbe za mfumo',
 
 # Watchlist
-'watchlist' => 'Maangalizi yangu',
+'watchlist' => 'Maangalizi',
 'mywatchlist' => 'Maangalizi',
 'watchlistfor2' => 'Kwa ajili ya $1 $2',
 'nowatchlist' => 'Hamna vitu katika maangalizi yako.',
@@ -2200,7 +2200,7 @@ $1',
 'blanknamespace' => '(Kuu)',
 
 # Contributions
-'contributions' => 'Michango ya mtumiaji',
+'contributions' => 'Michango ya {{GENDER:$1|mtumiaji}}',
 'contributions-title' => 'Michango ya mtumiaji $1',
 'mycontris' => 'Michango',
 'contribsub2' => 'Kwa $1 ($2)',
@@ -2243,7 +2243,7 @@ Rejea kumbukumbu ya uzuio ya mwisho inayoandikwa chini:',
 'whatlinkshere-hideredirs' => '$1 maelekezo',
 'whatlinkshere-hidetrans' => '$1 majumuisho',
 'whatlinkshere-hidelinks' => '$1 viungo',
-'whatlinkshere-hideimages' => '$1 viungo vya picha',
+'whatlinkshere-hideimages' => 'viungo $1 vya faili',
 'whatlinkshere-filters' => 'Machujio',
 
 # Block/unblock
index 0e110b2..67c8e48 100644 (file)
@@ -392,7 +392,7 @@ $messages = array(
 'protect_change' => 'เปลี่ยน',
 'protectthispage' => 'ล็อกหน้านี้',
 'unprotect' => 'เปลี่ยนค่าการป้องกัน',
-'unprotectthispage' => 'à¹\81à¸\81à¹\89à¹\84à¸\82การป้องกันหน้านี้',
+'unprotectthispage' => 'à¹\80à¸\9bลีà¹\88ยà¸\99การป้องกันหน้านี้',
 'newpage' => 'หน้าใหม่',
 'talkpage' => 'อภิปรายหน้านี้',
 'talkpagelinktext' => 'พูดคุย',
@@ -509,7 +509,7 @@ $1',
 คุณอาจกรอกยูอาร์แอลผิด หรือมาตามลิงก์ที่ไม่ถูกต้อง
 หรืออาจเกิดจากข้อผิดพลาดในซอฟต์แวร์ซึ่ง {{SITENAME}} ใช้อยู่',
 'nosuchspecialpage' => 'ไม่มีหน้าพิเศษดังกล่าว',
-'nospecialpagetext' => '<strong>à¸\84ุà¸\93รà¹\89อà¸\87à¸\82อหà¸\99à¹\89าà¸\9eิà¹\80ศษà¹\84มà¹\88à¸\96ูà¸\81à¸\95à¹\89อà¸\87</strong>
+'nospecialpagetext' => '<strong>คุณขอหน้าพิเศษไม่ถูกต้อง</strong>
 
 รายการหน้าพิเศษที่ถูกต้องดูได้ที่ [[Special:SpecialPages|รายการหน้าพิเศษ]]',
 
@@ -537,7 +537,7 @@ $1',
 
 สาเหตุมักเกิดจากการเปรียบเทียบที่ล้าสมัย หรือการเชื่อมโยงประวัติไปยังหน้านั้นได้ถูกลบแล้ว
 
-หากไม่ใช่กรณีดังกล่าว คุณอาจพบบั๊กในซอฟต์แวร์ กรุณารายงานต่อ[[Special:ListUsers/sysop|ผู้ดูแลระบบ]] พร้อมระบุ URL',
+หากไม่ใช่กรณีดังกล่าว คุณอาจพบบั๊กในซอฟต์แวร์ กรุณารายงานต่อ[[Special:ListUsers/sysop|ผู้ดูแลระบบ]] พร้อมระบุยูอาร์แอล',
 'missingarticle-rev' => '(รุ่น#: $1)',
 'missingarticle-diff' => '(ต่าง: $1, $2)',
 'readonly_lag' => 'ฐานข้อมูลถูกล็อกอัตโนมัติขณะที่เซิร์ฟเวอร์ฐานข้อมูลรองกำลังปรับปรุงตามฐานข้อมูลหลัก',
@@ -560,7 +560,8 @@ $1',
 'delete-hook-aborted' => 'การลบถูกฮุกยกเลิก
 ไม่มีคำอธิบายสำหรับการยกเลิกนี้',
 'badtitle' => 'ชื่อไม่เหมาะสม',
-'badtitletext' => 'ชื่อหน้าที่ร้องขอไม่ถูกต้อง เป็นชื่อว่าง หรือชื่อที่ผิดพลาดเนื่องจากลิงก์ข้ามมาจากภาษาอื่น ชื่อที่ใช้อาจมีตัวอักษรที่ไม่สามารถปรากฏในชื่อได้',
+'badtitletext' => 'ชื่อของหน้าที่ร้องขอไม่ถูกต้อง อาจเป็นชื่อว่าง หรือชื่อที่ผิดพลาดเนื่องจากลิงก์ข้ามมาจากภาษาอื่น
+หรือไม่ชื่อที่ใช้อาจมีตัวอักษรที่ไม่สามารถปรากฏในชื่อก็ได้',
 'perfcached' => 'ข้อมูลต่อไปนี้ถูกเก็บไว้ในแคช และอาจล้าสมัย มีผลการค้นหาสูงสุด $1 รายการในแคช',
 'perfcachedts' => 'ข้อมูลต่อไปนี้ถูกเก็บไว้ในหน่วยความจำแคช และได้รับการปรับล่าสุดเมื่อ $1 ค่าสูงสุด $4 ผลลัพธ์สามารถเก็บไว้ในหน่วยความจำแคชได้',
 'querypage-no-updates' => 'ขณะนี้การปรับปรุงหน้านี้ถูกระงับ ข้อมูลในที่นี่จะไม่รีเฟรชเป็นปัจจุบัน',
@@ -585,8 +586,8 @@ $1',
 'customcssprotected' => 'คุณไม่มีสิทธิแก้ไขหน้าสไตล์ CSS นี้ เนื่องจากหน้านี้มีการตั้งค่าส่วนบุคคลของผู้ใช้อื่น',
 'customjsprotected' => 'คุณไม่มีสิทธิแก้ไขหน้าจาวาสคริปต์นี้ เนื่องจากหน้านี้มีการตั้งค่าส่วนบุคคลของผู้ใช้อื่น',
 'ns-specialprotected' => 'หน้าพิเศษไม่สามารถแก้ไขได้',
-'titleprotected' => "หัวเรื่องนี้ถูกป้องกันมิให้สร้างโดย [[User:$1|$1]] 
-เหตุผลที่ให้ไว้ คือ ''$2''",
+'titleprotected' => "à¸\8aืà¹\88อเรื่องนี้ถูกป้องกันมิให้สร้างโดย [[User:$1|$1]] 
+เหตุผลที่ให้ไว้คือ ''$2''",
 'invalidtitle-knownnamespace' => 'ชื่อที่มีเนมสเปซ "$2" กับข้อความ "$3" ไม่ถูกต้อง',
 'invalidtitle-unknownnamespace' => 'ชื่อที่ไม่ทราบเนมสเปซหมายเลข $1 กับข้อความ "$2" ไม่ถูกต้อง',
 'exception-nologin' => 'ไม่ได้ล็อกอิน',
@@ -641,15 +642,15 @@ $1',
 'loginsuccesstitle' => 'ล็อกอินสำเร็จ',
 'loginsuccess' => "'''ขณะนี้คุณล็อกอินเข้าสู่ {{SITENAME}} ด้วยชื่อ \"\$1\"'''",
 'nosuchuser' => 'ไม่มีผู้ใช้ชื่อ "$1"
-อัà¸\81ษรà¹\83หà¸\8dà¹\88à¹\80ลà¹\87à¸\81มีà¸\9cลà¸\95à¹\88อà¸\8aืà¹\88อà¸\9cูà¹\89à¹\83à¸\8aà¹\89
+à¸\8aืà¹\88อà¸\9cูà¹\89à¹\83à¸\8aà¹\89à¸\99ัà¹\89à¸\99à¹\84วà¸\95à¹\88ออัà¸\81ษรà¹\83หà¸\8dà¹\88à¹\80ลà¹\87à¸\81
 กรุณาตรวจการสะกดอีกครั้ง หรือ[[Special:UserLogin/signup|สร้างบัญชีใหม่]]',
 'nosuchusershort' => 'ไม่มีผู้ใช้ชื่อ "$1" กรุณาตรวจสอบการสะกด',
 'nouserspecified' => 'คุณต้องระบุชื่อผู้ใช้',
 'login-userblocked' => 'ผู้ใช้นี้ถูกบล็อก ไม่อนุญาตให้ล็อกอิน',
 'wrongpassword' => 'รหัสผ่านที่ใส่ไม่ถูกต้อง โปรดลองอีกครั้ง',
 'wrongpasswordempty' => 'ยังไม่ได้ระบุรหัสผ่าน โปรดลองอีกครั้ง',
-'passwordtooshort' => 'รหัสà¸\9cà¹\88าà¸\99à¸\95à¹\89อà¸\87มีà¸\84วามยาวอยà¹\88าà¸\87à¸\99à¹\89อย $1 à¸\95ัวอัà¸\81ษร',
-'password-name-match' => 'รหัสà¸\9cà¹\88าà¸\99à¸\82อà¸\87à¸\84ุà¸\93à¸\95à¹\89อà¸\87à¸\95à¹\88าà¸\87à¸\88าà¸\81à¸\8aืà¹\88อà¸\9cูà¹\89à¹\83à¸\8aà¹\89à¸\82อà¸\87à¸\84ุà¸\93',
+'passwordtooshort' => 'รหัสà¸\9cà¹\88าà¸\99à¸\95à¹\89อà¸\87มีà¸\84วามยาวอยà¹\88าà¸\87à¸\99à¹\89อย $1 à¸­à¸±à¸\81à¸\82ระ',
+'password-name-match' => 'รหัสà¸\9cà¹\88าà¸\99à¸\95à¹\89อà¸\87à¸\95à¹\88าà¸\87à¸\88าà¸\81à¸\8aืà¹\88อà¸\9cูà¹\89à¹\83à¸\8aà¹\89',
 'password-login-forbidden' => 'ห้ามใช้ชื่อผู้ใช้และรหัสผ่านนี้',
 'mailmypassword' => 'อีเมลรหัสผ่านใหม่',
 'passwordremindertitle' => 'รหัสผ่านชั่วคราวใหม่สำหรับ {{SITENAME}}',
@@ -666,18 +667,19 @@ $1',
 'mailerror' => 'ไม่สามารถส่งอีเมลเนื่องจาก $1',
 'acct_creation_throttle_hit' => 'ผู้เข้าชมที่ใช้หมายเลขไอพีของคุณในวิกินี้ ได้สร้างชื่อบัญชีแล้ว $1 บัญชีในวันที่ผ่านมา ซึ่งเป็นจำนวนมากที่สุดที่อนุญาตในช่วงเวลาดังกล่าว
 จึงส่งผลให้ผู้เข้าชมที่ใช้หมายเลขไอพีนี้ ไม่สามารถสร้างบัญชีได้อีกในขณะนี้',
-'emailauthenticated' => 'อีเมลของคุณได้รับการรับรอง ณ วันที่ $2 เวลา $3',
-'emailnotauthenticated' => 'อีเมลของคุณยังไม่ได้ถูกยืนยัน ดังนั้นคำสั่งพิเศษที่ใช้งานผ่านอีเมลยังไม่เปิดใช้งาน',
+'emailauthenticated' => 'อีเมลของคุณได้รับการยืนยันเมื่อวันที่ $2 เวลา $3',
+'emailnotauthenticated' => 'ที่อยู่อีเมลของคุณยังไม่ได้รับการยืนยัน 
+ไม่มีการส่งอีเมลสำหรับคุณลักษณะใด ๆ ต่อไปนี้',
 'noemailprefs' => 'ระบุที่อยู่อีเมลในการตั้งค่าของคุณเพื่อให้คุณลักษณะเหล่านี้ทำงานได้',
 'emailconfirmlink' => 'ยืนยันอีเมลของคุณ',
 'invalidemailaddress' => 'ไม่สามารถรับที่อยู่อีเมลได้ เพราะดูมีรูปแบบไม่ถูกต้อง
 โปรดใส่ที่อยู่ให้มีรูปแบบถูกต้อง หรือเว้นช่องนั้น',
 'cannotchangeemail' => 'ไม่สามารถเปลี่ยนที่อยู่อีเมลบนวิกินี้',
 'emaildisabled' => 'เว็บไซต์นี้ไม่สามารถส่งอีเมล',
-'accountcreated' => 'à¸\8aืà¹\88อà¸\9aัà¸\8dà¸\8aีà¹\84à¸\94à¹\89ถูกสร้างขึ้น',
-'accountcreatedtext' => 'à¸\8aืà¹\88อà¸\9aัà¸\8dà¸\8aีสำหรัà¸\9a $1 à¹\84à¸\94à¹\89ถูกสร้างขึ้นแล้ว',
+'accountcreated' => 'à¸\9aัà¸\8dà¸\8aีถูกสร้างขึ้น',
+'accountcreatedtext' => 'à¸\9aัà¸\8dà¸\8aีà¸\9cูà¹\89à¹\83à¸\8aà¹\89à¸\82อà¸\87 $1 ถูกสร้างขึ้นแล้ว',
 'createaccount-title' => 'สร้างบัญชีสำหรับ {{SITENAME}}',
-'createaccount-text' => 'มีà¸\9aาà¸\87à¸\84à¸\99สรà¹\89าà¸\87à¸\9aัà¸\8dà¸\8aีสำหรัà¸\9aà¸\97ีà¹\88อยูà¹\88อีà¹\80มลà¸\82อà¸\87à¸\84ุà¸\93à¹\84วà¹\89à¸\9aà¸\99 {{SITENAME}} ($4) à¹\82à¸\94ยà¹\83à¸\8aà¹\89à¸\8aืà¹\88อà¸\9aัà¸\8dà¸\8aีà¸\9cูà¹\89à¹\83à¸\8aà¹\89 "$2" และรหัสผ่าน "$3" คุณควรล็อกอินเพื่อเปลี่ยนรหัสผ่านทันที
+'createaccount-text' => 'มีà¸\9aาà¸\87à¸\84à¸\99สรà¹\89าà¸\87à¸\9aัà¸\8dà¸\8aีà¹\82à¸\94ยà¹\83à¸\8aà¹\89à¸\97ีà¹\88อยูà¹\88อีà¹\80มลà¸\82อà¸\87à¸\84ุà¸\93à¸\9aà¸\99 {{SITENAME}} ($4) à¹\82à¸\94ยà¹\83à¸\8aà¹\89à¸\8aืà¹\88อ "$2" และรหัสผ่าน "$3" คุณควรล็อกอินเพื่อเปลี่ยนรหัสผ่านทันที
 
 คุณอาจเพิกเฉยข้อความนี้ หากการสร้างบัญชีนี้เกิดจากความผิดพลาด',
 'usernamehasherror' => 'ในชื่อผู้ใช้ต้องไม่มีตัวอักษร "#"',
@@ -730,14 +732,14 @@ $1',
 'changeemail-oldemail' => 'ที่อยู่อีเมลปัจจุบัน:',
 'changeemail-newemail' => 'ที่อยู่อีเมลใหม่:',
 'changeemail-none' => '(ไม่มี)',
-'changeemail-password' => 'รหัสผ่าน{{SITENAME}}ของคุณ:',
+'changeemail-password' => 'รหัสผ่าน {{SITENAME}} ของคุณ:',
 'changeemail-submit' => 'เปลี่ยนอีเมล',
 'changeemail-cancel' => 'ยกเลิก',
 
 # Edit page toolbar
-'bold_sample' => 'à¸\97ำตัวหนา',
+'bold_sample' => 'à¸\82à¹\89อà¸\84วามตัวหนา',
 'bold_tip' => 'ทำตัวหนา',
-'italic_sample' => 'à¸\95ัวหà¸\99ัà¸\87สือà¸\97ีà¹\88à¹\80à¸\9bà¹\87à¸\99ตัวเอน',
+'italic_sample' => 'à¸\82à¹\89อà¸\84วามตัวเอน',
 'italic_tip' => 'ทำตัวเอน',
 'link_sample' => 'ลิงก์เชื่อมโยง',
 'link_tip' => 'ลิงก์ภายในเว็บ',
@@ -745,8 +747,8 @@ $1',
 'extlink_tip' => 'ลิงก์ภายนอก (อย่าลืมใส่ http:// นำหน้าเสมอ)',
 'headline_sample' => 'หัวข้อ',
 'headline_tip' => 'หัวข้อ',
-'nowiki_sample' => 'à¹\83สà¹\88à¸\82à¹\89อà¸\84วามà¸\97ีà¹\88à¹\84มà¹\88à¸\88ัà¸\94รูà¸\9bà¹\81à¸\9aà¸\9a',
-'nowiki_tip' => 'à¸\82à¹\89ามการจัดรูปแบบวิกิ',
+'nowiki_sample' => 'à¹\81à¸\97รà¸\81à¸\82à¹\89อà¸\84วามà¸\97ีà¹\88à¹\84มà¹\88à¸\88ัà¸\94รูà¸\9bà¹\81à¸\9aà¸\9aà¸\97ีà¹\88à¸\99ีà¹\88',
+'nowiki_tip' => 'à¹\84มà¹\88สà¸\99à¹\83à¸\88การจัดรูปแบบวิกิ',
 'image_sample' => 'ตัวอย่าง.jpg',
 'image_tip' => 'ใส่ไฟล์',
 'media_sample' => 'ตัวอย่าง.ogg',
@@ -766,40 +768,40 @@ $1',
 'showdiff' => 'แสดงความเปลี่ยนแปลง',
 'anoneditwarning' => "'''คำเตือน:''' คุณมิได้ล็อกอิน ที่อยู่ไอพีของคุณจะถูกบันทึกไว้ในประวัติการแก้ไขของหน้านี้",
 'anonpreviewwarning' => "'''คุณมิได้ล็อกอิน การบันทึกจะเก็บที่อยู่ไอพีของคุณในประวัติการแก้ไขของหน้านี้'''",
-'missingsummary' => "'''อย่าลืม:''' คุณยังไม่ได้ระบุคำอธิบายการแก้ไขครั้งนี้ ถ้าคุณกดบันทึกไปส่วนคำอธิบายการแก้ไขนั้นจะว่างและไม่แสดงผล",
+'missingsummary' => "'''อย่าลืม:''' คุณยังไม่ได้ระบุคำอธิบายการแก้ไข ถ้าคุณกด \"บันทึก\" อีกครั้ง การแก้ไขของคุณจะถูกบันทึกโดยไม่มีคำอธิบายการแก้ไข",
 'missingcommenttext' => 'กรุณาใส่ความเห็นด้านล่าง',
 'missingcommentheader' => "'''ประกาศเตือน:''' คุณยังไม่ได้ใส่หัวข้อ/จ่าหัวสำหรับความเห็นนี้ ถ้าคุณกด \"{{int:savearticle}}\" อีกครั้ง การแก้ไขของคุณจะถูกบันทึกโดยไม่มีหัวข้อ",
 'summary-preview' => 'ตัวอย่างคำอธิบายการแก้ไข:',
 'subject-preview' => 'ตัวอย่างหัวข้อ:',
 'blockedtitle' => 'ผู้ใช้ถูกบล็อก',
-'blockedtext' => "'''à¸\8aืà¹\88อà¸\9cูà¹\89à¹\83à¸\8aà¹\89หรือหมายà¹\80ลà¸\82à¹\84อà¸\9eีà¸\96ูà¸\81à¸\82อà¸\87à¸\84ุà¸\93à¸\96ูà¸\81à¸\9aลà¹\87อà¸\81'''
+'blockedtext' => "'''ชื่อผู้ใช้หรือหมายเลขไอพีของคุณถูกบล็อก'''
 
-$1 เป็นผู้ดำเนินการบล็อก 
¹\82à¸\94ยà¹\83หà¹\89à¹\80หà¸\95ุà¸\9cลว่า ''$2''
+การบล็อกนี้ดำเนินการโดย $1
¸\8bึà¹\88à¸\87ระà¸\9aุà¹\80หà¸\95ุà¸\9cลà¹\84วà¹\89ว่า ''$2''
 
 * เริ่มการบล็อก: $8
 * หมดเขตการบล็อก: $6
 * ผู้ถูกบล็อก: $7
 
-à¸\84ุà¸\93สามารà¸\96à¸\95ิà¸\94à¸\95à¹\88อ $1 à¸«à¸£à¸·à¸­[[{{MediaWiki:Grouppage-sysop}}|à¸\9cูà¹\89à¸\94ูà¹\81ลระà¸\9aà¸\9a]]à¸\84à¸\99อืà¹\88à¸\99à¹\80à¸\9eืà¹\88อหารือà¹\80à¸\81ีà¹\88ยวà¸\81ัà¸\9aà¸\81ารà¸\9aลà¹\87อà¸\81à¸\99ีà¹\89 
-คุณไม่สามารถใช้คุณลักษณะ 'ส่งอีเมลหาผู้ใช้รายนี้ได้' จนกว่าจะระบุที่อยู่อีเมลที่ถูกต้องใน[[Special:Preferences|การตั้งค่าบัญชี]]ของคุณ และคุณมิได้ถูกบล็อกมิให้ใช
-
¸«à¸¡à¸²à¸¢à¹\80ลà¸\82à¹\84อà¸\9eีà¸\9bัà¸\88à¸\88ุà¸\9aัà¸\99à¸\82อà¸\87à¸\84ุà¸\93à¸\84ือ $3 à¹\81ละหมายà¹\80ลà¸\82à¸\81ารà¸\9aลà¹\87อà¸\81à¸\84ือ #$5 à¸\81รุà¸\93าระà¸\9aุหมายà¹\80ลà¸\82à¹\80หลà¹\88าà¸\99ีà¹\89à¹\83à¸\99à¸\81ารà¸\95ิà¸\94à¸\95à¹\88อà¹\83à¸\94 à¹\86",
-'autoblockedtext' => 'หมายเลขไอพีของคุณถูกบล็อกโดยอัตโนมัติ เนื่องจากมีผู้ใช้อื่นใช้งานผ่านหมายเลขไอพีนี้มาก่อน ซึ่งถูกบล็อกโดย $1
+à¸\84ุà¸\93สามารà¸\96à¸\95ิà¸\94à¸\95à¹\88อ $1 à¸«à¸£à¸·à¸­[[{{MediaWiki:Grouppage-sysop}}|à¸\9cูà¹\89à¸\94ูà¹\81ลระà¸\9aà¸\9a]]à¸\84à¸\99อืà¹\88à¸\99à¹\80à¸\9eืà¹\88ออภิà¸\9bรายà¸\81ารà¸\9aลà¹\87อà¸\81à¸\99ีà¹\89à¹\84à¸\94à¹\89
+คุณไม่สามารถใช้ 'ส่งอีเมลหาผู้ใช้รายนี้ได้' จนกว่าจะระบุที่อยู่อีเมลให้ถูกต้องใน[[Special:Preferences|การตั้งค่าบัญชี]]ของคุณ และคุณมิได้ถูกบล็อกไม่ให้ใช้ความสามารถนี
+เลขที่อยู่ไอพีปัจจุบันของคุณคือ $3 และหมายเลขการบล็อกคือ #$5 
¹\82à¸\9bรà¸\94à¹\81สà¸\94à¸\87รายละà¹\80อียà¸\94à¸\82à¹\89าà¸\87à¸\95à¹\89à¸\99à¸\97ัà¹\89à¸\87หมà¸\94à¸\99ีà¹\89à¹\83à¸\99à¸\81ารอภิà¸\9bรายà¹\80à¸\81ีà¹\88ยวà¸\81ัà¸\9aà¸\81ารà¸\9aลà¹\87อà¸\81à¸\82อà¸\87à¸\84ุà¸\93à¸\94à¹\89วย",
+'autoblockedtext' => "เลขที่อยู่ไอพีของคุณถูกบล็อกอัตโนมัติ เพราะมีผู้ใช้อื่นมาก่อน ซึ่งถูกบล็อกโดย $1
 เหตุผลที่ให้ไว้ในการบล็อกคือ:
 
-:\'\'$2\'\'
+:''$2''
 
 * เริ่มการบล็อก: $8
 * สิ้นสุดการบล็อก: $6
 * ผู้ถูกบล็อกโดยเจตนา: $7
 
-คุณอาจติดต่อ $1 หรือ[[{{MediaWiki:Grouppage-sysop}}|ผู้ดูแลระบบ]]คนอื่นเพื่อหารือเกี่ยวกับการบล็อกนี้
-
-โปรดทราบว่าคุณอาจไม่สามารถใช้คำสั่ง "อีเมลหาผู้ใช้นี้" หากคุณไม่มีที่อยู่อีเมลที่ถูกต้อง ดังที่ลงทะเบียนไว้ใน[[Special:Preferences|การตั้งค่าผู้ใช้]] และไม่ถูกบล็อกจากการใช้คำสั่งนี้
+คุณอาจติดต่อ $1 หรือ[[{{MediaWiki:Grouppage-sysop}}|ผู้ดูแลระบบ]]คนอื่นเพื่อหารือการบล็อกนี้
 
-หมายเลขไอพีปัจจุบันของคุณคือ $3 หมายเลขการบล็อกคือ #$5
-กรุณาระบุรายละเอียดทั้งหมดข้างต้นในการร้องขอใดๆ ที่คุณกระทำ',
+คุณสามารถติดต่อ $1 หรือ[[{{MediaWiki:Grouppage-sysop}}|ผู้ดูแลระบบ]]คนอื่นเพื่อหารือการบล็อกนี้ 
+คุณไม่สามารถใช้คุณลักษณะ 'ส่งอีเมลหาผู้ใช้รายนี้ได้' จนกว่าจะระบุที่อยู่อีเมลที่ถูกต้องใน[[Special:Preferences|การตั้งค่าบัญชี]]ของคุณ และคุณมิได้ถูกบล็อกไม่ให้
+เลขที่อยู่ไอพีปัจจุบันของคุณคือ $3 และหมายเลขการบล็อกคือ #$5 
+โปรดรวมรายละเอียดข้างต้นทั้งหมดในการสอบถามใด ๆ",
 'blockednoreason' => 'ไม่ได้ให้เหตุผลไว้',
 'whitelistedittext' => 'คุณต้อง$1เพื่อทำการแก้ไขหน้า',
 'confirmedittext' => 'คุณต้องยืนยันที่อยู่อีเมลของคุณก่อนแก้ไขหน้า โปรดกำหนดที่อยู่อีเมลของคุณและทำให้ถูกต้องผ่าน[[Special:Preferences|การตั้งค่าผู้ใช้]]',
@@ -931,6 +933,12 @@ $1 เป็นผู้ดำเนินการบล็อก
 เพราะมีหน้านี้แล้ว',
 'defaultmessagetext' => 'ข้อความสารโดยปริยาย',
 
+# Content models
+'content-model-wikitext' => 'ข้อความวิกิ',
+'content-model-text' => 'ข้อความธรรมดา',
+'content-model-javascript' => 'จาวาสคริปต์',
+'content-model-css' => 'CSS',
+
 # Parser/template warnings
 'expensive-parserfunction-warning' => "'''คำเตือน:''' หน้านี้มีการเรียกใช้ฟังก์ชันแจงส่วนมากเกินไป
 
@@ -1107,8 +1115,8 @@ $1",
 'mergehistory-fail' => 'ไม่สามารถรวมประวัติการแก้ไขได้ โปรดตรวจสอบค่าตัวแปรหน้าและเวลาอีกครั้ง',
 'mergehistory-no-source' => 'ไม่มีหน้าต้นทาง $1 อยู่ในสารบบ',
 'mergehistory-no-destination' => 'ไม่มีหน้าปลายทาง $1 อยู่ในสารบบ',
-'mergehistory-invalid-source' => 'หัวà¹\80รืà¹\88อà¸\87à¸\82อà¸\87หà¸\99à¹\89าà¸\95à¹\89à¸\99à¸\97าà¸\87à¸\95à¹\89อà¸\87à¸\95รà¸\87à¸\95ามà¸\82à¹\89อà¸\81ำหà¸\99à¸\94 (à¹\80à¸\8aà¹\88à¸\99 à¹\84มà¹\88มีà¸\95ัวอัà¸\81ษรà¸\97ีà¹\88à¹\84มà¹\88สามารà¸\96à¹\83à¸\8aà¹\89à¹\83à¸\99หัวà¹\80รืà¹\88อà¸\87à¹\84à¸\94à¹\89)',
-'mergehistory-invalid-destination' => 'หัวà¹\80รืà¹\88อà¸\87à¸\82อà¸\87หà¸\99à¹\89าà¸\9bลายà¸\97าà¸\87à¸\95à¹\89อà¸\87à¸\95รà¸\87à¸\95ามà¸\82à¹\89อà¸\81ำหà¸\99à¸\94 (à¹\80à¸\8aà¹\88à¸\99 à¹\84มà¹\88มีà¸\95ัวอัà¸\81ษรà¸\97ีà¹\88à¹\84มà¹\88สามารà¸\96à¹\83à¸\8aà¹\89à¹\83à¸\99หัวà¹\80รืà¹\88อà¸\87à¹\84à¸\94à¹\89)',
+'mergehistory-invalid-source' => 'หัวà¹\80รืà¹\88อà¸\87à¸\82อà¸\87หà¸\99à¹\89าà¸\95à¹\89à¸\99à¸\97าà¸\87à¸\95à¹\89อà¸\87สมà¹\80หà¸\95ุสมà¸\9cล',
+'mergehistory-invalid-destination' => 'à¸\8aืà¹\88อà¹\80รืà¹\88อà¸\87à¸\82อà¸\87หà¸\99à¹\89าà¸\9bลายà¸\97าà¸\87à¸\95à¹\89อà¸\87สมà¹\80หà¸\95ุสมà¸\9cล',
 'mergehistory-autocomment' => 'ย้าย [[:$1]] ไปยัง [[:$2]]',
 'mergehistory-comment' => 'ย้าย [[:$1]] ไปยัง [[:$2]]: $3',
 'mergehistory-same-destination' => 'หน้าต้นทางและปลายทางเป็นหน้าเดียวกันไม่ได้',
@@ -1139,8 +1147,8 @@ $1",
 'searchsubtitle' => 'คุณได้สืบค้นหา \'\'\'[[:$1]]\'\'\' ([[Special:Prefixindex/$1|ทุกหน้าที่ขึ้นต้นด้วย "$1"]]{{int:pipe-separator}}[[Special:WhatLinksHere/$1|ทุกหน้าที่โยงมาที่ "$1"]])',
 'searchsubtitleinvalid' => "ค้นหาเกี่ยวกับ '''$1'''",
 'toomanymatches' => 'พบตรงกันมากเกินไป กรุณาใช้คำค้นหาอื่น',
-'titlematches' => 'à¸\9eà¸\9aà¸\8aืà¹\88อหัวà¸\82à¹\89อà¸\99ีà¹\89',
-'notitlematches' => 'à¹\84มà¹\88à¸\9eà¸\9aà¸\8aืà¹\88อหัวà¸\82à¹\89อà¸\99ีà¹\89',
+'titlematches' => 'à¸\9eà¸\9aà¸\8aืà¹\88อà¹\80รืà¹\88อà¸\87หà¸\99à¹\89าà¸\95รà¸\87à¸\81ัà¸\99',
+'notitlematches' => 'à¹\84มà¹\88à¸\9eà¸\9aà¸\8aืà¹\88อà¹\80รืà¹\88อà¸\87หà¸\99à¹\89าà¸\95รà¸\87à¸\81ัà¸\99',
 'textmatches' => 'พบคำนี้ในหน้า',
 'notextmatches' => 'ไม่พบข้อความในหน้า',
 'prevn' => 'ก่อนหน้า $1',
@@ -1355,7 +1363,7 @@ $1",
 'group-all' => '(ทั้งหมด)',
 
 'group-user-member' => '{{GENDER:$1|ผู้ใช้ใหม่}}',
-'group-autoconfirmed-member' => 'ผู้ใช้ทั่วไป',
+'group-autoconfirmed-member' => '{{GENDER:$1|ผู้ใช้ทั่วไป}}',
 'group-bot-member' => '{{GENDER:$1|บอต}}',
 'group-sysop-member' => '{{GENDER:$1|ผู้ดูแลระบบ}}',
 'group-bureaucrat-member' => '{{GENDER:$1|ผู้ดูแลสิทธิแต่งตั้ง}}',
@@ -1653,8 +1661,12 @@ $1',
 'backend-fail-notexists' => 'ไม่พบไฟล์ $1 ที่ต้องการ',
 'backend-fail-delete' => 'ไม่สามารถลบไฟล์ $1 ได้',
 'backend-fail-alreadyexists' => 'มีไฟล์ "$1" อยู่แล้ว',
+'backend-fail-store' => 'ไม่สามารถเก็บไฟล์ "$1" ที่ "$2" ได้',
 'backend-fail-copy' => 'ไม่สามารถคัดลอกไฟล์ "$1" ไปยัง "$2" ได้',
 'backend-fail-move' => 'ไม่สามารถย้ายไฟล์ "$1" ไปยัง "$2" ได้',
+'backend-fail-opentemp' => 'ไม่สามารถเปิดไฟล์ชั่วคราวได้',
+'backend-fail-writetemp' => 'ไม่สามารถเขียนไฟล์ชั่วคราวได้',
+'backend-fail-closetemp' => 'ไม่สามารถปิดไฟล์ชั่วคราวได้',
 'backend-fail-read' => 'ไม่สามารถอ่านไฟล์ "$1" ได้',
 'backend-fail-create' => 'ไม่สามารถเขียนไฟล์ "$1" ได้',
 
@@ -1758,6 +1770,10 @@ $1',
 กรุณาดู [หน้าคำอธิบายของไฟล์ $2] สำหรับข้อมูลเพิ่มเติม',
 'sharedupload-desc-here' => 'ไฟล์นี้มาจาก $1 และอาจมีใช้ในโครงการอื่น
 คำอธิบายใน[$2 หน้าไฟล์]ได้แสดงไว้ข้างล่างนี้',
+'sharedupload-desc-edit' => 'ไฟล์นี้มาจาก $1 และอาจมีการใช้ไฟล์นี้ในโครงการอื่น ๆ อีก
+หากคุณต้องการแก้ไขคำอธิบาย ให้ดำเนินการ[$2 ที่นี่]',
+'sharedupload-desc-create' => 'ไฟล์นี้มาจาก $1 และอาจมีการใช้ไฟล์นี้ในโครงการอื่น ๆ อีก
+หากคุณต้องการแก้ไขคำอธิบาย ให้ดำเนินการ[$2 ที่นี่]',
 'filepage-nofile' => 'ไม่มีไฟล์ชื่อนี้',
 'filepage-nofile-link' => 'ไม่มีไฟล์ชื่อนี้ แต่คุณสามารถ[$1 อัปโหลด]ได้',
 'uploadnewversion-linktext' => 'อัปโหลดรุ่นใหม่ของไฟล์นี้',
@@ -1911,8 +1927,8 @@ $1',
 'protectedpages-cascade' => 'การล็อกแบบสืบทอดเท่านั้น',
 'protectedpagestext' => 'หน้าต่อไปนี้ถูกล็อกห้ามแก้ไขหรือเปลี่ยนชื่อ',
 'protectedpagesempty' => 'ไม่มีหน้าใดที่ถูกล็อกตามค่าที่เลือก',
-'protectedtitles' => 'หัวà¹\80รืà¹\88อà¸\87à¸\97ีà¹\88à¹\84à¸\94à¹\89รัà¸\9aà¸\81ารป้องกัน',
-'protectedtitlestext' => 'หัวà¹\80รืà¹\88อà¸\87à¸\95à¹\88อà¹\84à¸\9bà¸\99ีà¹\89à¹\84à¸\94à¹\89รัà¸\9aà¸\81ารป้องกันมิให้สร้าง',
+'protectedtitles' => 'à¸\8aืà¹\88อà¹\80รืà¹\88อà¸\87à¸\97ีà¹\88à¸\96ูà¸\81ป้องกัน',
+'protectedtitlestext' => 'à¸\8aืà¹\88อà¹\80รืà¹\88อà¸\87à¸\95à¹\88อà¹\84à¸\9bà¸\99ีà¹\89à¸\96ูà¸\81ป้องกันมิให้สร้าง',
 'protectedtitlesempty' => 'ปัจจุบันไม่มีหัวเรื่องที่ได้รับการป้องกันด้วยค่าต่อไปนี้',
 'listusers' => 'รายนามผู้ใช้',
 'listusers-editsonly' => 'แสดงเฉพาะผู้ใช้ที่มีการแก้ไข',
@@ -1949,7 +1965,7 @@ $1',
 'log' => 'ปูม',
 'all-logs-page' => 'ปูมสาธารณะทั้งหมด',
 'alllogstext' => 'การแสดงผลรวมปูมที่มีทั้งหมดของ {{SITENAME}}
-à¸\84ุà¸\93สามารà¸\96à¸\84à¹\89à¸\99หาà¹\83หà¹\89ละà¹\80อียà¸\94à¸\82ึà¹\89à¸\99à¹\82à¸\94ยà¹\80ลือà¸\81à¸\9bระà¹\80ภà¸\97à¸\9bูม à¸\8aืà¹\88อà¸\9cูà¹\89à¹\83à¸\8aà¹\89หรือหà¸\99à¹\89าà¸\97ีà¹\88à¸\95à¹\89อà¸\87à¸\81าร (ระวัà¸\87อัà¸\81ษรภาษาอัà¸\87à¸\81ฤษà¸\9eิมà¸\9eà¹\8cà¹\80ลà¹\87à¸\81à¹\83หà¸\8dà¹\88)',
+à¸\84ุà¸\93สามารà¸\96à¸\84à¹\89à¸\99หาà¹\83หà¹\89ละà¹\80อียà¸\94à¸\82ึà¹\89à¸\99à¹\82à¸\94ยà¹\80ลือà¸\81à¸\9bระà¹\80ภà¸\97à¸\9bูม à¸\8aืà¹\88อà¸\9cูà¹\89à¹\83à¸\8aà¹\89หรือหà¸\99à¹\89าà¸\97ีà¹\88à¸\95à¹\89อà¸\87à¸\81าร (à¹\84วà¸\95à¹\88ออัà¸\81ษรà¹\83หà¸\8dà¹\88à¹\80ลà¹\87à¸\81)',
 'logempty' => 'ไม่พบรายการตรงกันในปูม',
 'log-title-wildcard' => 'ค้นหาชื่อเรื่องด้วยคำขึ้นต้น',
 'showhideselectedlogentries' => 'แสดง/ซ่อนรายการปูมที่เลือก',
@@ -2223,7 +2239,7 @@ $UNWATCHURL
 'protect-summary-cascade' => 'สืบทอด',
 'protect-expiring' => 'หมดอายุ $1 (UTC)',
 'protect-expiring-local' => 'หมดอายุ $1',
-'protect-expiry-indefinite' => 'à¸\95ลอà¸\94à¸\81าล',
+'protect-expiry-indefinite' => 'à¹\84มà¹\88มีà¸\81ำหà¸\99à¸\94',
 'protect-cascade' => 'ล็อกหน้าที่เป็นส่วนหนึ่งของหน้านี้ (ล็อกแบบสืบทอด)',
 'protect-cantedit' => 'คุณไม่สามารถเปลี่ยนระดับการป้องกันของหน้านี้ เนื่องจากคุณไม่ได้รับสิทธิในการแก้ไขสิ่งนั้น',
 'protect-othertime' => 'ระยะเวลาอื่น:',
@@ -2237,7 +2253,7 @@ $UNWATCHURL
 ** สงครามการแก้ไขที่ไม่สร้างสรรค์
 ** หน้าที่มีการเข้าชมมาก',
 'protect-edit-reasonlist' => 'สาเหตุการป้องกันการแก้ไข',
-'protect-expiry-options' => '1 à¸\8aัà¹\88วà¹\82มà¸\87:1 hour,1 à¸§à¸±à¸\99:1 day,1 à¸ªà¸±à¸\9bà¸\94าหà¹\8c:1 week,2 à¸ªà¸±à¸\9bà¸\94าหà¹\8c:2 weeks,1 à¹\80à¸\94ือà¸\99:1 month,3 à¹\80à¸\94ือà¸\99:3 months,6 à¹\80à¸\94ือà¸\99:6 months,1 à¸\9bี:1 year,à¸\95ลอà¸\94à¸\81าล:infinite',
+'protect-expiry-options' => '1 à¸\8aัà¹\88วà¹\82มà¸\87:1 hour,1 à¸§à¸±à¸\99:1 day,1 à¸ªà¸±à¸\9bà¸\94าหà¹\8c:1 week,2 à¸ªà¸±à¸\9bà¸\94าหà¹\8c:2 weeks,1 à¹\80à¸\94ือà¸\99:1 month,3 à¹\80à¸\94ือà¸\99:3 months,6 à¹\80à¸\94ือà¸\99:6 months,1 à¸\9bี:1 year,à¹\84มà¹\88มีà¸\81ำหà¸\99à¸\94:infinite',
 'restriction-type' => 'อนุญาต',
 'restriction-level' => 'ระดับการล็อก',
 'minimum-size' => 'ขนาดอย่างน้อย',
@@ -2337,7 +2353,7 @@ $1',
 'sp-contributions-blocked-notice-anon' => 'ปัจจุบันเลขที่อยู่ไอพีนี้ถูกบล็อก
 ปูมการบล็อกล่าสุดแสดงด้านล่างนี้เพื่อการอ้างอิง:',
 'sp-contributions-search' => 'ค้นหาการแก้ไข',
-'sp-contributions-username' => 'หมายà¹\80ลà¸\82ไอพีหรือชื่อผู้ใช้:',
+'sp-contributions-username' => 'à¹\80ลà¸\82à¸\97ีà¹\88อยูà¹\88ไอพีหรือชื่อผู้ใช้:',
 'sp-contributions-toponly' => 'แสดงเฉพาะการแก้ไขรุ่นล่าสุด',
 'sp-contributions-submit' => 'สืบค้น',
 
@@ -2367,9 +2383,9 @@ $1',
 'blockip' => 'บล็อกผู้ใช้',
 'blockip-title' => 'ระงับผู้ใช้',
 'blockip-legend' => 'บล็อกผู้ใช้',
-'blockiptext' => 'à¹\83à¸\8aà¹\89à¹\81à¸\9aà¸\9aà¸\94à¹\89าà¸\99ลà¹\88าà¸\87à¹\80à¸\9eืà¹\88อà¸\9aลà¹\87อà¸\81สิà¸\97à¸\98ิà¹\80à¸\82à¹\89าà¸\96ึà¸\87à¸\81ารà¹\80à¸\82ียà¸\99à¸\82อà¸\87หมายà¹\80ลà¸\82ไอพีหรือชื่อผู้ใช้โดยเจาะจง การบล็อกนี้ควรดำเนินการเพื่อป้องกันการก่อกวนเท่านั้น และให้สอดคล้องกับ[[{{MediaWiki:Policy-url}}|นโยบาย]]
+'blockiptext' => 'à¹\83à¸\8aà¹\89à¹\81à¸\9aà¸\9aà¸\94à¹\89าà¸\99ลà¹\88าà¸\87à¹\80à¸\9eืà¹\88อà¸\9aลà¹\87อà¸\81สิà¸\97à¸\98ิà¹\80à¸\82à¹\89าà¸\96ึà¸\87à¸\81ารà¹\80à¸\82ียà¸\99à¸\82อà¸\87à¹\80ลà¸\82à¸\97ีà¹\88อยูà¹\88ไอพีหรือชื่อผู้ใช้โดยเจาะจง การบล็อกนี้ควรดำเนินการเพื่อป้องกันการก่อกวนเท่านั้น และให้สอดคล้องกับ[[{{MediaWiki:Policy-url}}|นโยบาย]]
 กรอกเหตุผลโดยเจาะจงด้านล่าง (เช่น อ้างถึงหน้าที่ถูกก่อกวน)',
-'ipadressorusername' => 'หมายà¹\80ลà¸\82ไอพีหรือชื่อผู้ใช้',
+'ipadressorusername' => 'à¹\80ลà¸\82à¸\97ีà¹\88อยูà¹\88ไอพีหรือชื่อผู้ใช้',
 'ipbexpiry' => 'หมดอายุ',
 'ipbreason' => 'เหตุผล:',
 'ipbreasonotherlist' => 'เลือกสาเหตุ',
@@ -2381,32 +2397,32 @@ $1',
 ** คุกคามผู้อื่น
 ** ก่อกวนผู้อื่น
 ** ชื่อผู้ใช้ที่ไม่สุภาพหรือไม่ควรใช้',
-'ipb-hardblock' => 'à¸\9bà¹\89อà¸\87à¸\81ัà¸\99à¹\84มà¹\88à¹\83หà¹\89à¸\9cูà¹\89à¹\83à¸\8aà¹\89ลà¹\87อà¸\81อิà¸\99à¹\81à¸\81à¹\89à¹\84à¸\82à¸\88าà¸\81หมายà¹\80ลà¸\82ไอพีนี้',
+'ipb-hardblock' => 'à¸\9bà¹\89อà¸\87à¸\81ัà¸\99à¹\84มà¹\88à¹\83หà¹\89à¸\9cูà¹\89à¹\83à¸\8aà¹\89ลà¹\87อà¸\81อิà¸\99à¹\81à¸\81à¹\89à¹\84à¸\82à¸\88าà¸\81à¹\80ลà¸\82à¸\97ีà¹\88อยูà¹\88ไอพีนี้',
 'ipbcreateaccount' => 'ป้องกันการสร้างบัญชี',
 'ipbemailban' => 'ป้องกันมิให้ผู้ใช้ส่งอีเมล',
-'ipbenableautoblock' => 'à¸\9aลà¹\87อà¸\81หมายà¹\80ลà¸\82à¹\84อà¸\9eีลà¹\88าสุà¸\94à¸\97ีà¹\88à¸\9cูà¹\89à¹\83à¸\8aà¹\89à¸\99ีà¹\89à¹\83à¸\8aà¹\89 à¸\97ัà¹\89à¸\87à¸\97ุà¸\81หมายà¹\80ลà¸\82ไอพีที่ผู้นั้นพยายามใช้แก้ไขโดยอัตโนมัติ',
+'ipbenableautoblock' => 'à¸\9aลà¹\87อà¸\81à¹\80ลà¸\82à¸\97ีà¹\88อยูà¹\88à¹\84อà¸\9eีลà¹\88าสุà¸\94à¸\97ีà¹\88à¸\9cูà¹\89à¹\83à¸\8aà¹\89à¸\99ีà¹\89à¹\83à¸\8aà¹\89 à¸\97ัà¹\89à¸\87à¸\97ุà¸\81à¹\80ลà¸\82à¸\97ีà¹\88อยูà¹\88ไอพีที่ผู้นั้นพยายามใช้แก้ไขโดยอัตโนมัติ',
 'ipbsubmit' => 'บล็อกผู้ใช้นี้',
 'ipbother' => 'เวลาอื่น',
-'ipboptions' => '2 à¸\8aัà¹\88วà¹\82มà¸\87:2 hours,1 à¸§à¸±à¸\99:1 day,3 à¸§à¸±à¸\99:3 days,1 à¸ªà¸±à¸\9bà¸\94าหà¹\8c:1 week,2 à¸ªà¸±à¸\9bà¸\94าหà¹\8c:2 weeks,1 à¹\80à¸\94ือà¸\99:1 month,3 à¹\80à¸\94ือà¸\99:3 months,6 à¹\80à¸\94ือà¸\99:6 months,1 à¸\9bี:1 year,à¸\95ลอà¸\94à¸\81าล:infinite',
+'ipboptions' => '2 à¸\8aัà¹\88วà¹\82มà¸\87:2 hours,1 à¸§à¸±à¸\99:1 day,3 à¸§à¸±à¸\99:3 days,1 à¸ªà¸±à¸\9bà¸\94าหà¹\8c:1 week,2 à¸ªà¸±à¸\9bà¸\94าหà¹\8c:2 weeks,1 à¹\80à¸\94ือà¸\99:1 month,3 à¹\80à¸\94ือà¸\99:3 months,6 à¹\80à¸\94ือà¸\99:6 months,1 à¸\9bี:1 year,à¹\84มà¹\88มีà¸\81ำหà¸\99à¸\94:infinite',
 'ipbotheroption' => 'เลือกเวลา',
 'ipbotherreason' => 'เหตุผลอื่น',
 'ipbhidename' => 'ซ่อนผู้ใช้จากปูมการบล็อก และรายการผู้ที่ถูกบล็อก',
 'ipbwatchuser' => 'เฝ้าดูหน้าผู้ใช้และหน้าคุยกับผู้ใช้ของผู้ใช้รายนี้',
-'ipb-disableusertalk' => 'à¸\9bà¹\89อà¸\87à¸\81ัà¸\99à¹\84มà¹\88à¹\83หà¹\89à¸\9cูà¹\89à¹\83à¸\8aà¹\89à¸\99ีà¹\89à¹\81à¸\81à¹\89à¹\84à¸\82หà¸\99à¹\89าà¸\9eูà¸\94à¸\84ุยของตัวเองขณะถูกบล็อก',
+'ipb-disableusertalk' => 'à¸\9bà¹\89อà¸\87à¸\81ัà¸\99à¹\84มà¹\88à¹\83หà¹\89à¸\9cูà¹\89à¹\83à¸\8aà¹\89à¸\99ีà¹\89à¹\81à¸\81à¹\89à¹\84à¸\82หà¸\99à¹\89าà¸\84ุยà¸\81ัà¸\9aà¸\9cูà¹\89à¹\83à¸\8aà¹\89ของตัวเองขณะถูกบล็อก',
 'ipb-change-block' => 'บล็อกผู้ใช้อีกครั้งด้วยการตั้งค่าเหล่านี้',
 'ipb-confirm' => 'ยืนยันการบล็อก',
-'badipaddress' => 'หมายà¹\80ลà¸\82ไอพีไม่ถูกต้อง',
+'badipaddress' => 'à¹\80ลà¸\82à¸\97ีà¹\88อยูà¹\88ไอพีไม่ถูกต้อง',
 'blockipsuccesssub' => 'บล็อกสำเร็จ',
 'blockipsuccesstext' => '[[Special:Contributions/$1|$1]] ถูกบล็อก<br />
 ดู[[Special:BlockList|รายการบล็อก]]เพื่อทบทวนการบล็อก',
-'ipb-blockingself' => 'à¸\84ุà¸\93à¸\81ำลัà¸\87à¸\97ำà¸\81ารà¸\9aลà¹\87อà¸\81à¸\95ัวà¸\84ุà¸\93à¹\80อà¸\87 à¸\84ุà¸\93à¹\81à¸\99à¹\88à¹\83à¸\88à¹\81ลà¹\89วหรือวà¹\88าà¸\95à¹\89อà¸\87à¸\81ารà¸\97ำà¹\80à¸\8aà¹\88à¸\99นั้น',
+'ipb-blockingself' => 'à¸\84ุà¸\93à¸\81ำลัà¸\87à¸\9aลà¹\87อà¸\81à¸\95ัวà¹\80อà¸\87! à¹\81à¸\99à¹\88à¹\83à¸\88à¹\81ลà¹\89วหรือวà¹\88าà¸\95à¹\89อà¸\87à¸\81ารà¸\97ำอยà¹\88าà¸\87นั้น',
 'ipb-edit-dropdown' => 'แก้ไขสาเหตุการบล็อก',
 'ipb-unblock-addr' => 'เลิกบล็อก $1',
-'ipb-unblock' => 'à¹\80ลิà¸\81à¸\9aลà¹\87อà¸\81à¸\9cูà¹\89à¹\83à¸\8aà¹\89หรือหมายà¹\80ลà¸\82ไอพี',
+'ipb-unblock' => 'à¹\80ลิà¸\81à¸\9aลà¹\87อà¸\81à¸\9cูà¹\89à¹\83à¸\8aà¹\89หรือà¹\80ลà¸\82à¸\97ีà¹\88อยูà¹\88ไอพี',
 'ipb-blocklist' => 'ดูการบล็อกปัจจุบัน',
 'ipb-blocklist-contribs' => 'ผลงานเขียนโดย $1',
 'unblockip' => 'ปลดบล็อกผู้ใช้',
-'unblockiptext' => 'à¹\83à¸\8aà¹\89à¹\81à¸\9aà¸\9aà¸\94à¹\89าà¸\99ลà¹\88าà¸\87สำหรัà¸\9aà¸\84ืà¸\99สิà¸\97à¸\98ิà¸\81ารà¹\80à¸\82à¹\89าà¸\96ึà¸\87à¸\81ารà¹\80à¸\82ียà¸\99à¹\81à¸\81à¹\88หมายà¹\80ลà¸\82ไอพี หรือชื่อผู้ใช้ที่เคยถูกบล็อก',
+'unblockiptext' => 'à¹\83à¸\8aà¹\89à¹\81à¸\9aà¸\9aà¸\94à¹\89าà¸\99ลà¹\88าà¸\87สำหรัà¸\9aà¸\84ืà¸\99สิà¸\97à¸\98ิà¸\81ารà¹\80à¸\82à¹\89าà¸\96ึà¸\87à¸\81ารà¹\80à¸\82ียà¸\99à¹\81à¸\81à¹\88à¹\80ลà¸\82à¸\97ีà¹\88อยูà¹\88ไอพี หรือชื่อผู้ใช้ที่เคยถูกบล็อก',
 'ipusubmit' => 'ยกเลิกการบล็อกนี้',
 'unblocked' => '[[User:$1|$1]] ถูกบล็อก',
 'unblocked-range' => '$1 ถูกปลดบล็อกแล้ว',
@@ -2426,7 +2442,7 @@ $1',
 'ipblocklist-submit' => 'สืบค้น',
 'ipblocklist-localblock' => 'การสกัดกั้นภายในวิกินี้',
 'ipblocklist-otherblocks' => '{{PLURAL:$1|การสกัดกั้น}}อื่นๆ',
-'infiniteblock' => 'à¸\95ลอà¸\94à¸\81าล',
+'infiniteblock' => 'à¹\84มà¹\88มีà¸\81ำหà¸\99à¸\94',
 'expiringblock' => 'หมดอายุ $1 เวลา $2',
 'anononlyblock' => 'ไม่ล็อกอินเท่านั้น',
 'noautoblockblock' => 'ยกเลิกการบล็อกอัตโนมัติ',
@@ -2434,13 +2450,13 @@ $1',
 'emailblock' => 'บล็อกการส่งอีเมล',
 'blocklist-nousertalk' => 'ไม่สามารถแก้ไขหน้าอภิปรายของตนเอง',
 'ipblocklist-empty' => 'รายการบล็อกว่าง',
-'ipblocklist-no-results' => 'หมายà¹\80ลà¸\82ไอพีหรือชื่อผู้ใช้ที่ต้องการไม่ได้ถูกบล็อก',
+'ipblocklist-no-results' => 'à¹\80ลà¸\82à¸\97ีà¹\88อยูà¹\88ไอพีหรือชื่อผู้ใช้ที่ต้องการไม่ได้ถูกบล็อก',
 'blocklink' => 'บล็อก',
 'unblocklink' => 'เลิกบล็อก',
 'change-blocklink' => 'เปลี่ยนการบล็อก',
 'contribslink' => 'เรื่องที่เขียน',
 'emaillink' => 'ส่งอีเมล',
-'autoblocker' => 'à¸\96ูà¸\81à¸\9aลà¹\87อà¸\81อัà¸\95à¹\82à¸\99มัà¸\95ิà¹\80à¸\99ืà¹\88อà¸\87à¸\88าà¸\81หมายà¹\80ลà¸\82ไอพีของคุณล่าสุดถูกใช้โดย "[[User:$1|$1]]" เหตุผลที่ให้แก่การบล็อก $1 คือ: "$2"',
+'autoblocker' => 'à¸\96ูà¸\81à¸\9aลà¹\87อà¸\81อัà¸\95à¹\82à¸\99มัà¸\95ิà¹\80à¸\99ืà¹\88อà¸\87à¸\88าà¸\81à¹\80ลà¸\82à¸\97ีà¹\88อยูà¹\88ไอพีของคุณล่าสุดถูกใช้โดย "[[User:$1|$1]]" เหตุผลที่ให้แก่การบล็อก $1 คือ: "$2"',
 'blocklogpage' => 'ปูมการบล็อก',
 'blocklog-showlog' => 'ผู้ใช้นี้ถูกสกัดกั้นมาก่อน
 ปูมการสกัดกั้นแสดงไว้ด้านล่างนี้เพื่อการอ้างอิง:',
@@ -2468,16 +2484,16 @@ $1',
 'ipb-otherblocks-header' => '{{PLURAL:$1|การบล็อก}}อื่น ๆ',
 'unblock-hideuser' => 'คุณไม่สามารถยกเลิกการบล็อคผู้ใช้งานรายนี้ได้, เนื่องจากชื่อผู้ใช้ของผู้ใช้งานถูกซ่อนอยู่',
 'ipb_cant_unblock' => 'ปัญหา: หมายเลขบล็อก $1 ไม่พบ อาจเกิดจากได้ถูกยกเลิกการบล็อกแล้ว',
-'ipb_blocked_as_range' => 'มีà¸\82à¹\89อà¸\9cิà¸\94à¸\9eลาà¸\94: à¸«à¸¡à¸²à¸¢à¹\80ลà¸\82à¹\84อà¸\9eี $1 à¹\84มà¹\88à¹\84à¸\94à¹\89à¸\96ูà¸\81ระà¸\87ัà¸\9aà¹\82à¸\94ยà¸\95รà¸\87à¹\81ละà¹\84มà¹\88สามารà¸\96ยà¸\81à¹\80ลิà¸\81à¸\81ารระà¸\87ัà¸\9aà¹\82à¸\94ยà¸\95รà¸\87à¹\84à¸\94à¹\89.  à¸­à¸¢à¹\88าà¸\87à¹\84รà¸\81à¹\87à¸\95าม à¹\84อà¸\9eีà¸\99ีà¹\89à¸\96ูà¸\81ระà¸\87ัà¸\9aà¹\83à¸\99à¸\90าà¸\99ะà¸\97ีà¹\88à¹\80à¸\9bà¹\87à¸\99สà¹\88วà¸\99หà¸\99ึà¹\88à¸\87à¸\82อà¸\87หมายà¹\80ลà¸\82à¹\84อà¸\9eีà¹\83à¸\99à¸\8aà¹\88วà¸\87 $2 ซึ่งสามารถยกเลิกการระงับได้',
-'ip_range_invalid' => 'à¸\8aà¹\88วà¸\87ไอพีไม่ถูกต้อง',
+'ipb_blocked_as_range' => 'มีà¸\82à¹\89อà¸\9cิà¸\94à¸\9eลาà¸\94: à¹\80ลà¸\82à¸\97ีà¹\88อยูà¹\88à¹\84อà¸\9eี $1 à¹\84มà¹\88à¹\84à¸\94à¹\89à¸\96ูà¸\81ระà¸\87ัà¸\9aà¹\82à¸\94ยà¸\95รà¸\87à¹\81ละà¹\84มà¹\88สามารà¸\96ยà¸\81à¹\80ลิà¸\81à¸\81ารระà¸\87ัà¸\9aà¹\82à¸\94ยà¸\95รà¸\87à¹\84à¸\94à¹\89.  à¸­à¸¢à¹\88าà¸\87à¹\84รà¸\81à¹\87à¸\95าม à¹\84อà¸\9eีà¸\99ีà¹\89à¸\96ูà¸\81ระà¸\87ัà¸\9aà¹\83à¸\99à¸\90าà¸\99ะà¸\97ีà¹\88à¹\80à¸\9bà¹\87à¸\99สà¹\88วà¸\99หà¸\99ึà¹\88à¸\87à¸\82อà¸\87à¹\80ลà¸\82à¸\97ีà¹\88อยูà¹\88à¹\84อà¸\9eีà¹\83à¸\99à¸\9eิสัย $2 ซึ่งสามารถยกเลิกการระงับได้',
+'ip_range_invalid' => 'à¸\9eิสัยไอพีไม่ถูกต้อง',
 'ip_range_toolarge' => 'ขนาดบล็อกมีขนาดใหญ่กว่า / $1 จะไม่ได้รับอนุญาต',
 'blockme' => 'บล็อกฉัน',
 'proxyblocker' => 'บล็อกพร็อกซี',
 'proxyblocker-disabled' => 'ฟังก์ชั่นนี้ไม่สามารถใช้ได้',
-'proxyblockreason' => 'หมายà¹\80ลà¸\82ไอพีของคุณถูกบล็อกเนื่องจากเป็นพร็อกซีเปิด กรุณาติดต่อผู้ให้บริการอินเทอร์เน็ตที่คุณใช้งานอยู่เกี่ยวกับปัญหานี้',
+'proxyblockreason' => 'à¹\80ลà¸\82à¸\97ีà¹\88อยูà¹\88ไอพีของคุณถูกบล็อกเนื่องจากเป็นพร็อกซีเปิด กรุณาติดต่อผู้ให้บริการอินเทอร์เน็ตที่คุณใช้งานอยู่เกี่ยวกับปัญหานี้',
 'proxyblocksuccess' => 'บล็อกสำเร็จ',
-'sorbsreason' => 'หมายà¹\80ลà¸\82ไอพีของคุณอยู่ในพร็อกซีเปิดในส่วน DNSBL ที่ถูกใช้งานในเว็บไซต์',
-'sorbs_create_account_reason' => 'หมายà¹\80ลà¸\82ไอพีของคุณอยู่ในพร็อกซีเปิดในส่วน DNSBL ที่ถูกใช้งานในเว็บไซต์ ดังนั้นคุณไม่สามารถสร้างชื่อบัญชีผู้ใช้ได้',
+'sorbsreason' => 'à¹\80ลà¸\82à¸\97ีà¹\88อยูà¹\88ไอพีของคุณอยู่ในพร็อกซีเปิดในส่วน DNSBL ที่ถูกใช้งานในเว็บไซต์',
+'sorbs_create_account_reason' => 'à¹\80ลà¸\82à¸\97ีà¹\88อยูà¹\88ไอพีของคุณอยู่ในพร็อกซีเปิดในส่วน DNSBL ที่ถูกใช้งานในเว็บไซต์ ดังนั้นคุณไม่สามารถสร้างชื่อบัญชีผู้ใช้ได้',
 'cant-block-while-blocked' => 'คุณไม่สามารถบล็อกผู้ใช้อื่นในขณะที่คุณกำลังถูกบล็อก',
 'cant-see-hidden-user' => 'ผู้ใช้ที่คุณกำลังพยายามระงับนั้นได้ถูกระงับหรือซ่อนเดิมอยู่แล้ว เนื่องจากคุณไม่มีสิทธิซ่อนผู้ใช้ คุณจึงไม่สามารถดูหรือแก้ไขการระงับผู้ใช้ได้',
 'ipbblocked' => 'คุณไม่สามารถบล็อกหรือปลดบล็อกผู้ใช้คนอื่น เนื่องจากคุณกำลังถูกบล็อก',
@@ -2594,9 +2610,9 @@ $1',
 
 # Export
 'export' => 'ส่งออกหน้า',
-'exporttext' => 'คุณสามารถส่งออก (export) ข้อความต้นฉบับและประวัติการแก้ไขของหน้าใดๆ มากกว่าหนึ่งหน้าในคราวเดียว ออกมาในรูปแบบ XML ซึ่งสามารถนำไปใส่เข้าไว้ในเว็บไซต์วิกิแห่งอื่นที่ใช้ซอฟต์แวร์มีเดียวิกิได้ ผ่านทางคำสั่ง[[Special:Import|การนำเข้าหน้า]]
+'exporttext' => 'คุณสามารถส่งออกข้อความและประวัติการแก้ไขของหน้าใด ๆ หรือชุดหน้าในคราวเดียว ออกมาในรูปแบบ XML ซึ่งสามารถนำไปใส่เข้าไว้ในวิกิแห่งอื่นที่ใช้ซอฟต์แวร์มีเดียวิกิได้ ผ่านคำสั่ง[[Special:Import|การนำเข้าหน้า]]
 
-à¸\81ารà¸\88ะสà¹\88à¸\87ออà¸\81หà¸\99à¹\89าà¸\99ัà¹\89à¸\99สามารà¸\96à¸\97ำà¹\84à¸\94à¹\89à¹\82à¸\94ยà¹\83สà¹\88à¸\8aืà¹\88อหัวà¹\80รืà¹\88อà¸\87à¸\82อà¸\87หà¸\99à¹\89าà¸\97ีà¹\88à¸\95à¹\89อà¸\87à¸\81าร à¸¥à¸\87à¹\83à¸\99à¸\81ลà¹\88อà¸\87à¸\82à¹\89อà¸\84วามà¸\94à¹\89าà¸\99ลà¹\88าà¸\87 à¸«à¸\99ึà¹\88à¸\87à¸\8aืà¹\88อà¸\95à¹\88อหà¸\99ึà¹\88à¸\87à¸\9aรรà¸\97ัà¸\94 à¸\88าà¸\81à¸\99ัà¹\89à¸\99à¹\80ลือà¸\81วà¹\88าà¸\95à¹\89อà¸\87à¸\81ารà¸\97ัà¹\89à¸\87รุà¹\88à¸\99à¸\9bัà¸\88à¸\88ุà¸\9aัà¸\99à¹\81ละรุà¹\88à¸\99à¹\80à¸\81à¹\88าà¹\86 à¸\97ัà¹\89à¸\87หมà¸\94à¸\9eรà¹\89อมà¸\81ัà¸\9aà¸\9bระวัà¸\95ิà¸\82อà¸\87หà¸\99à¹\89าà¸\99ัà¹\89à¸\99 à¸«à¸£à¸·à¸­à¸\95à¹\89อà¸\87à¸\81ารà¹\80à¸\9eียà¸\87à¹\81à¸\95à¹\88à¹\80à¸\99ืà¹\89อหารุà¹\88à¸\99à¸\9bัà¸\88à¸\88ุà¸\9aัà¸\99à¸\9eรà¹\89อมà¸\81ัà¸\9aรายละà¹\80อียà¸\94à¸\82อà¸\87รุà¹\88à¸\99à¸\99ัà¹\89à¸\99เท่านั้น
+à¸\81ารà¸\88ะสà¹\88à¸\87ออà¸\81หà¸\99à¹\89าà¸\99ัà¹\89à¸\99สามารà¸\96à¸\97ำà¹\84à¸\94à¹\89à¹\82à¸\94ยà¹\83สà¹\88à¸\8aืà¹\88อà¹\80รืà¹\88อà¸\87หà¸\99à¹\89าà¸\97ีà¹\88à¸\95à¹\89อà¸\87à¸\81าร à¸¥à¸\87à¹\83à¸\99à¸\81ลà¹\88อà¸\87à¸\82à¹\89อà¸\84วามà¸\94à¹\89าà¸\99ลà¹\88าà¸\87 à¸«à¸\99ึà¹\88à¸\87à¸\8aืà¹\88อà¸\95à¹\88อหà¸\99ึà¹\88à¸\87à¸\9aรรà¸\97ัà¸\94 à¸\88าà¸\81à¸\99ัà¹\89à¸\99à¹\80ลือà¸\81วà¹\88าà¸\95à¹\89อà¸\87à¸\81ารà¸\97ัà¹\89à¸\87รุà¹\88à¸\99à¸\9bัà¸\88à¸\88ุà¸\9aัà¸\99à¹\81ละรุà¹\88à¸\99à¹\80à¸\81à¹\88าà¸\97ัà¹\89à¸\87หมà¸\94à¸\9eรà¹\89อมà¸\81ัà¸\9aà¸\9bระวัà¸\95ิà¸\82อà¸\87หà¸\99à¹\89าà¸\99ัà¹\89à¸\99 à¸«à¸£à¸·à¸­à¸\95à¹\89อà¸\87à¸\81ารà¹\80à¸\9eียà¸\87à¹\80à¸\99ืà¹\89อหารุà¹\88à¸\99à¸\9bัà¸\88à¸\88ุà¸\9aัà¸\99à¸\9eรà¹\89อมà¸\81ัà¸\9aสารสà¸\99à¹\80à¸\97ศà¸\82อà¸\87à¸\81ารà¹\81à¸\81à¹\89à¹\84à¸\82à¸\84รัà¹\89à¸\87สุà¸\94à¸\97à¹\89ายเท่านั้น
 
 ในกรณีที่ต้องการเฉพาะรุ่นปัจจุบัน คุณสามารถใช้ในรูปแบบของลิงก์ เช่น [[{{#Special:Export}}/{{MediaWiki:Mainpage}}]] สำหรับหน้า "[[{{MediaWiki:Mainpage}}]]"',
 'exportall' => 'ส่งออกข้อมูลทุกหน้า',
@@ -2852,6 +2868,7 @@ $1',
 'pageinfo-redirectsto' => 'เปลี่ยนทางไปยัง',
 'pageinfo-contentpage' => 'นับเป็นหน้าเนื้อหา',
 'pageinfo-contentpage-yes' => 'ใช่',
+'pageinfo-protect-cascading-yes' => 'ใช่',
 'pageinfo-category-info' => 'ข้อมูลหมวดหมู่',
 'pageinfo-category-pages' => 'จำนวนหน้า',
 'pageinfo-category-subcats' => 'จำนวนหมวดหมู่ย่อย',
@@ -2881,7 +2898,7 @@ $1',
 
 # Patrol log
 'patrol-log-page' => 'ปูมการตรวจสอบ',
-'patrol-log-header' => 'หà¸\99à¹\89าà¸\99ีà¹\89à¸\84ือà¸\9aัà¸\99à¸\97ึà¸\81รุ่นการแก้ไขที่กำหนดว่าตรวจสอบแล้ว',
+'patrol-log-header' => 'หà¸\99à¹\89าà¸\99ีà¹\89à¸\84ือà¸\9bูมรุ่นการแก้ไขที่กำหนดว่าตรวจสอบแล้ว',
 'log-show-hide-patrol' => '$1 ปูมการตรวจสอบ',
 
 # Image deletion
@@ -2910,6 +2927,7 @@ $1',
 'file-info-size-pages' => '$1 × $2 พิกเซล, ขนาดไฟล์: $3, ประเภท MIME: $4, $5 {{PLURAL:$5|หน้า|หน้า}}',
 'file-nohires' => 'ไม่มีความละเอียดสูงกว่านี้',
 'svg-long-desc' => 'ไฟล์ SVG, $1 × $2 พิกเซล พอเป็นพิธี, ขนาดไฟล์: $3',
+'svg-long-error' => 'ไฟล์ SVG ไม่ถูกต้อง: $1',
 'show-big-image' => 'ความละเอียดสูงสุด',
 'show-big-image-other' => 'อื่นๆ {{PLURAL:$2|resolution|resolutions}}: $1.',
 'show-big-image-size' => '$1 × $2 พิกเซล',
index e9d5c1b..bb33363 100644 (file)
@@ -784,7 +784,7 @@ $messages = array(
 'emailuser' => 'Номә бә иштирокәкә',
 
 # Watchlist
-'watchlist' => 'ЧÑ\8bмÑ\8b Ð½оғо доә сијоһи',
+'watchlist' => 'Ð\9dоғо доә сијоһи',
 'mywatchlist' => 'Чәшәвәно кардә сијоһи',
 'watchlistfor2' => 'Бо $1 $2',
 'watch' => 'Думотоно егыниеј',
index 20d4160..99682ec 100644 (file)
@@ -776,7 +776,7 @@ Tarayıcınızın önbelleğini temizleyene kadar bazı sayfalar sanki hâlâ ot
 'gotaccount' => "Çoktan kayıt oldunuz mu? '''$1'''.",
 'gotaccountlink' => 'Oturum açın',
 'userlogin-resetlink' => 'Giriş bilgilerinizi mi unuttunuz?',
-'createaccountmail' => 'e-posta ile',
+'createaccountmail' => 'Geçici bir rastgele şifre kullan ve şifreyi aşağıda belirtilen e-posta adresine gönder',
 'createaccountreason' => 'Sebep:',
 'badretype' => 'Girdiğiniz şifreler birbirleriyle uyuşmuyor.',
 'userexists' => 'Girdiğiniz kullanıcı adı zaten kullanımda.
@@ -907,6 +907,7 @@ Geçici şifre: $2',
 'changeemail-oldemail' => 'Mevcut E-posta adresi:',
 'changeemail-newemail' => 'Yeni E-posta adresi:',
 'changeemail-none' => '(yok)',
+'changeemail-password' => '{{SITENAME}} parolanız:',
 'changeemail-submit' => "E-posta'yı değiştir",
 'changeemail-cancel' => 'İptal',
 
@@ -1058,9 +1059,10 @@ Ayrıca buraya katkıda bulunarak, bu katkının kendiniz tarafından yazıldı
 Ayrıca bu ekleyeceğiniz yazıyı sizin yazdığınızı ya da serbest kopyalama izni veren bir kaynaktan kopyaladığınızı bize taahhüt etmektesiniz (ayrıntılar için referans: $1).',
 'longpageerror' => "'''Hata: Girdiğiniz metnin uzunluğu kabul edilebilir en fazla uzunluk olan {{PLURAL:$2|bir kilobayt|$2 kilobayt}}tan fazladır ve {{PLURAL:$1|bir kilobayt|$1 kilobayt}} büyüklüğündedir.'''
 Değişikliğiniz kaydedilemez.",
-'readonlywarning' => "'''DİKKAT: Bakım nedeni ile veritabanı şu anda kilitlidir. Bu sebeple değişiklikleriniz şu anda kaydedilememektedir. Yazdıklarınızı başka bir editöre alıp saklayabilir ve daha sonra tekrar buraya getirip kaydedebilirsiniz'''
+'readonlywarning' => "'''Uyarı: Bakım nedeniyle veritabanı şu anda kilitlenmiştir. Bu yüzden şu anda düzenlemelerinizi kaydetmek mümkün değildir.''' 
+Yaptığınız düzenlemeleri daha sonra kaydetmek isterseniz, yaptığınız düzenlemeleri bir metin dosyasına ya da herhangi bir şeye kopyala yapıştır yaparak saklayınız.
 
-Kilitleyen hizmetli şu açıklamayı eklemiştir: $1",
+Kilitlemeyi yapan yetkili şu açıklamayı eklemiştir: $1",
 'protectedpagewarning' => "'''Uyarı: Bu sayfa koruma altına alınmıştır ve yalnızca hizmetli olanlar tarafından değiştirilebilir.'''
 Son günlük girdisi referans amaçlı aşağıda verilmiştir:",
 'semiprotectedpagewarning' => "'''Not:''' Bu sayfa sadece kayıtlı kullanıcı olanlar tarafından değiştirilebilir.
@@ -2205,7 +2207,7 @@ Ayrıca [[Special:WantedCategories|İstenen kategoriler]]'e bakınız.",
 'linksearch-ok' => 'Ara',
 'linksearch-text' => '"*.wikipedia.org" gibi jokerler kullanılabilir.
 En az bir üst-seviye alan gerekir, örneğin "*.org".<br />
-Desteklenen iletişim kuralları: <code>$1</code> (bunların hiçbirini aramanıza eklemeyin).',
+Desteklenen {{PLURAL:$2|iletişim kuralı|iletişim kuralları}}: <code>$1</code> (herhangi bir iletişim kuralı belirtmezseniz http:// otomatik olarak eklenir).',
 'linksearch-line' => "$1'e $2'den bağlantı verilmiş",
 'linksearch-error' => 'Jokerler sadece ana makine adının başında görünebilir.',
 
@@ -2218,7 +2220,7 @@ Desteklenen iletişim kuralları: <code>$1</code> (bunların hiçbirini aramanı
 # Special:ActiveUsers
 'activeusers' => 'Aktif kullanıcı listesi',
 'activeusers-intro' => 'Bu, son $1 {{PLURAL:$1|günde|günde}} bir çeşit etkinlik göstermiş kullanıcıların listesidir.',
-'activeusers-count' => 'Son {{PLURAL:$3|günde|$3 günde}} $1 {{PLURAL:$1|değişiklik|değişiklik}}',
+'activeusers-count' => 'Son {{PLURAL:$3|günde|$3 günde}} $1 {{PLURAL:$1|eylem|eylem}}',
 'activeusers-from' => 'Şununla başlayan kullanıcıları görüntüle:',
 'activeusers-hidebots' => 'Botları gizle',
 'activeusers-hidesysops' => 'Yöneticileri gizle',
@@ -2250,8 +2252,8 @@ Bireysel haklarla ilgili [[{{MediaWiki:Listgrouprights-helppage}}|daha fazla bil
 'emailuser-title-target' => 'Bu {{GENDER:$1|kullanıcıya}} e-posta gönder',
 'emailuser-title-notarget' => 'Kullanıcı e-posta',
 'emailpage' => 'Kullanıcıya e-posta gönder',
-'emailpagetext' => 'Bu kullanıcıya e-posta mesajı göndermek için aşağıdaki formu kullanabilirsiniz.
-[[Special:Preferences|Kullanıcı tercihlerinizde]] girdiğiniz e-posta adresiniz, e-postanın "From (Kimden)" adresinde görünecektir, bu yüzden alıcı size direk cevap verebilecektir.',
+'emailpagetext' => 'Bu {{GENDER:$1|kullanıcıya}} e-posta iletisi göndermek için aşağıdaki formu kullanabilirsiniz.
+[[Special:Preferences|Kullanıcı tercihlerinizde]] girdiğiniz e-posta adresiniz, e-postanın "From (Kimden)" adresinde görünecektir, bu yüzden alıcı size doğrudan yanıt verebilecektir.',
 'usermailererror' => 'E-posta hizmeti hata verdi:',
 'defemailsubject' => '"$1" kullanıcısından {{SITENAME}} e-postası',
 'usermaildisabled' => 'Kullanıcı e-postası devre dışı',
@@ -2281,7 +2283,7 @@ Bireysel haklarla ilgili [[{{MediaWiki:Listgrouprights-helppage}}|daha fazla bil
 'usermessage-editor' => 'Sistem habercisi',
 
 # Watchlist
-'watchlist' => 'İzleme listem',
+'watchlist' => 'İzleme listesi',
 'mywatchlist' => 'İzleme listesi',
 'watchlistfor2' => '$1 için $2',
 'nowatchlist' => 'İzleme listesinde hiçbir madde bulunmuyor.',
@@ -2289,13 +2291,8 @@ Bireysel haklarla ilgili [[{{MediaWiki:Listgrouprights-helppage}}|daha fazla bil
 'watchnologin' => 'Oturum açık değil.',
 'watchnologintext' => 'İzleme listenizi değiştirebilmek için [[Special:UserLogin|oturum açmalısınız]].',
 'addwatch' => 'İzleme listesine ekle',
-'addedwatchtext' => '"<nowiki>$1</nowiki>" adlı sayfa [[Special:Watchlist|izleme listenize]] kaydedildi.
-
-Gelecekte, bu sayfaya ve ilgili tartışma sayfasına yapılacak değişiklikler burada listelenecektir.
-
-Kolayca seçilebilmeleri için de [[Special:RecentChanges|son değişiklikler listesi]] başlığı altında koyu harflerle listeleneceklerdir.
-
-Sayfayı izleme listenizden çıkarmak istediğinizde "sayfayı izlemeyi durdur" bağlantısına tıklayabilirsiniz.',
+'addedwatchtext' => '"[[:$1]]" sayfası [[Special:Watchlist|izleme listenize]] eklenmiştir.
+Bundan sonra, bu sayfaya ve ilgili tartışma sayfasına yapılacak değişiklikler burada listelenecek.',
 'removewatch' => 'İzleme listesinden kaldır',
 'removedwatchtext' => '"[[:$1]]" sayfası [[Special:Watchlist|izleme listenizden]] silinmiştir.',
 'watch' => 'İzle',
@@ -2324,30 +2321,41 @@ Sayfayı izleme listenizden çıkarmak istediğinizde "sayfayı izlemeyi durdur"
 'enotif_mailer' => '{{SITENAME}} Bildirim Postası',
 'enotif_reset' => 'Tüm sayfaları ziyaret edilmiş olarak işaretle',
 'enotif_impersonal_salutation' => '{{SITENAME}} kullanıcı',
+'enotif_subject_deleted' => '{{SITENAME}} sayfası $1, $2 tarafından {{GENDER:$2|silindi}}.',
+'enotif_subject_created' => '{{SITENAME}} sayfası $1, $2 tarafından {{GENDER:$2|açıldı}}.',
+'enotif_subject_moved' => '{{SITENAME}} sayfası $1, $2 tarafından {{GENDER:$2|taşındı}}.',
+'enotif_subject_restored' => '{{SITENAME}} sayfası $1, $2 tarafından {{GENDER:$2|geri getirildi}}.',
+'enotif_subject_changed' => '{{SITENAME}} sayfası $1, $2 tarafından {{GENDER:$2|değiştirildi}}.',
+'enotif_body_intro_deleted' => '{{SITENAME}} sayfası $1, $2 tarafından $PAGEEDITDATE tarihinde {{GENDER:$2|silindi}}, bakınız: $3.',
+'enotif_body_intro_created' => '{{SITENAME}} sayfası $1, $2 tarafından $PAGEEDITDATE tarihinde {{GENDER:$2|açıldı}}, mevcut revizyon için bakınız: $3.',
+'enotif_body_intro_moved' => '{{SITENAME}} sayfası $1, $2 tarafından $PAGEEDITDATE tarihinde {{GENDER:$2|taşındı}}, mevcut revizyon için bakınız: $3.',
+'enotif_body_intro_restored' => '{{SITENAME}} sayfası $1, $2 tarafından $PAGEEDITDATE tarihinde {{GENDER:$2|geri getirildi}}, mevcut revizyon için bakınız: $3.',
+'enotif_body_intro_changed' => '{{SITENAME}} sayfası $1, $2 tarafından $PAGEEDITDATE tarihinde {{GENDER:$2|değiştirildi}}, mevcut revizyon için bakınız: $3.',
 'enotif_lastvisited' => "Son ziyaretinizden bu yana olan tüm değişiklikleri görmek için $1'e bakın.",
 'enotif_lastdiff' => 'Bu değişikliği görmek için, $1 sayfasına bakınız.',
 'enotif_anon_editor' => 'anonim kullanıcı $1',
 'enotif_body' => 'Sayın $WATCHINGUSERNAME,
 
-{{SITENAME}} bünyesindeki $PAGETITLE başlıklı sayfa $PAGEEDITDATE tarihinde $PAGEEDITOR tarafından $CHANGEDORCREATED. Sayfanın son haline $PAGETITLE_URL adresinden ulaşabilirsiniz.
+$PAGEINTRO $NEWPAGE
 
-$NEWPAGE
+Editörün girdiği özet: $PAGESUMMARY $PAGEMINOREDIT
 
-Değişikliği yapan kullanıcının açıklaması: $PAGESUMMARY $PAGEMINOREDIT
+Editörün iletişim bilgileri:
+e-posta: $PAGEEDITOR_EMAIL
+viki: $PAGEEDITOR_WIKI
 
-Sayfayı değiştiren kullanıcıya erişim bilgileri:
-E-posta: $PAGEEDITOR_EMAIL
-Viki: $PAGEEDITOR_WIKI
+Bahsi geçen sayfayı ziyaret edinceye kadar sayfayla ilgili başka bildirim gönderilmeyecektir. Ayrıca izleme listenizdeki tüm sayfaların bildirim durumlarını sıfırlayabilirsiniz.
 
-Bahsi geçen sayfayı ziyaret edinceye kadar sayfayla ilgili başka değişiklik bildirimi gönderilmeyecektir. İzleme listenizdeki tüm sayfalar bildirim durumlarını sıfırlayabilirsiniz.
-
-              {{SITENAME}} sitesinin uyarı sistemi.
+{{SITENAME}} bildirim sistemi
 
 --
-İzleme listesi ayarlarınızı değiştirmek için:
+E-posta bildirim ayarlarınızı değiştirmek için aşağıdaki sayfayı ziyaret ediniz:
+{{canonicalurl:{{#special:Preferences}}}}
+
+İzleme listesi ayarlarınızı değiştirmek için aşağıdaki sayfayı ziyaret ediniz:
 {{canonicalurl:{{#special:EditWatchlist}}}}
 
-Sayfayı izleme listenizden silmek için:
+Sayfayı izleme listenizden silmek için aşağıdaki sayfayı ziyaret ediniz:
 $UNWATCHURL
 
 Geri bildirim ve daha fazla yardım için:
@@ -2393,6 +2401,7 @@ dikkatle devam edin.',
 'rollback' => 'değişiklikleri geri al',
 'rollback_short' => 'geri al',
 'rollbacklink' => 'geridöndür',
+'rollbacklinkcount' => '$1 {{PLURAL:$1|değişikliği|değişikliği}} geri döndür',
 'rollbackfailed' => 'geri alma işlemi başarısız',
 'cantrollback' => 'Sayfaya son katkıda bulunan kullanıcı, sayfaya katkıda bulunmuş tek kişi olduğu için, değişiklikler geri alınamıyor.',
 'alreadyrolled' => '[[User:$2|$2]] ([[User talk:$2|Talk]]{{int:pipe-separator}}[[Special:Contributions/$2|{{int:contribslink}}]]) tarafından [[:$1]] sayfasında yapılmış son değişiklik geriye alınamıyor;
@@ -2440,8 +2449,8 @@ Lütfen "geri" gidin ve geldiğiniz sayfayı yeniden yükleyin, sonra tekrar den
 Bu sayfanın koruma seviyesini değiştirebilirsiniz; ancak bu kademeli korumaya etki etmeyecektir.',
 'protect-default' => 'Tüm kullanıcılara izin ver',
 'protect-fallback' => '"$1" izni gerektir',
-'protect-level-autoconfirmed' => 'Yeni ve kayıtlı olmayan kullanıcıları engelle',
-'protect-level-sysop' => 'sadece hizmetliler',
+'protect-level-autoconfirmed' => 'Yalnızca otomatik onaylanmış kullanıcılara izin verilir',
+'protect-level-sysop' => 'Yalnızca hizmetlilere izin verilir',
 'protect-summary-cascade' => 'kademeli',
 'protect-expiring' => 'bitiş tarihi $1 (UTC)',
 'protect-expiring-local' => '$1 tarihinde bitiyor',
@@ -2920,6 +2929,8 @@ Geçici dosya kayıp.',
 # JavaScriptTest
 'javascripttest' => 'JavaScript denemesi',
 'javascripttest-title' => '$1 testleri çalışıyor',
+'javascripttest-qunit-intro' => 'mediawiki.org üzerinden [$1 deneme belgelerine] bakınız.',
+'javascripttest-qunit-heading' => 'MediaWiki JavaScript QUnit deneme paketi',
 
 # Tooltip help for the actions
 'tooltip-pt-userpage' => 'Kullanıcı sayfanız',
@@ -3059,6 +3070,8 @@ Geçici dosya kayıp.',
 'pageinfo-protect-cascading-from' => 'Korumalar üzerinden geçiş',
 'pageinfo-category-info' => 'Kategori bilgileri',
 'pageinfo-category-pages' => 'Sayfa sayısı',
+'pageinfo-category-subcats' => 'Alt kategori sayısı',
+'pageinfo-category-files' => 'Dosya sayısı',
 
 # Skin names
 'skinname-standard' => 'Klasik',
@@ -3109,6 +3122,7 @@ Bunu çalıştırmak, sisteminizi tehlikeye atabilir.",
 'file-info-size-pages' => '$1 × $2 piksel, dosya boyutu: $3, MIME tipi: $4, $5 {{PLURAL:$5|sayfa|sayfa}}',
 'file-nohires' => 'Daha yüksek çözünürlük yok.',
 'svg-long-desc' => 'SVG dosyası, sözde $1 × $2 piksel, dosya boyutu: $3',
+'svg-long-desc-animated' => 'Hareketli SVG dosyası, sözde $1 × $2 piksel, dosya boyutu: $3',
 'svg-long-error' => 'Geçersiz SVG dosyası: $1',
 'show-big-image' => 'Tam çözünürlük',
 'show-big-image-preview' => 'Ön izleme boyutu: $1.',
@@ -3141,6 +3155,8 @@ Bunu çalıştırmak, sisteminizi tehlikeye atabilir.",
 'minutes' => '{{PLURAL:$1|$1 dakika|$1 dakika}}',
 'hours' => '{{PLURAL:$1|$1 saat|$1 saat}}',
 'days' => '{{PLURAL:$1|$1 gün|$1 gün}}',
+'months' => '{{PLURAL:$1|$1 ay|$1 ay}}',
+'years' => '{{PLURAL:$1|$1 yıl|$1 yıl}}',
 'ago' => '$1 önce',
 'just-now' => 'Hemen şimdi',
 
@@ -3297,6 +3313,7 @@ Diğerleri varsayılan olarak gizlenecektir.
 'exif-worldregiondest' => 'Gösterilen bölge',
 'exif-countrydest' => 'Gösterilen ülke',
 'exif-countrycodedest' => 'Gösterilen ülke kodu',
+'exif-provinceorstatedest' => 'Gösterilen il ya da devlet/eyalet',
 'exif-citydest' => 'Gösterilen Şehir',
 'exif-objectname' => 'Kısa başlık',
 'exif-specialinstructions' => 'Özel talimatlar',
@@ -3332,6 +3349,7 @@ Diğerleri varsayılan olarak gizlenecektir.
 'exif-giffilecomment' => 'GIF dosyası yorumu',
 'exif-intellectualgenre' => 'Öğe türü',
 'exif-subjectnewscode' => 'Konu kodu',
+'exif-scenecode' => 'IPTC sahne kodu',
 'exif-event' => 'Adı geçen olay',
 'exif-organisationinimage' => 'Organizasyon gösterilmiştir',
 'exif-personinimage' => 'Adı geçen kişi',
@@ -3805,7 +3823,7 @@ Resimler tam çözünürlükte görüntülenir, diğer dosya tipleri ilgili prog
 'specialpages-group-highuse' => 'Çok kullanılan sayfalar',
 'specialpages-group-pages' => 'Sayfaların listeleri',
 'specialpages-group-pagetools' => 'Sayfa araçları',
-'specialpages-group-wiki' => 'Viki bilgiler ve araçlar',
+'specialpages-group-wiki' => 'Veri ve araçlar',
 'specialpages-group-redirects' => 'Yönlendirmeli özel sayfalar',
 'specialpages-group-spam' => 'Spam araçları',
 
index 6467684..8dfc21b 100644 (file)
@@ -480,6 +480,15 @@ $messages = array(
 
 The password for this new account can be changed on the ''[[Special:ChangePassword|change password]]'' page upon logging in.",
 'newarticle' => '(Чаа)',
+'newarticletext' => 'Амдыызында чаяатынмаан арынче шөлүглеп шилчий бердиңер.
+Ону чаяарда адакы көзенекке сөзүглелден таналап киириңер ([[{{MediaWiki:Helppage}}|тайылбыр арынын]] тода көрүңер).. 
+Маңаа алдаг аайы-биле шилчий берген болзуңарза, браузериңерниң "дедир"  деп таназын базыптыңар.',
+'noarticletext' => "Амдыызында ук арында сөзүглел чок.
+Ол дилеп турар [[Special:Search/{{PAGENAME}}|арыныңар дугайында өске чүүлдерге бижээнин тып аап]] болур силер,
+<span class=\"plainlinks\">[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} журналдар аразынга айытканын көрүп болур силер] азы '''[{{fullurl:{{FULLPAGENAME}}|action=edit}} шак ындыг аттыг арын чаяап болур силер]'''</span>.,",
+'noarticletext-nopermission' => 'Амдыызында ук арында сөзүглел чок.
+Ол дилеп турар [[Special:Search/{{PAGENAME}}|арыныңар дугайында өске чүүлдерге бижээнин тып аап]] болур силер, азы
+<span class="plainlinks">[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} журналдар аразынга айытканын көрүп болур силер]. Шак ындыг ук арын чаяар чөшпээрелиңер чок.',
 'userpage-userdoesnotexist' => '«<nowiki>$1</nowiki>» деп ажыглакчы is not registered.
 Please check if you want to create/edit this page.',
 'userpage-userdoesnotexist-view' => '«$1» деп ажыглакчы not registered.',
@@ -496,6 +505,10 @@ Please check if you want to create/edit this page.',
 'template-semiprotected' => '(четпес камгалаан)',
 'hiddencategories' => 'Бо арын {{PLURAL:$1|$1 чажыт бөлүкке}} хамааржыр:',
 'permissionserrorstext-withaction' => "Мында «'''$2'''» силерниң эргеңер чок, {{PLURAL:$1|чылдагааны|чылдагааннары}}:",
+'recreate-moveddeleted-warn' => "'''Кичээңейлиг. Ооң мурнунда казыттынган арынны катап тургузар деп тур Силер.'''
+
+Ол арынны катап тургузары шынап-ла чугула бе, боданыңар.
+Бо адаанда ол арынның казыышкыннар болгаш өскээр адалгалар журналдарын көргүскен.",
 'moveddeleted-notice' => 'Бо арын ап каавыткан.
 Адаанда ап каавыткан биле өскээр адаан бижиктер шынзылгазын көргүскен.',
 
@@ -522,6 +535,8 @@ Please check if you want to create/edit this page.',
 'last' => 'эрткен',
 'page_first' => 'бирги',
 'page_last' => 'сөөлгү',
+'histlegend' => "Версиялар шилиири: деңнээр дээн арыныңар версияларын имнеңеш, бээр базыптыңар '''{{int:compare-submit}}'''.<br />
+Тайылбыр: '''({{int:cur}})''' — амгы версиядан ылгавыр; '''({{int:last}})''' — эрткен версиядан ылгавыр;  '''{{int:minoreditletter}}''' — биче өскерилгелер.",
 'history-fieldset-title' => 'Каралаары төөгүзү',
 'history-show-deleted' => 'Чүгле казыттынган',
 'histfirst' => 'Эң эрте',
@@ -946,7 +961,7 @@ It must not be more than $1 {{PLURAL:$1|character|characters}} long.',
 'emailsend' => 'Чорудары',
 
 # Watchlist
-'watchlist' => 'Ð\9cÑ\8dÑ\8dÒ£ Ñ\85айгааÑ\80ал Ð´Ð°Ò£Ð·Ñ\8bм',
+'watchlist' => 'ХайгааÑ\80ал Ð´Ð°Ò£Ð·Ñ\8bзÑ\8b',
 'mywatchlist' => 'Хайгаарал даңзы',
 'watchlistfor2' => '$1, силерге $2',
 'nowatchlist' => 'Силерниң хайгаарал даңзыңар куруг.',
@@ -1342,6 +1357,16 @@ It must not be more than $1 {{PLURAL:$1|character|characters}} long.',
 # Special:BlankPage
 'blankpage' => 'Куруг арын',
 
+# External image whitelist
+'external_image_whitelist' => ' #Бо одуругну ол-ла хевээр арттырыңар<pre>
+#Турум илередиглер (регулярные выражения) фрагментилерин маңаа салыңар (// аразынга турар кезээн)
+#Даштыкы чурумалдар URL-биле олар холбаашкан болур.
+#Дужа бергеннери чурумалдар кылдыр көстүп келир, артканнары чурумалдарже шөлүг кылдыр көстүр.
+# "#" деп демдектен эгелээн одуругларны саналдар кылдыр билдинер.
+#Одуруглар регистрге кунук эвес (билинмес)
+
+#Турум илередиглер фрагментилерин бо одуругнуң кырынга салыңар. А бо одуругну олчаан хевээр арттырыңар</pre>',
+
 # Special:Tags
 'tag-filter' => '[[Special:Tags|демдек]] шүүрү:',
 'tag-filter-submit' => 'Шүүрү',
index 1067f7d..152b92d 100644 (file)
@@ -9,6 +9,7 @@
  *
  * @author Alfredie
  * @author Arlin
+ * @author Calak
  * @author Kaganer
  * @author Reedy
  * @author Sahran
@@ -173,6 +174,7 @@ $messages = array(
 'newwindow' => '(يېڭى كۆزنەكتە ئاچ)',
 'cancel' => 'ۋاز كەچ',
 'moredotdotdot' => 'تەپسىلىي…',
+'morenotlisted' => 'تەپسىلاتى كۆرسىتىلمىگەنلىرى…',
 'mypage' => 'بەتىم',
 'mytalk' => 'مۇنازىرە بېتىم',
 'anontalk' => 'بۇ IP نىڭ مۇنازىرە بېتى',
@@ -499,7 +501,7 @@ $2',
 'gotaccount' => "ھېساباتىم بار؟ '''$1'''.",
 'gotaccountlink' => 'تىزىمغا كىر',
 'userlogin-resetlink' => 'تىزىمغا كىرىش تەپسىلاتىنى ئۇنۇتتىڭىز؟',
-'createaccountmail' => 'ئېلخەتتە',
+'createaccountmail' => 'ۋاقىتلىق ئىختىيارىي بىر ئېمنى ئىشلىتىدۇ ھەمدە تۆۋەندىكى بەلگىلەنگەن تورخەت ئادرېسىغا ئەۋەتىدۇ',
 'createaccountreason' => 'سەۋەب:',
 'badretype' => 'سىز كىرگۈزگەن ئىم ماس كەلمىدى.',
 'userexists' => 'كىرگۈزگەن ئىشلەتكۈچى ئاتى ئىشلىتىلىۋاتىدۇ.
@@ -587,6 +589,7 @@ cookies نى قوزغاتقانلىقىڭىزنى جەزملەڭ، بۇ بەتن
 # E-mail sending
 'php-mail-error-unknown' => 'PHP نىڭ mail() فونكسىيەسىدىكى يوچۇن خاتالىق',
 'user-mail-no-addy' => 'ئېلخەت ئادرېسسىز خەت يوللاشنى سىنىدى.',
+'user-mail-no-body' => 'بوش ياكى مەزمۇنى قىسقا مۇۋاپىق بولمىغان تورخەت ئەۋەتىشنى سىنىدى.',
 
 # Change password dialog
 'resetpass' => 'ئىم ئۆزگەرت',
@@ -825,7 +828,7 @@ $2
 'readonlywarning' => "'''ئاگاھلاندۇرۇش: ساندان قۇلۇپلىنىپ ئاسرىلىۋاتىدۇ، شۇڭلاشقا ئۆزگەرتىشىڭىزنى ساقلىيالمايسىز.'''
 سىز بۇ تېكستنى كۆچۈرۈپ تېكست ھۆججىتىگە ساقلاپ، سەل تۇرۇپ ئاندىن ئۆزگەرتىڭ.
 
-باشقۇرغۇچىنىڭ چۈشەندۈرۈشى تۆۋەندىكىچە: $1",
³Ø§Ù\86داÙ\86Ù\86Ù\89 Ù\82Û\87Ù\84Û\87Ù¾Ù\84Ù\89غاÙ\86 Ø¨Ø§Ø´Ù\82Û\87رغÛ\87Ú\86Ù\89Ù\86Ù\89Ú­ Ú\86Û\88Ø´Û\95Ù\86دÛ\88رÛ\88Ø´Ù\89 ØªÛ\86Û\8bÛ\95Ù\86دÙ\89Ù\83Ù\89Ú\86Û\95: $1",
 'protectedpagewarning' => "'''ئاگاھلاندۇرۇش:''' بۇ بەت قۇلۇپلانغان شۇڭلاشقا باشقۇرغۇچى ھوقۇقىغا ئىگە ئىشلەتكۈچىلا ئۇنى ئۆزگەرتەلەيدۇ. پايدىلىنىش ئۈچۈن تۆۋەندە يېقىنقى خاتىرە تەمىنلەندى:",
 'semiprotectedpagewarning' => "'''دىققەت:''' بۇ بەت قۇلۇپلانغان شۇڭلاشقا خەتلەتكەن ئىشلەتكۈچىلا ئۇنى تەھرىرلىيەلەيدۇ.
  پايدىلىنىش ئۈچۈن تۆۋەندە يېقىنقى خاتىرە تەمىنلەندى:",
@@ -2049,7 +2052,7 @@ URL نىڭ توغرىلىقى ۋە تور بېكەتنى زىيارەت قىلى
 # Special:ActiveUsers
 'activeusers' => 'ئاكتىپ ئەزالار تىزىملىكى',
 'activeusers-intro' => 'بۇ يېقىنقى $1 {{PLURAL:$1| كۈن|كۈن}}دىكى مەشغۇلات قىلغان ئىشلەتكۈچىلەر تىزىملىكى.',
-'activeusers-count' => 'يېقىنقى {{PLURAL:$3|كۈن|$3 كۈن}}دىكى $1 {{PLURAL:$1|تەھرىر|تەھرىر}}  قېتىم سانى',
+'activeusers-count' => 'يېقىنقى {{PLURAL:$3|كۈن|$3 كۈن}}دىكى {{PLURAL:$1|مەشغۇلات}} قېتىم سانى $1',
 'activeusers-from' => 'باشلانغان ئىشلەتكۈچىنى كۆرسەت:',
 'activeusers-hidebots' => 'ماشىنا ئادەمنى يوشۇر',
 'activeusers-hidesysops' => 'باشقۇرغۇچىنى يوشۇر',
@@ -2115,7 +2118,7 @@ URL نىڭ توغرىلىقى ۋە تور بېكەتنى زىيارەت قىلى
 'usermessage-template' => 'MediaWiki:UserMessage',
 
 # Watchlist
-'watchlist' => 'كۆزەت تىزىملىكىم',
+'watchlist' => 'كۆزەت تىزىملىكى',
 'mywatchlist' => 'كۆزىتىش تىزىملىكى',
 'watchlistfor2' => '$1 $2 ئۈچۈن',
 'nowatchlist' => 'كۆزەت تىزىملىكىڭىز بوش.',
@@ -2265,6 +2268,8 @@ $2 نىڭ ئاخىرقى تۈزىتىلگەن نەشرىگە ئۆزگەرتىل
 'prot_1movedto2' => '[[$1]] دىن [[$2]]غا يۆتكەلدى',
 'protect-badnamespace-title' => 'قوغداتقل بولمايدىغان ئىسىم بوشلۇق',
 'protect-badnamespace-text' => 'بۇ ئىسىم بوشلۇقىدىكى بەتنى قوغدىغىلى بولمايدۇ.',
+'protect-norestrictiontypes-text' => 'بۇ بەتنى ساقلىيالمايدۇ سەۋەبى ئىشلەتكىلى بولىدىغان قوغداش تىپى يوق.',
+'protect-norestrictiontypes-title' => 'قوغدىغىلى بولمايدىغان بەت',
 'protect-legend' => 'قوغداش جەزملە',
 'protectcomment' => 'سەۋەب:',
 'protectexpiry' => 'قەرەلى:',
@@ -2281,9 +2286,9 @@ $2 نىڭ ئاخىرقى تۈزىتىلگەن نەشرىگە ئۆزگەرتىل
 'protect-cascadeon' => 'تۆۋەندىكى {{PLURAL:$1|بىر|بىر قانچە}} بەت مەزكۇر بەتنى ئۆز ئىچىگە ئېلىش بىلەن بىللە زەنجىرسىمان قوغداش قوزغىتىلغان.
  شۇڭلاشقا بۇ بەتمۇ قوغدالغان. بۇ بەتنىڭ قوغداش دەرىجىسىنى ئۆزگەرتەلەيسىز، ئەمما زەنجىرسىمان قوغداشقا تەسىر كۆرسەتمەيدۇ.',
 'protect-default' => 'ھەممە ئىشلەتكۈچىگە يول قوي',
-'protect-fallback' => '"$1" نىڭ ئىجازىتى زۆرۈر.',
-'protect-level-autoconfirmed' => 'يېڭى ۋە تىزىملاتمىغان ئىشلەتكۈچى چەكلىنىدۇ',
-'protect-level-sysop' => 'باشقۇرغۇچىلا',
+'protect-fallback' => 'پەقەت "$1" ھوقۇقى بار ئىشلەتكۈچىلەرگىلا يول قويىدۇ',
+'protect-level-autoconfirmed' => 'ئۆزلۈكىدىن جەزملەنگەن ئىشلەتكۈچىلەرگىلا يول قويىدۇ',
+'protect-level-sysop' => 'باشقۇرغۇچىلارغىلا يول قويىدۇ',
 'protect-summary-cascade' => 'زەنجىرسىمان قۇلۇپ',
 'protect-expiring' => ' $1 (UTC) توختىتىلغان',
 'protect-expiring-local' => '$1 ۋاقتى توشىدۇ',
@@ -2970,6 +2975,7 @@ $1',
 'pageinfo-magic-words' => '{{PLURAL:$1|سېھرىي خەت}}',
 'pageinfo-hidden-categories' => '{{PLURAL:$1|يوشۇرۇلغان تۈر}}',
 'pageinfo-templates' => '{{PLURAL:$1|سىڭدۈرۈلگەن قېلىپ}}',
+'pageinfo-transclusions' => '($1) {{PLURAL:$1|بەت}}تە سىڭدۈرۈلگەن',
 'pageinfo-toolboxlink' => 'بەت ئۇچۇر',
 'pageinfo-redirectsto' => 'قايتا نىشانلىنىدىغىنى',
 'pageinfo-redirectsto-info' => ' ئۇچۇر',
@@ -2978,6 +2984,10 @@ $1',
 'pageinfo-protect-cascading' => 'زەنجىرلىك قۇلۇپ بۇ جايدىن باشلىنىدۇ',
 'pageinfo-protect-cascading-yes' => 'ھەئە',
 'pageinfo-protect-cascading-from' => 'قوغداش دەرىجىسىنىڭ باغلىنىش ئورنى',
+'pageinfo-category-info' => 'تۈر ئۇچۇرى',
+'pageinfo-category-pages' => 'بەت سانى',
+'pageinfo-category-subcats' => 'تارماق تۈر سانى',
+'pageinfo-category-files' => 'ھۆججەت سانى',
 
 # Skin names
 'skinname-standard' => 'Classic',
@@ -3070,6 +3080,7 @@ $1',
 'minutes' => '{{PLURAL: $1|$1مىنۇت}}',
 'hours' => '{{PLURAL:$1|$1سائەت}}',
 'days' => '{{PLURAL:$1|$1 كۈن}}',
+'months' => '{{PLURAL:$1|$1 ئاي}}',
 'years' => '{{PLURAL:$1|$1 يىل}}',
 'ago' => '$1 بۇرۇن',
 'just-now' => 'بايا',
@@ -3761,7 +3772,7 @@ MediaWiki ئىشلىتىش مەقسىتىنى ئاساس قىلىپ ئېلان 
 'specialpages-group-highuse' => 'كۆپ ئىشلىتىلگەن بەت',
 'specialpages-group-pages' => 'بەت تىزىملىكى',
 'specialpages-group-pagetools' => 'بەت قورالى',
-'specialpages-group-wiki' => 'Wiki سانلىق مەلۇماتى ۋە قورال',
+'specialpages-group-wiki' => 'سانلىق مەلۇمات ۋە قوراللار',
 'specialpages-group-redirects' => 'قايتا نىشانلانغان ئالاھىدە بەت',
 'specialpages-group-spam' => 'ئەخلەتكە قارشى قورال',
 
@@ -3859,6 +3870,7 @@ MediaWiki ئىشلىتىش مەقسىتىنى ئاساس قىلىپ ئېلان 
 'logentry-newusers-newusers' => 'ئەزا $1 قۇرۇلبولدى',
 'logentry-newusers-create' => 'ئەزا $1 قۇرۇلبولدى',
 'logentry-newusers-create2' => 'ئىشلەتكۈچى ھېساباتى $3 نى $1 قۇردى',
+'logentry-newusers-byemail' => 'ئىشلەتكۈچى ھېساباتى $3 نى $1 قۇردى ھەمدە ئىمنى تورخەتكە ئەۋەتتى',
 'logentry-newusers-autocreate' => 'ئىشلەتكۈچى $1 ئاپتوماتلىق قۇرۇلدى',
 'logentry-rights-rights' => '$3 نىڭ ئىشلەتكۈچى گۇرۇپپىسىنى $4 دىن $5 غا $1 ئالماشتۇردى',
 'logentry-rights-rights-legacy' => '$3 نىڭ ئىشلەتكۈچى گۇرۇپپىسىنى $1 ئۆزگەرتتى',
@@ -3916,6 +3928,7 @@ MediaWiki ئىشلىتىش مەقسىتىنى ئاساس قىلىپ ئېلان 
 'api-error-ok-but-empty' => 'ئىچكى خاتالىق: مۇلازىمېتىردا ئىنكاس يوق.',
 'api-error-overwrite' => 'مەۋجۇد ھۆججەت قاپلاشقا يول قويمايدۇ.',
 'api-error-stashfailed' => 'ئىچكى خاتالىق: مۇلازىمېتىر ۋاقىتلىق ھۆججەتنى ساقلىيالمىدى.',
+'api-error-publishfailed' => 'ئىچكى خاتالىق: مۇلازىمېتىر ۋاقىتلىق ھۆججەتنى تارقىتالمىدى.',
 'api-error-timeout' => 'مۇلازىمەت كومپيۇتېر كۆتكەن ۋاقتا ئىنكاس قايتۇرمىدى.',
 'api-error-unclassified' => 'نامەلۇم خاتالىق كۆرۈلدى.',
 'api-error-unknown-code' => 'نامەلۇم خاتالىق:"$1"',
index 8e64eef..daf43ee 100644 (file)
@@ -1409,7 +1409,7 @@ $1",
 'search-interwiki-default' => '$1 результати:',
 'search-interwiki-more' => '(більше)',
 'search-relatedarticle' => "Пов'язаний",
-'mwsuggest-disable' => 'Ð\92имкнÑ\83Ñ\82и Ð¿Ð¾Ñ\80ади AJAX',
+'mwsuggest-disable' => 'Ð\92имкнÑ\83Ñ\82и Ð¿Ð¾Ñ\88Ñ\83ковÑ\96 Ð¿Ñ\96дказки',
 'searcheverything-enable' => 'Пошук у всіх просторах назв',
 'searchrelated' => "пов'язаний",
 'searchall' => 'усі',
@@ -1516,7 +1516,7 @@ $1",
 'prefs-emailconfirm-label' => 'Підтвердження електронної пошти:',
 'prefs-textboxsize' => 'Розмір вікна редагування',
 'youremail' => 'Адреса електронної пошти:',
-'username' => '{{GENDER:$1|Ім’я користувача}}:',
+'username' => "{{GENDER:$1|Ім'я користувача|Ім'я користувачки}}:",
 'uid' => 'Ідентифікатор {{GENDER:$1|користувача}}:',
 'prefs-memberingroups' => '{{GENDER:$2|Член}} {{PLURAL:$1|групи|груп}}:',
 'prefs-memberingroups-type' => '$1',
@@ -2517,7 +2517,7 @@ $UNWATCHURL
 'rollbacklinkcount' => 'скасування $1 {{PLURAL:$1|редагування|редагувань|редагувань}}',
 'rollbacklinkcount-morethan' => 'скасування більш, ніж $1 {{PLURAL:$1|редагування|редагувань|редагувань}}',
 'rollbackfailed' => 'Відкинути зміни не вдалося',
-'cantrollback' => 'Неможливо відкинути редагування, оскільки останній дописувач є її автором.',
+'cantrollback' => 'Ð\9dеможливо Ð²Ñ\96дкинÑ\83Ñ\82и Ñ\80едагÑ\83ваннÑ\8f, Ð¾Ñ\81кÑ\96лÑ\8cки Ð¾Ñ\81Ñ\82аннÑ\96й Ð´Ð¾Ð¿Ð¸Ñ\81Ñ\83ваÑ\87 Ñ\81Ñ\82оÑ\80Ñ\96нки Ñ\94 Ñ\97Ñ\97 Ð°Ð²Ñ\82оÑ\80ом.',
 'alreadyrolled' => 'Неможливо відкинути останні редагування [[:$1]], зроблені [[User:$2|$2]] ([[User talk:$2|обговорення]]{{int:pipe-separator}}[[Special:Contributions/$2|{{int:contribslink}}]]), оскільки хтось інший уже змінив чи відкинув редагування цієї статті.
 
 Останні редагування зроблено [[User:$3|$3]] ([[User talk:$3|обговорення]]{{int:pipe-separator}}[[Special:Contributions/$3|{{int:contribslink}}]]).',
@@ -2860,7 +2860,7 @@ $1',
 Якщо ви цього не зробите, будь ласка, перевірте наявність [[Special:DoubleRedirects|подвійних]] чи [[Special:BrokenRedirects|розірваних]] перенаправлень.
 Ви відповідаєте за те, щоб посилання і надалі вказували туди, куди припускалося.
 
\97веÑ\80нÑ\96Ñ\82Ñ\8c Ñ\83вагÑ\83, Ñ\89о Ñ\81Ñ\82оÑ\80Ñ\96нка '''не''' Ð±Ñ\83де Ð¿ÐµÑ\80ейменована, Ñ\8fкÑ\89о Ñ\81Ñ\82оÑ\80Ñ\96нка Ð· Ð½Ð¾Ð²Ð¾Ñ\8e Ð½Ð°Ð·Ð²Ð¾Ñ\8e Ð²Ð¶Ðµ Ñ\96Ñ\81нÑ\83Ñ\94, Ð¾ÐºÑ\80Ñ\96м Ð²Ð¸Ð¿Ð°Ð´ÐºÑ\96в, ÐºÐ¾Ð»Ð¸ Ð²Ð¾Ð½Ð° порожня або є перенаправленням, а журнал її редагувань порожній.
\97веÑ\80нÑ\96Ñ\82Ñ\8c Ñ\83вагÑ\83, Ñ\89о Ñ\81Ñ\82оÑ\80Ñ\96нка '''не''' Ð±Ñ\83де Ð¿ÐµÑ\80ейменована, Ñ\8fкÑ\89о Ñ\81Ñ\82оÑ\80Ñ\96нка Ð· Ð½Ð¾Ð²Ð¾Ñ\8e Ð½Ð°Ð·Ð²Ð¾Ñ\8e Ð²Ð¶Ðµ Ñ\96Ñ\81нÑ\83Ñ\94, Ð¾ÐºÑ\80Ñ\96м Ð²Ð¸Ð¿Ð°Ð´ÐºÑ\96в, ÐºÐ¾Ð»Ð¸ Ð¾Ñ\81Ñ\82аннÑ\8f порожня або є перенаправленням, а журнал її редагувань порожній.
 Це означає, що ви можете повернути сторінці стару назву, якщо ви перейменували її помилково, але ви не можете затерти існуючу сторінку.
 
 '''ПОПЕРЕДЖЕННЯ!'''
@@ -3221,6 +3221,7 @@ The wiki server can't provide data in a format your client can read.",
 'pageinfo-robot-noindex' => 'Не індексується',
 'pageinfo-views' => 'Кількість переглядів',
 'pageinfo-watchers' => 'Кількість спостерігачів',
+'pageinfo-few-watchers' => 'Менше ніж $1 {{PLURAL:$1|спостерігач|спостерігачі|спостерігачів}}',
 'pageinfo-redirects-name' => 'Перенаправлення на цю сторінку',
 'pageinfo-subpages-name' => 'Підсторінки цієї сторінки',
 'pageinfo-subpages-value' => '$1 ($2 {{PLURAL:$2|перенаправлення|перенаправлення|перенаправлень}}; $3 {{PLURAL:$3|неперенаправлення|неперенаправлення|неперенаправлень}})',
index e6e577d..e01943a 100644 (file)
@@ -722,7 +722,7 @@ Bu yerda: (joriy) = hozirgi koʻrinish bilan farq,
 'search-interwiki-default' => '$1 natijalar:',
 'search-interwiki-more' => '(yana)',
 'search-relatedarticle' => "Bog'liq",
-'mwsuggest-disable' => "AJAX-takliflarini o'chirish",
+'mwsuggest-disable' => 'Qidiruv takliflarini oʻchirib qoʻyish',
 'searcheverything-enable' => 'Barcha nomfazolarda qidir',
 'searchrelated' => 'bogʻlangan',
 'searchall' => 'barchasi',
index 8f64783..58208a8 100644 (file)
@@ -2120,7 +2120,7 @@ Se pol consultar anca dele altre [[{{MediaWiki:Listgrouprights-helppage}}|inform
 'usermessage-editor' => 'Messagero de sistema',
 
 # Watchlist
-'watchlist' => "Pagine tegnùe d'ocio",
+'watchlist' => "Pàjine tegnùe d'ocio",
 'mywatchlist' => "Pàjine tegnùe d'ocio",
 'watchlistfor2' => 'De $1 $2',
 'nowatchlist' => "No te ghè indicà pagine da tegner d'ocio.",
index 44e1dc8..e65af13 100644 (file)
@@ -2338,7 +2338,7 @@ Những sửa đổi đối với trang này và trang thảo luận của nó s
 'enotif_subject_created' => 'Trang $1 tại {{SITENAME}} đã được tạo ra bởi $2.',
 'enotif_subject_moved' => 'Trang $1 tại {{SITENAME}} đã được di chuyển bởi $2.',
 'enotif_subject_restored' => 'Trang $1 tại {{SITENAME}} đã được phục hồi bởi $2.',
-'enotif_subject_changed' => 'Trang $1 tại {{SITENAME}} đã được thay đổi bởi $2.',
+'enotif_subject_changed' => 'Trang $1 tại {{SITENAME}} đã được thay đổi bởi $2',
 'enotif_body_intro_deleted' => 'Trang $1 tại {{SITENAME}} đã được $2 xóa vào $PAGEEDITDATE. Xem $3 .',
 'enotif_body_intro_created' => 'Trang $1 tại {{SITENAME}} đã được $2 tạo ra vào $PAGEEDITDATE. Xem phiên bản hiện hành tại $3 .',
 'enotif_body_intro_moved' => 'Trang $1 tại {{SITENAME}} đã được $2 di chuyển vào $PAGEEDITDATE. Xem phiên bản hiện hành tại $3 .',
index 895d82e..6ca447b 100644 (file)
@@ -609,7 +609,7 @@ Seness [$2 kuvauhsõ lehocülless] informaattsija on alapallõ annõttu.',
 'emailmessage' => 'Ilmottamin:',
 
 # Watchlist
-'watchlist' => 'Minu kattsõspiiska',
+'watchlist' => 'Kattsõspiiska',
 'mywatchlist' => 'Minu kattsõspiiska',
 'watchlistfor2' => '$2 - $1 vart',
 'addedwatchtext' => "Cülci \"[[:\$1]]\" on lisättü Teďďee [[Special:Watchlist|kattsospiizgallõ]].
index cad26e0..e3dbb83 100644 (file)
@@ -112,7 +112,7 @@ $messages = array(
 
 'underline-always' => 'Pirme',
 'underline-never' => 'Diri',
-'underline-default' => 'An aada-nga-daan nga panngaykayan',
+'underline-default' => 'An panmutos o pandalikyat nga aada-nga-daan',
 
 # Font style option in Special:Preferences
 'editfont-style' => 'Estilo hin font ha lugar hin pagliwat',
@@ -199,7 +199,8 @@ $messages = array(
 'newwindow' => '(nabuklad hin bag-o nga tamboan o bintana)',
 'cancel' => 'Pasagdi',
 'moredotdotdot' => 'Damo pa nga…',
-'mypage' => 'Akon pakli',
+'morenotlisted' => 'Damo pa nga waray gintalaan...',
+'mypage' => 'Pakli',
 'mytalk' => 'Mga akon paghingay',
 'anontalk' => 'Paghingay para hini nga IP',
 'navigation' => 'Paglayag',
@@ -440,7 +441,7 @@ Kweri: $2',
 'actionthrottled' => 'Ginpahinay an ginbuhat',
 'actionthrottledtext' => 'Komo uska pangontra ha spam, ikaw in ginlilimitaran paghimo hini nga pagbuhat hin sobra kadamo ha sulod hin gutiay nga oras, ngan ikaw in naglapos hini nga katubtuban.
 Alayon pagutro kahuman hin pipira ka mga minuto.',
-'protectedpagetext' => 'Ini nga pakli in pinasaliporan para mapugngan an mga pagliwat.',
+'protectedpagetext' => 'Ginpanalipdan ini nga pakli basi mapugngan an pagliwat o iba pa nga mga maburuhat.',
 'viewsourcetext' => 'Puydi ka kinmita ngan kinmopya han gintikangan han pakli:',
 'viewyourtext' => "Puydi nim makit-an ngan makopya an tinikangan han '''imo mga pagliwat''' ha dinhi nga pakli:",
 'protectedinterface' => 'Ini nga pakli in nahatag hin teksto hit interface para han software han hin nga wiki, ngan in pinasasaliporan para makalikay hit pag-abuso.
@@ -464,6 +465,7 @@ An magdudurmara nga nagtrangka hini in naghatag hini nga eksplenasyon: "$3".',
 'virus-unknownscanner' => 'diri-nasasabtan nga antivirus:',
 
 # Login and logout pages
+'welcomeuser' => '¡Uswag ngan Dayon, $1!',
 'yourname' => 'Agnay hit gumaramit:',
 'yourpassword' => 'Tigaman-pagsulod:',
 'yourpasswordagain' => 'Utroha pagbutang an tigaman-han-pagsakob:',
@@ -628,7 +630,7 @@ o <span class="plainlinks">[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}}
 'note' => "'''Pahibaro:'''",
 'previewnote' => "'''Hinumdumi nga pahiuna-nga-paggawas pa la ini.'''
 ¡Waray pa katipig an imo mga ginbag-o!",
-'continue-editing' => 'Padayon pagliwat',
+'continue-editing' => 'Pakadto han lugar hin panliwat',
 'editing' => 'Ginliliwat an $1',
 'creating' => 'Ginhihimo an $1',
 'editingsection' => 'Ginliliwat an $1 (bahin)',
index 12a797f..88ebdea 100644 (file)
@@ -626,7 +626,7 @@ $2',
 'gotaccount' => "האסטו שוין א קאנטע? '''$1'''.",
 'gotaccountlink' => 'אַרײַנלאגירן',
 'userlogin-resetlink' => 'פארגעסן אײַערע אַרײַנלאָגירן פרטים?',
-'createaccountmail' => '×\93×\95ר×\9a ×¢-פ×\90ס×\98',
+'createaccountmail' => '× ×\99צ×\9f ×\90 ×¤×¨×\90×\95×\95×\99×\96×\90ר×\99ש ×¤×\90ס×\95×\95×\90ר×\98 ×\90×\95×\9f ×©×\99ק×\9f ×¦×\95×\9d ×¢-פ×\90ס×\98 ×\90×\93רעס ×\92עצ×\99×\99×\9b× ×\98 ×\90×\95× ×\98×\9f',
 'createaccountreason' => 'אורזאַך:',
 'badretype' => 'די פאסווערטער וואס איר האט אריינגעלייגט זענען נישט אייניג.',
 'userexists' => 'דער באַניצער נאָמען איז שוין געניצט. 
@@ -703,6 +703,7 @@ $2',
 # E-mail sending
 'php-mail-error-unknown' => 'אומבאַקאַנט טעות אין()mail פֿונקציע פֿון PHP.',
 'user-mail-no-addy' => 'געפרוווט צו שיקן ע-פּאָסט אָן אַן ע-פּאָסט אַדרעס.',
+'user-mail-no-body' => 'האט פרובירט צו שיקן א בליצבריוו וואס זיין אינהאלט איז ליידיק אדער גאר קורץ.',
 
 # Change password dialog
 'resetpass' => 'ענדערן קאנטע פאסווארט',
@@ -933,8 +934,8 @@ $2
 '''זיכט נישט באניצן מיט שטאף וואס איז באשיצט מיט קאפירעכטן!'''",
 'longpageerror' => "'''פעלער: דער טעקסט וואס איר האט ארײַנגעשטעלט איז לאנג {{PLURAL:$1|איין קילאבייט|$1 קילאבייטן}}, וואס איז לענגער פון דעם מאקסימום פון {{PLURAL:$2|איין קילאבייט|$2 קילאבייטן}}. 
 ער קען נישט ווערן אפגעהיטן.'''",
-'readonlywarning' => "'''×\95×\95×\90רענ×\95× ×\92: ×\93×\99 ×\93×\90×\98×¢×\91×\90×\96×¢ ×\90×\99×\96 ×\92×¢×\95×\95×\90ר×\9f ×¤×\90רש×\9c×\90ס×\9f ×¤×\90ר ×¡×\99×\99×\98 ×\90×\95×\99פ×\94×\90×\9c×\98×\95× ×\92,
\9e×\9e×\99×\9c×\90 ×\95×\95×¢×\98 ×\90×\99ר × ×\99ש×\98 ×§×¢× ×¢×\9f ×\90פ×\94×\99×\98×\9f ×\90×\99×\99ערע ×¢× ×\93ער×\95× ×\92×¢×\9f ×\90צ×\99× ×\93. ×\90×\99ר ×§×¢× ×\98 ×§×\90פ×\99ר×\9f ×\90×\95×\9f ×\90רײַנ×\9c×\99×\99×\92×\9f ×\93×¢×\9d ×\98עקס×\98 ×\90ר×\99×\99×\9f ×¦×\95 ×\90 ×\98עקס×\98 ×\98עקע ×\90×\95×\9f ×\93×\90ס ×\93×\90ר×\98×\9f ×\90פ×\94×\99×\98×\9f ×¤×\90ר ×©×¤×¢×\98ער.'''
+'readonlywarning' => "'''×\95×\95×\90רענ×\95× ×\92: ×\93×\99 ×\93×\90×\98× ×\91×\90×\96×¢ ×\90×\99×\96 ×\92×¢×\95×\95×\90ר×\9f ×¤×\90רש×\9c×\90ס×\9f ×¤×\90ר ×\90×\95×\99פ×\94×\90×\9c×\98×\95× ×\92, ×\9e×\9e×\99×\9c×\90 ×\95×\95×¢×\98 ×\90×\99ר × ×\99ש×\98 ×§×¢× ×¢×\9f ×\90פ×\94×\99×\98×\9f ×\90×\99×\99ערע ×¢× ×\93ער×\95× ×\92×¢×\9f ×\90צ×\99× ×\93. '''
\90×\99ר ×§×¢× ×\98 ×§×\90פ×\99ר×\9f ×\90×\95×\9f ×\90רײַנ×\9c×\99×\99×\92×\9f ×\93×¢×\9d ×\98עקס×\98 ×\90ר×\99×\99×\9f ×¦×\95 ×\90 ×\98עקס×\98 ×\98עקע ×\90×\95×\9f ×\93×\90ס ×\93×\90ר×\98×\9f ×\90פ×\94×\99×\98×\9f ×\90×\95×\99×£ ×©×¤×¢×\98ער.
 
 דער אדמיניסטראטאר וואס האט זי פארשלאסן האט מסביר געווען אזוי: $1",
 'protectedpagewarning' => "'''ווארענונג:  דער בלאט איז געווארן פארשפארט אז בלויז באניצערס מיט סיסאפ פריווילעגיעס קענען אים ענדערן.'''
@@ -1000,6 +1001,8 @@ $2
 'language-converter-depth-warning' => 'אַריבער דעם שפּראַך קאַנווערטער טיף לימיט ($1)',
 'node-count-exceeded-category' => 'בלעטער וואו קנופצאל איז צו פיל',
 'node-count-exceeded-warning' => 'קנופנצאל אויפן בלאט צו הויך',
+'expansion-depth-exceeded-category' => "בלעטער וואו מ'האט אריבערגעשטיגן די פארברייטערונג טיף",
+'expansion-depth-exceeded-warning' => 'בלאט גייט אריבער דער פארברייטערונג טיף',
 'converter-manual-rule-error' => 'געטראפן א גרײַז אין האנטלעכן שפראך־קאנווערטירן כלל',
 
 # "Undo" feature
@@ -1229,7 +1232,7 @@ $1",
 'search-interwiki-default' => '$1 רעזולטאטן:',
 'search-interwiki-more' => '(נאך)',
 'search-relatedarticle' => 'פארבינדן',
-'mwsuggest-disable' => '×\91×\98×\9c ×\9e×\90×\9b×\9f ×¤×\90רש×\9c×\90×\92×\9f AJAX',
+'mwsuggest-disable' => '×\91×\98×\9c ×\9e×\90×\9b×\9f ×\96×\95×\9a ×¤×\90רש×\9c×\90×\92×\9f',
 'searcheverything-enable' => 'זוכן אין אלע נאמענטיילן',
 'searchrelated' => 'פארבינדן',
 'searchall' => 'אלץ',
@@ -1730,6 +1733,7 @@ $1",
 'lockmanager-fail-deletelock' => 'נישט מעגלעך אויסמעקן שלאס טעקע פאר "$1".',
 
 # ZipDirectoryReader
+'zip-file-open-error' => 'געטראפן א גרײַז ביים עפענען די טעקע פאר ZIP־קאנטראלירונג.',
 'zip-wrong-format' => 'ספעציפירטע טעקע איז נישט קיין ZIP טעקע.',
 
 # Special:UploadStash
@@ -2276,6 +2280,7 @@ $UNWATCHURL
 'prot_1movedto2' => '[[$1]] אריבערגעפירט צו [[$2]]',
 'protect-badnamespace-title' => 'אומשיצבארער נאמענטייל',
 'protect-badnamespace-text' => 'בלעטער אין דעם נאמענטייל קען מען נישט שיצן.',
+'protect-norestrictiontypes-title' => 'נישט־שיצבארער בלאט',
 'protect-legend' => 'באַשטעטיגן שיץ',
 'protectcomment' => 'אורזאַך:',
 'protectexpiry' => 'גייט אויס:',
@@ -2584,7 +2589,7 @@ $1',
 'move-page' => 'באַוועגן $1',
 'move-page-legend' => 'באַוועגן בלאַט',
 'movepagetext' => "זיך באניצן מיט דעם פֿארעם וועט פֿארענדערן דעם נאמען פֿון דעם בלאט, און וועט אריבערפֿירן זיין געשיכטע צום נייעם נאמען.
\93×\90ס ×\90×\9c×\98×¢ ×§×¢×¤×\9c ×\95×\95×¢×\98 ×\95×\95ער×\9f ×\90 ×\95×\95×\99×\99×\98ערפֿ×\99ר×\9f בלאט צום נייעם קעפל.
\93×\90ס ×\90×\9c×\98×¢ ×§×¢×¤×\9c ×\95×\95×¢×\98 ×\95×\95ער×\9f ×\90 ×\95×\95×\99×\99×\98ערפֿ×\99ר×\95× ×\92 בלאט צום נייעם קעפל.
 
 איר קענט דערהיינטיגן ווייטערפֿירונגען צום אלטן נאמען אויטאמאטיש.
 
@@ -3225,7 +3230,9 @@ $1',
 'exif-unknowndate' => 'אומבאַוואוסטע דאַטע',
 
 'exif-orientation-1' => 'נארמאַל',
+'exif-orientation-2' => 'האריזאנטאל געשפיגלט',
 'exif-orientation-3' => 'ראטירט 180°',
+'exif-orientation-4' => 'ווערטיקאל געשפיגלט',
 'exif-orientation-6' => 'ראטירט 90° קעגן זייגער',
 'exif-orientation-7' => 'ראטירט  90° מיטן זייגער און איבערגעדרייט ווערטיקאל',
 'exif-orientation-8' => 'ראטירט 90° מיטן זייגער',
@@ -3621,7 +3628,7 @@ $5
 'specialpages-group-highuse' => 'בלעטער וואס זענען געניצט אסאך',
 'specialpages-group-pages' => 'ליסטעס פֿון בלעטער',
 'specialpages-group-pagetools' => 'געצייג פֿאר בלעטער',
-'specialpages-group-wiki' => '×\95×\95×\99ק×\99 ×\93×\90Ö·×\98×\9f ×\90×\95×\9f ×\92עצ×\99×\99×\92',
+'specialpages-group-wiki' => 'דאַטן און געצייג',
 'specialpages-group-redirects' => 'ווײַטערפֿירן ספעציעלע בלעטער',
 'specialpages-group-spam' => 'ספאַם געצייג',
 
index 0b9e5e5..c426b82 100644 (file)
@@ -361,7 +361,7 @@ $messages = array(
 'tog-editsection' => '启用[编辑]链接编辑段落',
 'tog-editsectiononrightclick' => '启用右击段落标题编辑段落(需要JavaScript)',
 'tog-showtoc' => '显示目录(对于有多于3个标题的页面)',
-'tog-rememberpassword' => '在浏览器上记住我的登录状态(最长$1天)',
+'tog-rememberpassword' => '在该浏览器保存我的登录状态(最长$1日)',
 'tog-watchcreations' => '添加我创建的页面和上传的文件至我的监视列表',
 'tog-watchdefault' => '添加我编辑的页面和文件至我的监视列表',
 'tog-watchmoves' => '将我移动的页面和文件添加到我的监视列表',
@@ -369,7 +369,7 @@ $messages = array(
 'tog-minordefault' => '默认标记编辑为小编辑',
 'tog-previewontop' => '在编辑框上方显示预览',
 'tog-previewonfirst' => '首次编辑时显示预览',
-'tog-nocache' => '用浏览器页面缓存',
+'tog-nocache' => '用浏览器页面缓存',
 'tog-enotifwatchlistpages' => '当我的监视列表中的页面或文件更改时发送电子邮件通知我',
 'tog-enotifusertalkpages' => '当我的讨论页更改时发送电子邮件通知我',
 'tog-enotifminoredits' => '当页面和文件有小编辑时发送电子邮件通知我',
@@ -380,7 +380,7 @@ $messages = array(
 'tog-externaleditor' => '默认使用外部编辑器(供高级用户使用,需要在您的计算机上作出一些特别设置。[//www.mediawiki.org/wiki/Manual:External_editors 更多信息。])',
 'tog-externaldiff' => '默认使用外部差异分析(供高级用户使用,需要在您的计算机上作出一些特别设置。[//www.mediawiki.org/wiki/Manual:External_editors 更多信息。])',
 'tog-showjumplinks' => '启用“跳转到”访问链接',
-'tog-uselivepreview' => '使用实时预览(需要 Javascript 支持)(实验功能)',
+'tog-uselivepreview' => '使用实时预览(需要JavaScript)(实验功能)',
 'tog-forceeditsummary' => '未输入编辑摘要时提醒我',
 'tog-watchlisthideown' => '在监视列表中隐藏我的编辑',
 'tog-watchlisthidebots' => '在监视列表中隐藏机器人的编辑',
@@ -389,7 +389,7 @@ $messages = array(
 'tog-watchlisthideanons' => '在监视列表中隐藏匿名用户',
 'tog-watchlisthidepatrolled' => '在监视列表中隐藏已巡查的编辑',
 'tog-ccmeonemails' => '把我给其他用户发送的电子邮件的副本发送给我',
-'tog-diffonly' => '对比差异时不显示页面内容',
+'tog-diffonly' => '比较差异时不显示页面内容',
 'tog-showhiddencats' => '显示隐藏分类',
 'tog-noconvertlink' => '停用链接文字转换',
 'tog-norollbackdiff' => '执行回退后不显示差异',
@@ -481,7 +481,7 @@ $messages = array(
 'newwindow' => '(将于新窗口中打开)',
 'cancel' => '取消',
 'moredotdotdot' => '更多',
-'morenotlisted' => '更多未被列出...',
+'morenotlisted' => '更多未被列出的模板...',
 'mypage' => '页面',
 'mytalk' => '讨论',
 'anontalk' => '该IP地址的讨论',
@@ -601,7 +601,7 @@ $1',
 'privacypage' => 'Project:隐私权政策',
 
 'badaccess' => '权限错误',
-'badaccess-group0' => '您被禁止执行您刚才请求的操作。',
+'badaccess-group0' => '你被禁止执行你刚才请求的操作。',
 'badaccess-groups' => '您刚才请求的操作只有{{PLURAL:$2|这个用户组|以下用户组}}中的用户才能使用: $1',
 
 'versionrequired' => '需要版本为$1的MediaWiki',
@@ -610,14 +610,14 @@ $1',
 
 'ok' => '确定',
 'retrievedfrom' => '来自“$1”',
-'youhavenewmessages' => '有$1($2)。',
+'youhavenewmessages' => '有$1($2)。',
 'newmessageslink' => '新信息',
 'newmessagesdifflink' => '最后更改',
-'youhavenewmessagesfromusers' => '您有来自{{PLURAL:$3| 另一位用户| $3位用户}}的$1($2)。',
-'youhavenewmessagesmanyusers' => '您有来自多位用户的$1($2)。',
+'youhavenewmessagesfromusers' => '你有来自{{PLURAL:$3|其他用户|$3个用户}}的$1($2)。',
+'youhavenewmessagesmanyusers' => '你有来自多个用户的$1($2)。',
 'newmessageslinkplural' => '{{PLURAL:$1|一条新信息|新信息}}',
-'newmessagesdifflinkplural' => '最{{PLURAL:$1|更改}}',
-'youhavenewmessagesmulti' => '在$1有新信息',
+'newmessagesdifflinkplural' => '最{{PLURAL:$1|更改}}',
+'youhavenewmessagesmulti' => '在$1有新信息',
 'editsection' => '编辑',
 'editold' => '编辑',
 'viewsourceold' => '查看源代码',
@@ -657,7 +657,7 @@ $1',
 
 # Main script and global functions
 'nosuchaction' => '这个命令不存在',
-'nosuchactiontext' => 'URL 指定的命令无效。您可能误输入了 URL 地址,或者点击了错误的链接。这一错误也有可能是由{{SITENAME}}所使用软件自身的错误导致的。',
+'nosuchactiontext' => 'URL指定的命令无效。你可能误输入了URL地址,或者点击了错误的链接。这一错误亦有可能是由{{SITENAME}}所使用软件自身的错误导致的。',
 'nosuchspecialpage' => '此特殊页面不存在',
 'nospecialpagetext' => '<strong>您请求的特殊页面无效。</strong>
 
@@ -741,8 +741,8 @@ $2',
 执行锁定的管理员给出如下解释:$3。',
 'invalidtitle-knownnamespace' => '使用名字空间“$2”和文本“$3”的无效标题',
 'invalidtitle-unknownnamespace' => '使用未知名字空间编号$1和文本“$2”的无效标题',
-'exception-nologin' => '未登录',
-'exception-nologin-text' => '此操作需要您先登录。',
+'exception-nologin' => '未登录',
+'exception-nologin-text' => '该页面或操作需要你登录至本wiki。',
 
 # Virus scanner
 'virus-badscanner' => "错误的配置:未知的病毒扫描程序:''$1''",
@@ -754,19 +754,18 @@ $2',
 
 您可以继续以匿名方式使用{{SITENAME}},或再次以相同或不同用户身份<span class='plainlinks'>[$1 登录]</span>。请注意一些页面可能仍然显示您为登录状态,直到您清空您的浏览器缓存为止。",
 'welcomeuser' => '欢迎,$1!',
-'welcomecreation-msg' => '您的帐户已创建。
-请不要忘记更改您的[[Special:Preferences|{{SITENAME}}个人设置]]。',
+'welcomecreation-msg' => '你的账户已创建。请不要忘记更改你的[[Special:Preferences|{{SITENAME}}系统设置]]。',
 'yourname' => '用户名:',
 'yourpassword' => '密码:',
 'yourpasswordagain' => '再次输入密码:',
-'remembermypassword' => '自动登录(最长$1{{PLURAL:$1|天|天}})',
-'securelogin-stick-https' => '登录后继续使用 HTTPS 连接',
+'remembermypassword' => '在该浏览器保存我的登录状态(最长$1日)',
+'securelogin-stick-https' => '登录后继续使用HTTPS连接',
 'yourdomainname' => '您的域名:',
-'password-change-forbidden' => '您不能在此 wiki 上修改密码。',
+'password-change-forbidden' => '你不能在本wiki更改密码。',
 'externaldberror' => '这可能是由于验证数据库错误或您被禁止更新您的外部账号。',
 'login' => '登录',
 'nav-login-createaccount' => '登录/创建账户',
-'loginprompt' => '您必须启用 Cookies 才能登录{{SITENAME}}。',
+'loginprompt' => '你必须启用Cookies才能登录{{SITENAME}}。',
 'userlogin' => '登录/创建账户',
 'userloginnocreate' => '登录',
 'logout' => '退出',
@@ -777,25 +776,24 @@ $2',
 'createaccount' => '创建账户',
 'gotaccount' => '已经拥有账户?请$1。',
 'gotaccountlink' => '登录',
-'userlogin-resetlink' => '忘记了的登录信息?',
+'userlogin-resetlink' => '忘记了的登录信息?',
 'createaccountmail' => '使用一个临时的随机密码,并将它发送到以下指定的电子邮件地址',
 'createaccountreason' => '原因:',
 'badretype' => '您所输入的密码并不相同。',
 'userexists' => '用户名已存在。请使用其他名称。',
 'loginerror' => '登录错误',
 'createaccounterror' => '无法建立账户:$1',
-'nocookiesnew' => '已成功创建新账户!检测到您已禁用 Cookies,请先启用然后登录。',
-'nocookieslogin' => '本站使用 Cookies 进行登录,检测到您已禁用 Cookies,请先启用然后重试。',
-'nocookiesfornew' => '该用户账户尚未创建,因为我们不能确认它的来源。
-请确保您已经启用 Cookies,刷新本页后重试。',
-'noname' => '您没有输入有效的用户名。',
+'nocookiesnew' => '本用户账户已被创建,但登录失败。{{SITENAME}}使用cookie登录。你已停用cookie。请启用cookie,然后使用你的新用户名和密码登录。',
+'nocookieslogin' => '{{SITENAME}}使用cookie登录。你已停用cookie。请启用cookie后重试。',
+'nocookiesfornew' => '本用户账户未被创建,我们不能确认它的来源。请确保你已启用cookie,刷新本页后重试。',
+'noname' => '你没有指定有效的用户名。',
 'loginsuccesstitle' => '登录成功',
 'loginsuccess' => "'''“$1”,欢迎登录{{SITENAME}}。'''",
-'nosuchuser' => 'æ\89¾ä¸\8då\88°ç\94¨æ\88·â\80\9c$1â\80\9dã\80\82ç\94¨æ\88·å\90\8d对大å°\8få\86\99å\92\8cç¹\81ç®\80ä½\93æ\98¯å\8cºå\88\86ç\9a\84ã\80\82请æ£\80æ\9f¥æ\82¨ç\9a\84æ\8b¼å\86\99æ\98¯å\90¦æ\9c\89é\94\99误ï¼\8cæ\88\96è\80\85[[Special:UserLogin/signup|注å\86\8c]]。',
-'nosuchusershort' => 'æ\89¾ä¸\8då\88°ç\94¨æ\88·â\80\9c$1â\80\9dã\80\82请æ£\80æ\9f¥æ\82¨ç\9a\84æ\8b¼å\86\99æ\98¯å\90¦æ\9c\89é\94\99误。',
-'nouserspecified' => '您需要指定一个用户名。',
+'nosuchuser' => '没æ\9c\89å\90\8d为â\80\9c$1â\80\9dç\9a\84ç\94¨æ\88·ã\80\82ç\94¨æ\88·å\90\8då\8cºå\88\86大å°\8få\86\99ã\80\82请æ£\80æ\9f¥ä½ ç\9a\84æ\8b¼å\86\99æ\88\96[[Special:UserLogin/signup|å\88\9b建æ\96°è´¦æ\88·]]。',
+'nosuchusershort' => '没æ\9c\89å\90\8d为â\80\9c$1â\80\9dç\9a\84ç\94¨æ\88·ã\80\82请æ£\80æ\9f¥ä½ ç\9a\84æ\8b¼å\86\99。',
+'nouserspecified' => '你必须指定用户名。',
 'login-userblocked' => '该用户已被封禁,禁止登录。',
-'wrongpassword' => '密码错误,请重试。',
+'wrongpassword' => '你输入的密码错误。请重试。',
 'wrongpasswordempty' => '您没有输入密码,请重试!',
 'passwordtooshort' => '您的密码至少需要$1个字符。',
 'password-name-match' => '您的密码必须和您的用户名不相同。',
@@ -813,13 +811,13 @@ $2',
 'noemailcreate' => '您需要提供一个有效的电子邮件地址',
 'passwordsent' => '用户"$1"的新密码已经寄往所登记的电子邮件地址。
 请在收到后再登录。',
-'blocked-mailpassword' => '您的 IP 地址已被禁止编辑,同时为了防止密码恢复功能被滥用,已禁用该功能。',
+'blocked-mailpassword' => '你的IP地址被禁止编辑,为预防滥用,密码恢复功能也被禁止使用。',
 'eauthentsent' => '一封确认信已经发送到推荐的地址。在发送其它邮件到此账户前,您必须首先依照这封信中的指导确认这个电子邮箱真实有效。',
 'throttled-mailpassword' => '密码提醒已在最近$1小时内发送。为了安全起见,在每$1小时内只能发送一个密码提醒。',
 'mailerror' => '发送邮件错误:$1',
-'acct_creation_throttle_hit' => '抱歉!您已经创建了$1个账号,已经达到最大允许注册数量。目前使用本 IP 的来访者将不能再创建任何账户。',
+'acct_creation_throttle_hit' => '使用你的IP地址访问本wiki的访客在过去24小时中创建了{{PLURAL:$1|$1个账户}},达到了这段时间所允许的最大值。因此,使用该IP地址的访客现在不能再创建账户。',
 'emailauthenticated' => '您的电子邮箱地址已经于$2 $3确认有效。',
-'emailnotauthenticated' => '您的邮箱地址<strong>尚未被认证</strong>。下列功能将不会发送任何邮件。',
+'emailnotauthenticated' => '你的电子邮件地址未确认。你不会接收到以下任何特性的电子邮件。',
 'noemailprefs' => '指定一个电子邮箱地址以使用此功能。',
 'emailconfirmlink' => '确认您的邮箱地址',
 'invalidemailaddress' => '邮箱地址格式不正确,请输入正确的邮箱地址或清空该输入框。',
@@ -832,8 +830,7 @@ $2',
 
 如果该账户创建错误的话,您可以忽略此信息。',
 'usernamehasherror' => '用户名中不可包含哈希(hash)字符',
-'login-throttled' => '您最近已经尝试多次登录。
-请稍后重试。',
+'login-throttled' => '你最近尝试登录的次数过多。请稍后重试。',
 'login-abort-generic' => '登录失败 - 已终止',
 'loginlanguagelabel' => '语言:$1',
 'suspicious-userlogout' => '注销请求被拒绝,因为它似乎是由有设计缺陷的浏览器或缓存代理发出的。',
@@ -862,7 +859,7 @@ $2',
 
 # Special:PasswordReset
 'passwordreset' => '重置密码',
-'passwordreset-text' => '完成此表格以接收一封包含您的帐户详情的提醒邮件。',
+'passwordreset-text' => '完成该表格以接收你账户信息的邮件提醒。',
 'passwordreset-legend' => '重置密码',
 'passwordreset-disabled' => '此wiki已经禁用密码重置。',
 'passwordreset-pretext' => '{{PLURAL:$1||输入下面的数据块之一}}',
@@ -894,11 +891,11 @@ $2
 'changeemail-text' => '完成此窗体可以更改您的电子邮件地址。您将需要输入您的密码以确认此更改。',
 'changeemail-no-info' => '
 您必须登录以直接访问本页。',
-'changeemail-oldemail' => 'å½\93å\89\8dç\9a\84ç\94µå­\90é\82®ä»¶å\9c°å\9d\80ï¼\9a',
+'changeemail-oldemail' => '当前电子邮件地址:',
 'changeemail-newemail' => '新的电子邮件地址:',
 'changeemail-none' => '(无)',
-'changeemail-password' => '的{{SITENAME}}密码:',
-'changeemail-submit' => '更改电子邮',
+'changeemail-password' => '的{{SITENAME}}密码:',
+'changeemail-submit' => '更改电子邮件地址',
 'changeemail-cancel' => '取消',
 
 # Edit page toolbar
@@ -914,9 +911,9 @@ $2
 'headline_tip' => '2级标题文字',
 'nowiki_sample' => '在此插入非格式文本',
 'nowiki_tip' => '插入非格式文本',
-'image_sample' => '例.jpg',
+'image_sample' => '例.jpg',
 'image_tip' => '插入文件',
-'media_sample' => '例.ogg',
+'media_sample' => '例.ogg',
 'media_tip' => '文件链接',
 'sig_tip' => '带时间戳的签名',
 'hr_tip' => '水平线(请小心使用)',
@@ -934,30 +931,34 @@ $2
 'anoneditwarning' => "'''警告:'''您没有登录。
 您的IP地址将记录在此页的编辑历史中。",
 'anonpreviewwarning' => "''您没有登录。保存页面将会把您的IP地址记录在此页的编辑历史中。''",
-'missingsummary' => "'''提示:'''您没有提供编辑摘要。如果您再次点击“{{int:savearticle}}”,您的编辑将不带编辑摘要保存。",
+'missingsummary' => "'''提示:'''你没有提供编辑摘要。如果你再次点击“{{int:savearticle}}”,你的编辑将不带编辑摘要保存。",
 'missingcommenttext' => '请在下面输入评论。',
 'missingcommentheader' => "'''提示:''' 您还没有为此评论提供一个标题。如果您再次点击“{{int:savearticle}}”,您的编辑将不带标题保存。",
 'summary-preview' => '摘要预览:',
 'subject-preview' => '标题预览:',
 'blockedtitle' => '用户被封禁',
-'blockedtext' => "'''您的用户名或 IP 地址已被封禁。'''
+'blockedtext' => "'''你的用户名或IP地址已被封禁。'''
 
\9c¬æ¬¡å°\81ç¦\81æ\93\8dä½\9cç\94±$1å®\8cæ\88\90ï¼\8cå°\81ç¦\81å\8e\9få\9b ä¸º''$2''。
\89§è¡\8cå°\81ç¦\81ç\9a\84管ç\90\86å\91\98æ\98¯$1ã\80\82å°\81ç¦\81å\8e\9få\9b æ\98¯''$2''。
 
 * 开始时间:$8
-* ç»\93æ\9d\9fæ\97¶é\97´ï¼\9a$6
-* 拟封禁对象:$7
+* å\88°æ\9c\9fæ\97¶é\97´ï¼\9a$6
+* 目标用户:$7
 
-您可以联系$1或其他的[[{{MediaWiki:Grouppage-sysop}}|管理员]]以申诉此次封禁。若您已在[[Special:Preferences|个人设置]]中设置了一个有效的电子邮件地址,且未被封禁电子邮件功能,则您可通过“发送邮件”功能来联系相关管理员。您当前的 IP 地址为$3,此次封禁的 ID 为#$5。请在您的查询中注明上述所有信息。",
-'autoblockedtext' => "您的 IP 地址因与另一位已封禁用户的相同而被自动封禁,该用户是由$1封禁的。封禁原因如下
+你可以联系$1或其他[[{{MediaWiki:Grouppage-sysop}}|管理员]]讨论该封禁。只有当你在[[Special:Preferences|系统设置]]确认了电子邮件地址且未被禁止使用“电邮联系”功能时,才可以使用它。你当前的IP地址是$3,该封禁ID是#$5。请在你的询问中包含上面的所有信息。",
+'autoblockedtext' => "你的IP地址因曾被一位被$1封禁的用户使用而被自动封禁。封禁原因
 
 :''$2''
 
 * 开始时间:$8
-* ç»\93æ\9d\9fæ\97¶é\97´ï¼\9a$6
-* 拟封禁对象:$7
+* å\88°æ\9c\9fæ\97¶é\97´ï¼\9a$6
+* 目标用户:$7
 
-您可以联系$1或其他的[[{{MediaWiki:Grouppage-sysop}}|管理员]]以申诉此次封禁。若您已在[[Special:Preferences|个人设置]]中设置了一个有效的电子邮件地址,且未被封禁电子邮件功能,则您可通过“发送邮件”功能来联系相关管理员。您当前的 IP 地址是$3,此次封禁的 ID 为#$5。请在您的查询中注明上述所有信息。",
+你可以联系$1或其他[[{{MediaWiki:Grouppage-sysop}}|管理员]]讨论该封禁。
+
+请注意,只有当你在[[Special:Preferences|系统设置]]确认了电子邮件地址且未被禁止使用“电邮联系”功能时,才可以使用它。
+
+你当前的IP地址是$3,该封禁ID是#$5。请在你的询问中包含上面的所有信息。",
 'blockednoreason' => '无给出原因',
 'whitelistedittext' => '您必须先$1才可编辑页面。',
 'confirmedittext' => '你必须确认你的电子邮件地址才能编辑页面。请通过[[Special:Preferences|系统设置]]设置并确认你的电子邮件地址。',
@@ -974,63 +975,53 @@ $2
 要创建该页面,请在下面的编辑框中输入内容(详情参见[[{{MediaWiki:Helppage}}|帮助页]])。
 如果您误入此页,请点击浏览器中的“返回”按钮。',
 'anontalkpagetext' => "---- ''这是一个还未建立账户的匿名用户的讨论页, 因此我们只能用IP地址来与他或她联络。该IP地址可能由几名用户共享。如果您是一名匿名用户并认为此页上的评语与您无关,请[[Special:UserLogin/signup|创建新账户]]或[[Special:UserLogin|登录]]以避免在未来与其他匿名用户混淆。''",
-'noarticletext' => '本页面目前没有内容。您可以在其他页面中[[Special:Search/{{PAGENAME}}|搜索该页标题]]、<span class="plainlinks">[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} 搜索相关日志]或[{{fullurl:{{FULLPAGENAME}}|action=edit}} 编辑本页]。</span>',
+'noarticletext' => '本页面目前没有内容。你可以在其他页面中[[Special:Search/{{PAGENAME}}|搜索该页标题]]、<span class="plainlinks">[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} 搜索相关日志]或[{{fullurl:{{FULLPAGENAME}}|action=edit}} 编辑本页面]。</span>',
 'noarticletext-nopermission' => '此页目前没有内容。
 您可以在其它页[[Special:Search/{{PAGENAME}}|搜寻此页标题]],或<span class="plainlinks">[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} 搜寻有关日志]</span>,但您没有权限建立此页。',
 'missing-revision' => '“{{PAGENAME}}”的修订#$1不存在。
 
 这通常是因为进入了一个已被删除的页面的历史链接。
 详细信息可以在[{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} 删除日志]中找到。',
-'userpage-userdoesnotexist' => '用户账户"$1"尚未注册。
-请在创建/编辑该页之前进行核对。',
+'userpage-userdoesnotexist' => '用户账户“$1”没有注册。请在创建/编辑本页前检查。',
 'userpage-userdoesnotexist-view' => '用户账户“$1”未曾创建。',
 'blocked-notice-logextract' => '这位用户目前已被封禁。以下提供最近的封禁日志以供参考:',
-'clearyourcache' => "'''注意:'''保存之后,必须清除浏览器缓存才能看到做出的更改。
-* '''火狐(Firefox)/Safari:'''按住“Shift”,同时击“刷新”,或按“Ctrl-F5”或“Ctrl-R”(Mac为“⌘-R”)
-* '''谷歌浏览器(Google Chrome):'''按“Ctrl-Shift-R”(Mac为“⌘-Shift-R”)
-* '''Internet Explorer:'''按住“Ctrl”,同时击“刷新”,或按“Ctrl-F5”
+'clearyourcache' => "'''注意:'''保存之后,必须清除浏览器缓存才能看到做出的更改。
+* '''火狐(Firefox)/Safari:'''按住“Shift”,同时击“刷新”,或按“Ctrl-F5”或“Ctrl-R”(Mac为“⌘-R”)
+* '''Google Chrome:'''按“Ctrl-Shift-R”(Mac为“⌘-Shift-R”)
+* '''Internet Explorer:'''按住“Ctrl”,同时击“刷新”,或按“Ctrl-F5”
 * '''Opera:'''在“工具→首选项”中清除缓存",
 'usercssyoucanpreview' => "'''提示:''' 在保存前请用“{{int:showpreview}}”按钮来测试您新的 CSS 。",
 'userjsyoucanpreview' => "'''提示:''' 在保存前请用“{{int:showpreview}}”按钮来测试您新的 JavaScript 。",
-'usercsspreview' => "'''记住您只是在预览您的个人 CSS。'''
-'''还没有保存!'''",
-'userjspreview' => "'''记住您只是在测试/预览您的个人 JavaScript。'''
-'''还没有保存!'''",
-'sitecsspreview' => "'''记住您现在只是预览此 CSS。'''
-'''尚未保存!'''",
-'sitejspreview' => "'''记住您现在只是预览此 JavaScript 代码。'''
-'''尚未保存!'''",
+'usercsspreview' => "'''请记住你现在只是在预览你的用户CSS。它尚未保存!'''",
+'userjspreview' => "'''请记住你现在只是在测试/预览你的用户JavaScript。它尚未保存!'''",
+'sitecsspreview' => "'''请记住你现在只是在预览该CSS。它尚未保存!'''",
+'sitejspreview' => "'''请记住你现在只是在预览该JavaScript代码。它尚未保存!'''",
 'userinvalidcssjstitle' => "'''警告:''' 不存在皮肤\"\$1\"。注意自定义的 .css 和 .js 页要使用小写标题,例如,{{ns:user}}:Foo/vector.css 不同于 {{ns:user}}:Foo/Vector.css。",
 'updated' => '(已更新)',
 'note' => "'''注意:'''",
 'previewnote' => "'''请记住这仅为预览。'''您的更改还未保存!",
 'continue-editing' => '往编辑框',
-'previewconflict' => 'è¿\99个é¢\84è§\88æ\98¾ç¤ºäº\86ä¸\8aé\9d¢æ\96\87å­\97ç¼\96è¾\91å\8cºä¸­ç\9a\84å\86\85容ã\80\82å®\83们å°\86å\9c¨æ\82¨ä¿\9då­\98å\90\8eå\87ºç\8e°。',
-'session_fail_preview' => "'''抱歉!由于会话数据丢失,我们不能处理您的编辑。'''请重试。如果仍然失败,请尝试[[Special:UserLogout|注销]]然后重新登录。",
-'session_fail_preview_html' => "'''抱歉!我们不能处理您在会话数据丢失时的编辑。'''
+'previewconflict' => '该é¢\84è§\88å\8f\8dæ\98 äº\86ä¸\8aé\9d¢æ\96\87å­\97ç¼\96è¾\91å\8cºä¸­ç\9a\84æ\96\87å­\97å\9c¨ä½ ä¿\9då­\98å\90\8eç\9a\84æ\98¾ç¤ºç\8a¶å\86µ。',
+'session_fail_preview' => "'''对不起!由于会话数据丢失,我们无法处理你的编辑。'''请重试。如果仍然失败,请尝试[[Special:UserLogout|退出登录]]后重新登录。",
+'session_fail_preview_html' => "'''对不起!由于会话数据丢失,我们无法处理你的编辑。'''
 
-''由于{{SITENAME}}允许使用原始的 HTML,为了防范 JavaScript 攻击,预览已被隐藏。''
+''因为{{SITENAME}}已启用原始HTML,为了预防JavaScript攻击,预览被隐藏。''
 
-'''å¦\82æ\9e\9cè¿\99æ\98¯ä¸\80次å\90\88æ³\95ç\9a\84ç¼\96è¾\91ï¼\8c请å°\9dè¯\95é\87\8dè¯\95ã\80\82'''å¦\82æ\9e\9cä¾\9dç\84¶ä¸\8dè¡\8cï¼\8c请[[Special:UserLogout|注é\94\80]]并重新登录。",
+'''å¦\82æ\9e\9c该ç¼\96è¾\91å°\9dè¯\95å\90\88æ³\95ï¼\8c请é\87\8dè¯\95ã\80\82'''å¦\82æ\9e\9cä»\8dç\84¶å¤±è´¥ï¼\8c请å°\9dè¯\95[[Special:UserLogout|é\80\80å\87ºç\99»å½\95]]å\90\8e重新登录。",
 'token_suffix_mismatch' => "'''由于您用户端中的编辑令牌毁损了一些标点符号字元,您的编辑已经被拒绝。'''
 此次编辑被拒绝以防止页面文本损坏。
 这种情况通常在您使用含有故障的网页式匿名代理服务的时候出现。",
-'edit_form_incomplete' => "'''编辑表单的某些部分没有传送至服务器;请检查您的编辑内容是否完整并重试。'''",
+'edit_form_incomplete' => "'''编辑表格的某些部分没有到达服务器,请检查你的编辑是否完整并重试。'''",
 'editing' => '编辑“$1”',
 'creating' => '创建 $1',
 'editingsection' => '编辑“$1”(段落)',
 'editingcomment' => '编辑“$1”(新段落)',
 'editconflict' => '编辑冲突:$1',
-'explainconflict' => "有人在您开始编辑后更改了页面。
-上面的文字框内显示的是目前本页的内容。
-您所做的修改显示在下面的文字框中。
-您应当将您的修改加入至现有的内容中。
-'''只有'''在上面文字框中的内容会在您点击“{{int:savearticle}}”后被保存。",
-'yourtext' => '您的文字',
+'explainconflict' => "其他用户在你开始编辑后更改了该页面。上面的文字区含有该页面当前的文字。下面的文字区显示你的更改。你必须把你的更改合并至现有文字。'''只有'''当你单击“{{int:savearticle}}”后,上面的文字区中的文字才会被保存。",
+'yourtext' => '你的文字',
 'storedversion' => '已保存的版本',
 'nonunicodebrowser' => "'''警告:您的浏览器不兼容Unicode编码。'''这里有一个工作区将使您能安全地编辑页面:非ASCII字符将以十六进制编码方式出现在编辑框中。",
-'editingold' => "'''警告:您正在编辑的是本页的旧版本。'''
-如果您保存它的话,在旧版本之后的任何修改都将丢失。",
+'editingold' => "'''警告:你正在编辑的是本页面的旧版本。'''如果你保存该编辑,该版本后的所有更改都会丢失。",
 'yourdiff' => '差异',
 'copyrightwarning' => "请注意您对{{SITENAME}}的所有贡献都被认为是在$2下发布,请查看在$1的细节。
 如果您不希望您的文字被任意修改和再散布,请不要提交。<br />
@@ -1057,12 +1048,12 @@ $2
 'template-semiprotected' => '(半保护)',
 'hiddencategories' => '本页面属于$1个隐藏分类:',
 'edittools' => '<!-- 这里的文字将显示在编辑和上传表格下面。 -->',
-'nocreatetext' => '{{SITENAME}}限制了创建新页面功能。您可以返回并编辑已有的页面,或者[[Special:UserLogin|登录或创建新账户]]。',
-'nocreate-loggedin' => '没有权限创建新页面。',
+'nocreatetext' => '{{SITENAME}}已经限制创建新页面功能。你可以返回编辑现有页面或[[Special:UserLogin|登录或创建账户]]。',
+'nocreate-loggedin' => '没有权限创建新页面。',
 'sectioneditnotsupported-title' => '段落编辑不支持',
 'sectioneditnotsupported-text' => '本页面不支持段落编辑。',
 'permissionserrors' => '权限错误',
-'permissionserrorstext' => 'å\9b ä¸ºä¸\8bå\88\97{{PLURAL:$1|å\8e\9få\9b }}ï¼\8cæ\82¨æ²¡æ\9c\89æ\9d\83é\99\90æ\89§行该操作:',
+'permissionserrorstext' => 'å\9b ä¸ºä»¥ä¸\8b{{PLURAL:$1|å\8e\9få\9b }}ï¼\8c你没æ\9c\89æ\9d\83é\99\90è¿\9b行该操作:',
 'permissionserrorstext-withaction' => '因为以下{{PLURAL:$1|原因}},你没有权限$2:',
 'recreate-moveddeleted-warn' => "'''警告:你正在重新创建曾经被删除的页面。'''
 
@@ -1074,7 +1065,7 @@ $2
 'edit-gone-missing' => '不能更新页面。
 它可能刚刚被删除。',
 'edit-conflict' => '编辑冲突。',
-'edit-no-change' => '由于文字无任何改动,您的编辑已被忽略。',
+'edit-no-change' => '因为没有文字更改,你的编辑已被忽略。',
 'edit-already-exists' => '不可以建立一个新页面。
 它已经存在。',
 'defaultmessagetext' => '默认消息文本',
@@ -1111,10 +1102,10 @@ $2
 'converter-manual-rule-error' => '手动语言转换规则中检测到错误',
 
 # "Undo" feature
-'undo-success' => '此编辑可被撤销。请检查以下对比以核实这正是您想做的,然后保存以下更改完成撤销编辑。',
+'undo-success' => '该编辑可以被撤销。请检查下面的对比以核实你想要撤销的内容,然后保存下面的更改以完成撤销。',
 'undo-failure' => '因存在冲突的中间编辑,本编辑不能撤销。',
 'undo-norev' => '由于其修订版本不存在或已删除,此编辑不能撤销。',
-'undo-summary' => '撤销由[[Special:Contributions/$2|$2]]([[User talk:$2|讨论]])所作出的修订$1',
+'undo-summary' => '撤销[[Special:Contributions/$2|$2]]([[User talk:$2|讨论]])的版本$1',
 
 # Account creation failure
 'cantcreateaccounttitle' => '无法创建账户',
@@ -1140,7 +1131,7 @@ $3的理由是''$2''",
 'histlegend' => "差异选择:选出需要对比的版本,按“回车键”或下方的按钮进行对比。<br />
 说明:'''({{int:cur}})'''=与最后版本之间的差异,'''({{int:last}})'''=与上一版本之间的差异,'''{{int:minoreditletter}}'''=小编辑。",
 'history-fieldset-title' => '浏览历史',
-'history-show-deleted' => '仅删除的',
+'history-show-deleted' => '仅删除的',
 'histfirst' => '最早',
 'histlast' => '最后',
 'historysize' => '($1字节)',
@@ -1159,13 +1150,12 @@ $3的理由是''$2''",
 'rev-deleted-event' => '(日志条目被删除)',
 'rev-deleted-user-contribs' => '[用户名或IP地址被删除 - 编辑在贡献中隐藏]',
 'rev-deleted-text-permission' => "本页面版本已被'''删除'''。详情请见[{{fullurl:{{#Special:Log}}/delete|page={{PAGENAMEE}}}} 删除日志]。",
-'rev-deleted-text-unhide' => "æ\9c¬é¡µé\9d¢ç\9a\84修订ç\89\88已被'''å\88 é\99¤'''ã\80\82详æ\83\85请è§\81[{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} å\88 é\99¤æ\97¥å¿\97\80\82æ\82¨å\8f¯ä»¥[$1 æ\9f¥ç\9c\8bå½\93å\89\8dç\89\88æ\9c¬]以继续。",
+'rev-deleted-text-unhide' => "æ\9c¬é¡µé\9d¢ç\89\88æ\9c¬å·²è¢«'''å\88 é\99¤'''ã\80\82详æ\83\85请è§\81[{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} å\88 é\99¤æ\97¥å¿\97\80\82å¦\82æ\9e\9cä½ æ\83³ç»§ç»­æ\93\8dä½\9cï¼\8cä½ ä»\8dç\84¶å\8f¯ä»¥[$1 æ\9f¥ç\9c\8bæ\9c¬ç\89\88æ\9c¬]。",
 'rev-suppressed-text-unhide' => "该页面修订已经被'''监督隐藏'''。在[{{fullurl:{{#Special:Log}}/suppress|page={{FULLPAGENAMEE}}}} 监督日志]中可以找到详细的信息。如果您想继续的话,您可以仍然[$1 去查看这次修订]。",
-'rev-deleted-text-view' => "æ\9c¬é¡µé\9d¢ç\9a\84修订ç\89\88已被'''å\88 é\99¤'''ã\80\82æ\82¨可以查看它,详情请见[{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} 删除日志]。",
+'rev-deleted-text-view' => "æ\9c¬é¡µé\9d¢ç\89\88æ\9c¬å·²è¢«'''å\88 é\99¤'''ã\80\82ä½ 可以查看它,详情请见[{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} 删除日志]。",
 'rev-suppressed-text-view' => "该页面修订已经被'''监督隐藏'''。您可以查看它。在[{{fullurl:{{#Special:Log}}/suppress|page={{FULLPAGENAMEE}}}} 监督日志]中可以找到详细的信息。",
-'rev-deleted-no-diff' => "因为其中一次修订已被'''删除''',您不可以查看这个差异。
-在[{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} 删除日志]中可以找到更多的信息。",
-'rev-suppressed-no-diff' => "该页面的其中一次修订版已被'''删除''',您无法查看这个对比。",
+'rev-deleted-no-diff' => "你不能查看该差异,因为其中一个版本已被'''删除'''。详情请见[{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} 删除日志]。",
+'rev-suppressed-no-diff' => "你不能查看该差异,因为其中一个版本已被'''删除'''。",
 'rev-deleted-unhide-diff' => "该差异对比其中的一个修订版本已经被'''删除'''。在[{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} 删除日志]中可以找到更多的信息。如果您想继续的话,您仍然可以[$1 查看这次修订]。",
 'rev-suppressed-unhide-diff' => "该页面的其中一次修订已经被'''监督隐藏'''。
 在[{{fullurl:{{#Special:Log}}/suppress|page={{FULLPAGENAMEE}}}} 监督日志]中可以找到更多的资料。如果您想继续的话,您可以仍然[$1 去查看这次修订]。",
@@ -1182,16 +1172,17 @@ $3的理由是''$2''",
 'revdelete-nologid-title' => '无效的日志项目',
 'revdelete-nologid-text' => '您尚未指定一个目标日志项目去进行这个动作或指定的项目不存在。',
 'revdelete-no-file' => '指定的文件不存在。',
-'revdelete-show-file-confirm' => '您是否想查看文件“<nowiki>$1</nowiki>”于$2 $3时的已被删除的修订版本?',
+'revdelete-show-file-confirm' => '确定要查看文件“<nowiki>$1</nowiki>”于$2$3被删除的版本吗?',
 'revdelete-show-file-submit' => '是',
 'revdelete-selected' => "'''选取'''[[:$1]]'''的$2次修订:'''",
 'logdelete-selected' => "'''{{PLURAL:$1|选取的日志项目}}:'''",
 'revdelete-text' => "'''删除的修订仍将显示在页面历史中, 但它们的文本内容已不能被公众访问。'''
 在{{SITENAME}}的其他管理员将仍能访问隐藏的内容并通过与此相同的界面恢复删除,除非站点工作者进行了一些附加的限制。",
 'revdelete-confirm' => '请确认您肯定去做的话,您就要明白到后果,以及这个程序符合[[{{MediaWiki:Policy-url}}|政策]]。',
-'revdelete-suppress-text' => "'''只有'''出现下列情况下才应阻止访问:
-* 可能虚假的个人信息
-*: ''家庭地址、电话号码、身份证号码等等。''",
+'revdelete-suppress-text' => "阻止应该'''只'''在以下情形使用:
+*潜在的诽谤信息
+*不合适的个人信息
+*:''家庭地址、电话号码和社保号码等。''",
 'revdelete-legend' => '设置可见性之限制',
 'revdelete-hide-text' => '隐藏版本文字',
 'revdelete-hide-image' => '隐藏文件内容',
@@ -1245,7 +1236,7 @@ $1",
 'mergehistory-from' => '来源页面:',
 'mergehistory-into' => '目的页面:',
 'mergehistory-list' => '可以合并的编辑历史',
-'mergehistory-merge' => 'ä¸\8bå\88\97[[:$1]]ç\9a\84修订å\8f¯ä»¥å\90\88并å\88°[[:$2]]ã\80\82ç\94¨è¯¥é\80\89项æ\8c\89é\92®å\88\97å\8e»å\90\88并å\8fªæ\9c\89å\9c¨æ\8c\87å®\9aæ\97¶é\97´ä»¥å\89\8dæ\89\80å\88\9b建ç\9a\84修订ã\80\82è¦\81ç\95\99æ\84\8fç\9a\84æ\98¯ä½¿ç\94¨å¯¼è\88ªé\93¾æ\8e¥ä¾¿ä¼\9aé\87\8d设è¿\99ä¸\80æ \8f。',
+'mergehistory-merge' => '以ä¸\8b[[:$1]]ç\9a\84ç\89\88æ\9c¬å\8f¯ä»¥å\90\88并è\87³[[:$2]]ã\80\82请使ç\94¨å\8d\95é\80\89æ\8c\89é\92®å\88\97以å\90\88并è\87³å\9c¨æ\8c\87å®\9aæ\97¶é\97´å\8f\8aä¹\8bå\89\8då\88\9b建ç\9a\84ç\89\88æ\9c¬ã\80\82请注æ\84\8fï¼\8c使ç\94¨å¯¼è\88ªé\93¾æ\8e¥ä¼\9aé\87\8d置该å\88\97。',
 'mergehistory-go' => '显示可以合并的编辑',
 'mergehistory-submit' => '合并版本',
 'mergehistory-empty' => '没有可以合并的版本。',
@@ -1331,7 +1322,7 @@ $1",
 'showingresults' => "下面显示从第'''$2'''条结果开始的'''$1'''条结果。",
 'showingresultsnum' => "下面显示从第'''$2'''条结果开始的'''$3'''条结果。",
 'showingresultsheader' => "关于'''$4'''的{{PLURAL:$5|第'''$1'''条至第'''$3'''条结果|第'''$1'''条至第'''$2'''条结果,共'''$3'''条结果}}",
-'nonefound' => "'''注意''':只有部分名字空间的页面会被默认搜索。尝试在您的搜索语句前添加“all:”前缀,这样可以搜索全部页面(包括讨论页、模板等),或者您也可使用所需名字空间作为前缀。",
+'nonefound' => "'''注意''':只有某些名字空间被默认搜索。请尝试给你的搜索内容添加前缀“all:”以搜索全部内容(包括讨论页面、模板等)或使用期望的名字空间作为前缀。",
 'search-nonefound' => '找不到和查询相匹配的结果。',
 'powersearch' => '高级搜索',
 'powersearch-legend' => '高级搜索',
@@ -1357,7 +1348,7 @@ $1",
 'preferences' => '系统设置',
 'mypreferences' => '系统设置',
 'prefs-edits' => '编辑数量:',
-'prefsnologin' => '未登录',
+'prefsnologin' => '未登录',
 'prefsnologintext' => '您必须先<span class="plainlinks">[{{fullurl:{{#Special:UserLogin}}|returnto=$1}} 登录]</span>才能设置个人参数。',
 'changepassword' => '更改密码',
 'prefs-skin' => '皮肤',
@@ -1391,13 +1382,13 @@ $1",
 'searchresultshead' => '搜索',
 'resultsperpage' => '每页显示链接数:',
 'stub-threshold' => '<a href="#" class="stub">短页面链接</a>格式阈值(字节):',
-'stub-threshold-disabled' => '已用',
+'stub-threshold-disabled' => '已用',
 'recentchangesdays' => '最近更改中显示的天数:',
 'recentchangesdays-max' => '最多$1天',
 'recentchangescount' => '默认显示的编辑数:',
 'prefs-help-recentchangescount' => '该项包含最近更改、页面历史和日志。',
 'prefs-help-watchlist-token' => '此栏填写的密钥可以生成您监视列表的RSS源。任何知晓本栏密钥的人都能阅读您的监视列表,因此请使用安全的数值。这里已提供了一个随机生成的数值供您选择:$1',
-'savedprefs' => '你的系统设置已保存。',
+'savedprefs' => '你的系统设置已保存。',
 'timezonelegend' => '时区:',
 'localtime' => '当地时间:',
 'timezoneuseserverdefault' => '使用wiki默认值($1)',
@@ -1421,23 +1412,23 @@ $1",
 'defaultns' => '否则在这些名字空间中搜索:',
 'default' => '默认',
 'prefs-files' => '文件',
-'prefs-custom-css' => '自定义 CSS',
-'prefs-custom-js' => '自定义 JavaScript',
+'prefs-custom-css' => '自定义CSS',
+'prefs-custom-js' => '自定义JavaScript',
 'prefs-common-css-js' => '所有皮肤共用的CSS/JavaScript:',
-'prefs-reset-intro' => '您可以通过本页面重置您的系统设置为默认值。此操作不可撤销。',
+'prefs-reset-intro' => '你可以使用本页面重置你的系统设置为网站默认值。该操作不能撤销。',
 'prefs-emailconfirm-label' => '电子邮件确认:',
 'prefs-textboxsize' => '编辑框大小',
 'youremail' => '电子邮件:',
 'username' => '{{GENDER:$1|用户名}}:',
 'uid' => '{{GENDER:$1|用户}}ID:',
-'prefs-memberingroups' => '{{PLURAL:$1|用户组}}的{{GENDER:$2|成员}}:',
+'prefs-memberingroups' => '{{GENDER:$2|用户}}{{PLURAL:$1|组}}:',
 'prefs-registration' => '注册时间:',
 'yourrealname' => '真实姓名:',
 'yourlanguage' => '语言:',
 'yourvariant' => '内容语言变种:',
 'prefs-help-variant' => '您希望用于显示本站内容的语种或拼写语系。',
 'yournick' => '新签名:',
-'prefs-help-signature' => '讨论页面上的评论应使用“<nowiki>~~~~</nowiki>”签名,它会自动转换为您的签名和时间戳。',
+'prefs-help-signature' => '讨论页面上的评论应该使用“<nowiki>~~~~</nowiki>”签名,它会自动转换为你的签名及时间戳。',
 'badsig' => '错误的原始签名。请检查HTML标签。',
 'badsiglength' => '签名过长。请不超过$1个字符。',
 'yourgender' => '性别:',
@@ -1446,7 +1437,7 @@ $1",
 'gender-female' => '女',
 'prefs-help-gender' => '选填项目。使软件使用正确的性别称呼。该信息将会公开。',
 'email' => '电子邮件',
-'prefs-help-realname' => '真实姓名是可选的项目。如果您选择提供它,它将会用于贡献署名。',
+'prefs-help-realname' => '真实姓名是选填项目。如果你选择提供它,它将会用于贡献署名。',
 'prefs-help-email' => '电子邮件地址是选填项目。但是在你忘记密码需要重置密码时需要电子邮件地址。',
 'prefs-help-email-others' => '你亦可以选择让其他用户通过你的用户页或讨论页上的链接用电子邮件联系你。其他用户联系你时你的电子邮件地址不会显示。',
 'prefs-help-email-required' => '电子邮件地址是必填项目。',
@@ -1479,7 +1470,7 @@ $1",
 'saveusergroups' => '保存用户组',
 'userrights-groupsmember' => '用户组:',
 'userrights-groupsmember-auto' => '自动用户组:',
-'userrights-groups-help' => '可以更改该用户的用户组:
+'userrights-groups-help' => '可以更改该用户的用户组:
 * 选中的选项框表示该用户属于该用户组。
 * 未选中的选项框表示该用户不属于该用户组。
 * 星号(*)表示一旦添加该用户组后不能删除,反之亦然。',
@@ -1487,9 +1478,9 @@ $1",
 'userrights-no-interwiki' => '您并没有权限去编辑在其它wiki上的用户权限。',
 'userrights-nodatabase' => '数据库$1不存在或并非为本地的。',
 'userrights-nologin' => '您必须要以管理员帐户[[Special:UserLogin|登录]]之后才可以指定用户权限。',
-'userrights-notallowed' => '您的帐户无添加或删除用户权限的权限。',
-'userrights-changeable-col' => '可以更改的用户组',
-'userrights-unchangeable-col' => '不能更改的用户组',
+'userrights-notallowed' => '你的账户没有权限添加或删除用户权限。',
+'userrights-changeable-col' => '可以更改的用户组',
+'userrights-unchangeable-col' => '不能更改的用户组',
 
 # Groups
 'group' => '用户组:',
@@ -1549,7 +1540,7 @@ $1",
 'right-suppressrevision' => '审查和恢复管理员隐藏的版本',
 'right-suppressionlog' => '查看非公开日志',
 'right-block' => '阻止其他用户编辑',
-'right-blockemail' => '阻止用户发送邮件',
+'right-blockemail' => '阻止用户电邮联系',
 'right-hideuser' => '封禁并隐藏用户名',
 'right-ipblock-exempt' => '避开IP封禁、自动封禁和IP段封禁',
 'right-proxyunbannable' => '避开代理服务器的自动封禁',
@@ -1574,7 +1565,7 @@ $1",
 'right-userrights-interwiki' => '编辑其它wiki的用户的用户权限',
 'right-siteadmin' => '锁定和解锁数据库',
 'right-override-export-depth' => '导出含有链接页面深度为5的页面',
-'right-sendemail' => '向其他用户发送邮件',
+'right-sendemail' => '电邮联系其他用户',
 'right-passwordreset' => '查看密码重置电子邮件',
 
 # Special:Log/newusers
@@ -1620,7 +1611,7 @@ $1",
 'action-userrights' => '编辑所有用户的权限',
 'action-userrights-interwiki' => '编辑其它wiki的用户的用户权限',
 'action-siteadmin' => '锁定或解锁数据库',
-'action-sendemail' => '通过邮件联系其他用户',
+'action-sendemail' => '电邮联系其他用户',
 
 # Recent changes
 'nchanges' => '$1次更改',
@@ -1653,8 +1644,8 @@ $1",
 'rc_categories' => '分类限制(用“|”分隔)',
 'rc_categories_any' => '任意',
 'rc-change-size-new' => '更改后$1字节',
-'newsectionsummary' => '/* $1 */ 新段落',
-'rc-enhanced-expand' => '显示细节(需JavaScript支持)',
+'newsectionsummary' => '/*$1*/新段落',
+'rc-enhanced-expand' => '显示细节(需要JavaScript)',
 'rc-enhanced-hide' => '隐藏细节',
 'rc-old-title' => '最初被创建为" $1 "',
 
@@ -1742,23 +1733,21 @@ $1",
 'fileexists-thumbnail-yes' => "此文件可能是另一幅图像的缩小版本''(缩略图)''。 [[$1|thumb]]
 请仔细检查该文件<strong>[[:$1]]</strong>。
 如果被检查文件与原始大小的图像是同一幅图像,您无需上传多余的缩略图。",
-'file-thumbnail-no' => "文件名以<strong>$1</strong>开头。它可能是另一幅图像的缩小版本''(缩略图)''。
-如果您有该图像完整分辨率的版本,请上传该完整版本。否则请修改文件名。",
+'file-thumbnail-no' => "文件名以<strong>$1</strong>开始。它似乎是缩小的图像''(缩略图)''。如果你有完整分辨率的该图像,请上传它,否则请更改文件名。",
 'fileexists-forbidden' => '已存在相同名称的文件,且不能覆盖;请返回并用一个新的名称来上传此文件。[[File:$1|thumb|center|$1]]',
-'fileexists-shared-forbidden' => '在共享文件库中已存在同名文件。
-如果您仍然想继续上传,请返回并使用一个新的文件名来上传此文件。[[File:$1|thumb|center|$1]]',
-'file-exists-duplicate' => '这个文件与下列{{PLURAL:$1|一|多}}个文件重复:',
+'fileexists-shared-forbidden' => '共享文件库中存在该名称的文件。如果你仍想上传你的文件,请返回使用其他名称。[[File:$1|thumb|center|$1]]',
+'file-exists-duplicate' => '本文件是以下{{PLURAL:$1|文件}}的副本:',
 'file-deleted-duplicate' => '一个相同名称的文件 ([[:$1]]) 在先前删除过。您应该在重新上传之前检查一下该文件之删除纪录。',
 'uploadwarning' => '上传警告',
 'uploadwarning-text' => '请修改下面的文件说明并重试。',
 'savefile' => '保存文件',
 'uploadedimage' => '上传“[[$1]]”',
 'overwroteimage' => '上传“[[$1]]”的新版本',
-'uploaddisabled' => '上传己用。',
-'copyuploaddisabled' => '通过网址上传功能已禁用。',
+'uploaddisabled' => '上传己用。',
+'copyuploaddisabled' => 'URL上传已停用。',
 'uploadfromurl-queued' => '上传已被列入队列。',
-'uploaddisabledtext' => '文件上传已用。',
-'php-uploaddisabledtext' => 'PHP 设置已禁用文件上传功能。请检查 file_uploads 设置。',
+'uploaddisabledtext' => '文件上传已用。',
+'php-uploaddisabledtext' => 'PHP文件上传停用。请检查file_uploads设置。',
 'uploadscripted' => '该文件包含可能被网络浏览器错误解释的 HTML 或脚本代码。',
 'uploadvirus' => '该文件包含病毒!
 详情:$1',
@@ -1846,11 +1835,11 @@ $1',
 不能正确检查安全。',
 
 # Special:UploadStash
-'uploadstash' => '文件贮藏',
+'uploadstash' => '上传隐藏',
 'uploadstash-summary' => '这个页面提供已经上传(或者上传中)但未发布到wiki之文件存取。这些文件除了上传的用户之外不会被其他人可见。',
 'uploadstash-clear' => '清除贮藏文件',
-'uploadstash-nofiles' => '您没有已贮藏的文件。',
-'uploadstash-badtoken' => '执行操作不成功,或者您的编辑信息已经过期。请重试。',
+'uploadstash-nofiles' => '你没有被隐藏的文件。',
+'uploadstash-badtoken' => '该操作执行失败,可能是因为你的编辑凭证已过期。请重试。',
 'uploadstash-errclear' => '清除文件不成功。',
 'uploadstash-refresh' => '更新文件清单',
 'invalid-chunk-offset' => '无效区块偏移量',
@@ -1867,7 +1856,7 @@ $1',
 'img-auth-nofile' => '文件“$1”不存在。',
 'img-auth-isdir' => '您正试图访问目录“$1”。您只能访问文件。',
 'img-auth-streaming' => '流式化“$1”中。',
-'img-auth-public' => 'img_auth.php 的功能是从私有 wiki 输出文件。但本 wiki 已被设置为公共 wiki。出于安全考虑,img_auth.php 已被禁用。',
+'img-auth-public' => 'img_auth.php的功能是从非公开wiki输出文件。本wiki已被设置为公开。为了最佳安全状况,img_auth.php已停用。',
 'img-auth-noread' => '用户无权读取“$1”。',
 'img-auth-bad-query-string' => 'URL 有一个无效的查询字符串。',
 
@@ -1910,7 +1899,7 @@ $1',
 # File description page
 'file-anchor-link' => '文件',
 'filehist' => '文件历史',
-'filehist-help' => '查看某一时刻的文件,请击相应的日期/时间。',
+'filehist-help' => '查看某一时刻的文件,请击相应的日期/时间。',
 'filehist-deleteall' => '删除全部',
 'filehist-deleteone' => '删除',
 'filehist-revert' => '恢复',
@@ -1925,14 +1914,14 @@ $1',
 'filehist-comment' => '评论',
 'filehist-missing' => '文件遗失',
 'imagelinks' => '文件用途',
-'linkstoimage' => 'ä¸\8bå\88\97$1个页é\9d¢é\93¾æ\8e¥å\88°本文件:',
+'linkstoimage' => '以ä¸\8b{{PLURAL:$1|页é\9d¢|$1个页é\9d¢}}é\93¾æ\8e¥è\87³本文件:',
 'linkstoimage-more' => '多于$1个页面连接到这个文件。
 下面的列表只列示了连去这个文件的最首$1个页面。
 一个[[Special:WhatLinksHere/$2|完整的列表]]可以提供。',
 'nolinkstoimage' => '没有页面链接到本文件。',
 'morelinkstoimage' => '查看连接到这个文件的[[Special:WhatLinksHere/$1|更多链接]]。',
 'linkstoimage-redirect' => '$1(文件重定向)$2',
-'duplicatesoffile' => 'ä¸\8bå\88\97$1个æ\96\87件ä¸\8e该æ\96\87件é\87\8då¤\8d([[Special:FileDuplicateSearch/$2|更多细节]]):',
+'duplicatesoffile' => '以ä¸\8b{{PLURAL:$1|æ\96\87件|$1个æ\96\87件}}æ\98¯æ\9c¬æ\96\87件ç\9a\84å\89¯æ\9c¬([[Special:FileDuplicateSearch/$2|更多细节]]):',
 'sharedupload' => '该文件来自于$1,它可能在其它计划项目中被应用。',
 'sharedupload-desc-there' => '该文件来自于$1,它可能在其它计划项目中被应用。
 请参阅在[$2 文件描述页面]以了解其相关信息。',
@@ -1963,8 +1952,8 @@ $1',
 # File deletion
 'filedelete' => '删除$1',
 'filedelete-legend' => '删除文件',
-'filedelete-intro' => "您将删除文件'''[[Media:$1|$1]]'''。",
-'filedelete-intro-old' => "您正在删除'''[[Media:$1|$1]]'''于[$4 $2 $3]的版本。",
+'filedelete-intro' => "你将要删除文件'''[[Media:$1|$1]]'''及其全部历史。",
+'filedelete-intro-old' => "你正在删除'''[[Media:$1|$1]]'''[$4 $2$3]的版本。",
 'filedelete-comment' => '原因:',
 'filedelete-submit' => '删除',
 'filedelete-success' => "'''$1'''已经删除。",
@@ -1978,7 +1967,7 @@ $1',
 ** 侵犯版权
 ** 重复文件',
 'filedelete-edit-reasonlist' => '编辑删除埋由',
-'filedelete-maintenance' => '处于维护时将暂时禁用文件删除和恢复。',
+'filedelete-maintenance' => '维护期间文件删除和恢复暂时停用。',
 'filedelete-maintenance-title' => '无法删除文件',
 
 # MIME search
@@ -2032,7 +2021,7 @@ $1',
 'disambiguations-text' => "以下的页面都有到'''消歧义页'''的链接,但它们可能可以链接到更适当的页面。<br />一个页面如果使用了[[MediaWiki:Disambiguationspage]]内的模板,则会被视为消歧义页。",
 
 'doubleredirects' => '双重重定向页',
-'doubleredirectstext' => '此页å\88\97å\87ºäº\86æ\89\80æ\9c\89é\87\8då®\9aå\90\91å\88°å\8f¦ä¸\80é\87\8då®\9aå\90\91页é\9d¢ç\9a\84页é\9d¢ã\80\82æ¯\8fä¸\80è¡\8cé\83½å\8c\85å\90«æ\9c\89å\88°ç¬¬ä¸\80å\92\8c第äº\8c个é\87\8då®\9aå\90\91页é\9d¢ç\9a\84é\93¾æ\8e¥ï¼\8c以å\8f\8a第äº\8c个é\87\8då®\9aå\90\91页é\9d¢ç\9a\84ç\9b®æ \87â\80\94â\80\94é\80\9a常就æ\98¯â\80\9cç\9c\9fæ­£ç\9a\84â\80\9dç\9b®æ \87页é\9d¢ï¼\8cä¹\9få°±æ\98¯ç¬¬ä¸\80个é\87\8då®\9aå\90\91页é\9d¢åº\94该æ\8c\87å\90\91ç\9a\84页é\9d¢ã\80\82<del>å·²å\88\92å\8e»</del>ç\9a\84æ\9d¡ç\9b®æ\98¯å·²ç»\8f解å\86³ç\9a\84项ç\9b®。',
+'doubleredirectstext' => 'æ\9c¬é¡µé\9d¢å\88\97å\87ºé\87\8då®\9aå\90\91è\87³å\85¶ä»\96é\87\8då®\9aå\90\91页ç\9a\84页é\9d¢ã\80\82æ¯\8fè¡\8cå\90«æ\9c\89第ä¸\80å\8f\8a第äº\8cé\87\8då®\9aå\90\91ç\9a\84é\93¾æ\8e¥å\92\8c第äº\8cé\87\8då®\9aå\90\91ç\9a\84ç\9b®æ \87ï¼\88é\80\9a常æ\98¯ç¬¬ä¸\80é\87\8då®\9aå\90\91åº\94该æ\8c\87å\90\91ç\9a\84â\80\9cç\9c\9få®\9eâ\80\9dç\9b®æ \87页é\9d¢ï¼\89ã\80\82<del>带å\88 é\99¤çº¿ç\9a\84</del>æ\9d¡ç\9b®å·²è¢«è§£å\86³。',
 'double-redirect-fixed-move' => '[[$1]]已被移动。它现在重定向至[[$2]]。',
 'double-redirect-fixed-maintenance' => '修复双重重定向自[[$1]]至[[$2]]。',
 'double-redirect-fixer' => '重定向页修复器',
@@ -2059,7 +2048,7 @@ $1',
 'nviews' => '$1次浏览',
 'nimagelinks' => '用于$1个页面中',
 'ntransclusions' => '用于$1个页面中',
-'specialpage-empty' => '该报告结果为空。',
+'specialpage-empty' => '无该报告的结果。',
 'lonelypages' => '孤立页面',
 'lonelypagestext' => '以下页面尚未被{{SITENAME}}中的其它页面链接或被之包含。',
 'uncategorizedpages' => '未归类页面',
@@ -2117,12 +2106,12 @@ $1',
 'pager-newer-n' => '前$1个',
 'pager-older-n' => '后$1个',
 'suppress' => '监督',
-'querypage-disabled' => 'æ­¤ç\89¹æ®\8a页é\9d¢ç\94±äº\8eæ\80§è\83½å\8e\9få\9b å·²è¢«ç¦\81用。',
+'querypage-disabled' => 'æ\9c¬ç\89¹æ®\8a页é\9d¢å\9b æ\80§è\83½é\97®é¢\98è\80\8cå\81\9c用。',
 
 # Book sources
 'booksources' => '网络书源',
 'booksources-search-legend' => '搜索网络书源',
-'booksources-isbn' => 'ISBN:',
+'booksources-isbn' => 'ISBN',
 'booksources-go' => '提交',
 'booksources-text' => '以下是一些网络书店的链接列表,其中可能有您要找的书籍的更多信息:',
 'booksources-invalid-isbn' => '提供的ISBN号码并不正确,请检查原始复制来源号码是否有误。',
@@ -2156,7 +2145,7 @@ $1',
 'allpages-hide-redirects' => '隐藏重定向页',
 
 # SpecialCachedPage
-'cachedspecial-viewing-cached-ttl' => '您正在浏览本页的缓存版本,至多可能存在 $1 的延迟。',
+'cachedspecial-viewing-cached-ttl' => '你正在查看本页面至少$1前的缓存版本。',
 'cachedspecial-viewing-cached-ts' => '您正浏览此页的缓存版本,不一定是最新的完整版本。',
 'cachedspecial-refresh-now' => '查看最新的。',
 
@@ -2170,8 +2159,8 @@ $1',
 'special-categories-sort-abc' => '按字母排列',
 
 # Special:DeletedContributions
-'deletedcontributions' => '删除的用户贡献',
-'deletedcontributions-title' => '删除的用户贡献',
+'deletedcontributions' => '删除的用户贡献',
+'deletedcontributions-title' => '删除的用户贡献',
 'sp-deletedcontributions-contribs' => '贡献',
 
 # Special:LinkSearch
@@ -2219,18 +2208,17 @@ $1',
 'listgrouprights-removegroup-self-all' => '删除自己的账户的所有用户组',
 
 # E-mail user
-'mailnologin' => '没æ\9c\89å\8f\91é\80\81地址',
+'mailnologin' => 'æ\97 ç\94µå­\90é\82®ä»¶地址',
 'mailnologintext' => '你必须[[Special:UserLogin|登录]]并在你的[[Special:Preferences|系统设置]]中拥有有效的电子邮件地址才能向其他用户发送电子邮件。',
 'emailuser' => '电邮联系',
-'emailuser-title-target' => '邮件联系该{{GENDER:$1|用户}}',
-'emailuser-title-notarget' => '邮件联系',
+'emailuser-title-target' => '电邮联系该{{GENDER:$1|用户}}',
+'emailuser-title-notarget' => '电邮联系',
 'emailpage' => '电邮联系',
-'emailpagetext' => '您可以使用下面的表单向该{{GENDER:$1|用户}}发送电子邮件消息。
-您在[[Special:Preferences|个人设置]]中输入的电子邮件地址将显示为该邮件的“发件人”地址,所以收件人可以直接回复给您。',
+'emailpagetext' => '你可以使用下面的表格发送电子邮件信息至该{{GENDER:$1|用户}}。你在[[Special:Preferences|系统设置]]中输入的电子邮件地址将显示为邮件的“发件人”地址,所以该用户将可以直接回复你。',
 'usermailererror' => 'Mail 对象返回错误:',
 'defemailsubject' => '{{SITENAME}}来自用户“$1”的电子邮件',
-'usermaildisabled' => '邮件发送功能已禁用',
-'usermaildisabledtext' => '您不可以给这个 wiki 上的其他用户发送邮件',
+'usermaildisabled' => '用户电子邮件停用',
+'usermaildisabledtext' => '你不能发送电子邮件至本wiki的其他用户',
 'noemailtitle' => '无电子邮件地址',
 'noemailtext' => '该用户还没有指定一个有效的电子邮件地址。',
 'nowikiemailtitle' => '禁止电子邮件',
@@ -2249,7 +2237,7 @@ $1',
 'emailccsubject' => '您发送给$1的消息的副本:$2',
 'emailsent' => '电子邮件已发送',
 'emailsenttext' => '您的电子邮件已经发出。',
-'emailuserfooter' => '本邮件由{{SITENAME}}的“电邮用户”功能从$1发送至$2。',
+'emailuserfooter' => '本电子邮件是通过{{SITENAME}}的“电邮联系”功能被$1发送至$2的。',
 
 # User Messenger
 'usermessage-summary' => '留下系统信息。',
@@ -2259,15 +2247,14 @@ $1',
 'watchlist' => '监视列表',
 'mywatchlist' => '监视列表',
 'watchlistfor2' => '$1的监视列表$2',
-'nowatchlist' => '的监视列表为空。',
+'nowatchlist' => '的监视列表为空。',
 'watchlistanontext' => '请$1以查看或编辑您的监视列表。',
 'watchnologin' => '未登录',
 'watchnologintext' => '您必须先[[Special:UserLogin|登录]]才能更改您的监视列表。',
 'addwatch' => '添加至监视列表',
-'addedwatchtext' => '页面“[[:$1]]”已添加至您的[[Special:Watchlist|监视列表]]。
-本页面及其讨论页面的新增更改将会列入监视列表。',
+'addedwatchtext' => '页面“[[:$1]]”已添加至你的[[Special:Watchlist|监视列表]]。本页面及其讨论页面的新增更改将会列入监视列表。',
 'removewatch' => '从监视列表中删除',
-'removedwatchtext' => '页面“[[:$1]]”已从[[Special:Watchlist|的监视列表]]中删除。',
+'removedwatchtext' => '页面“[[:$1]]”已从[[Special:Watchlist|的监视列表]]中删除。',
 'watch' => '监视',
 'watchthispage' => '监视本页',
 'unwatch' => '取消监视',
@@ -2275,9 +2262,9 @@ $1',
 'notanarticle' => '非内容页面',
 'notvisiblerev' => '上次由不同用户所作的修订版本已经删除',
 'watchnochange' => '在显示的时间段内您所监视的页面没有更改。',
-'watchlist-details' => '不包括讨论页面,您的监视列表中有$1个页面。',
+'watchlist-details' => '不计讨论页面,你的监视列表中有$1个页面。',
 'wlheader-enotif' => '* 已经启动电子邮件通知功能。',
-'wlheader-showupdated' => "* 在您上次查看后有被修改过的页面会以'''粗体'''的形式被显示",
+'wlheader-showupdated' => "*你上次访问后更改的页面以'''粗体'''显示",
 'watchmethod-recent' => '检查被监视页面的最近编辑',
 'watchmethod-list' => '查看监视页中的最新修改',
 'watchlistcontains' => '您的监视列表包含$1个页面。',
@@ -2294,39 +2281,40 @@ $1',
 'enotif_mailer' => '{{SITENAME}}通知发送器',
 'enotif_reset' => '标记所有页面为已访问',
 'enotif_impersonal_salutation' => '{{SITENAME}}用户',
-'enotif_subject_deleted' => '{{SITENAME}}的$1页面被$2删除',
-'enotif_subject_created' => '{{SITENAME}}的$1页面被$2创建',
-'enotif_subject_moved' => '{{SITENAME}}的$1页面被$2移动',
-'enotif_subject_restored' => '{{SITENAME}}的$1页面被$2恢复',
-'enotif_subject_changed' => '{{SITENAME}}的$1页面被$2修改',
-'enotif_body_intro_deleted' => '{{SITENAME}}页面$1已于$PAGEEDITDATE被{{gender:$2|$2}}删除,见 $3 。',
-'enotif_body_intro_created' => '{{SITENAME}}页面$1已于$PAGEEDITDATE被{{gender:$2|$2}}创建,在 $3 可以查看当前版本。',
-'enotif_body_intro_moved' => '{{SITENAME}}页面$1已于$PAGEEDITDATE被{{gender:$2|$2}}移动,在 $3 可以查看当前版本。',
-'enotif_body_intro_restored' => '{{SITENAME}}页面$1已于$PAGEEDITDATE被{{gender:$2|$2}}恢复,在 $3 可以查看当前版本。',
-'enotif_body_intro_changed' => '{{SITENAME}}页面$1已于$PAGEEDITDATE被{{gender:$2|$2}}修改,在 $3 可以查看当前版本。',
-'enotif_lastvisited' => '请浏览 $1 查看从您上次访问后的所有更改。',
-'enotif_lastdiff' => '请浏览 $1 查看该更改。',
+'enotif_subject_deleted' => '{{SITENAME}}页面$1已被$2删除',
+'enotif_subject_created' => '{{SITENAME}}页面$1已被$2创建',
+'enotif_subject_moved' => '{{SITENAME}}页面$1已被$2移动',
+'enotif_subject_restored' => '{{SITENAME}}页面$1已被$2恢复',
+'enotif_subject_changed' => '{{SITENAME}}页面$1已被$2更改',
+'enotif_body_intro_deleted' => '{{SITENAME}}页面$1已于$PAGEEDITDATE被$2{{GENDER:$2|删除}},请见$3。',
+'enotif_body_intro_created' => '{{SITENAME}}页面$1已于$PAGEEDITDATE被$2{{GENDER:$2|创建}},请浏览$3查看当前版本。',
+'enotif_body_intro_moved' => '{{SITENAME}}页面$1已于$PAGEEDITDATE被$2{{GENDER:$2|移动}},请浏览$3查看当前版本。',
+'enotif_body_intro_restored' => '{{SITENAME}}页面$1已于$PAGEEDITDATE被$2{{GENDER:$2|恢复}},请浏览$3查看当前版本。',
+'enotif_body_intro_changed' => '{{SITENAME}}页面$1已于$PAGEEDITDATE被$2{{GENDER:$2|更改}},请浏览$3查看当前版本。',
+'enotif_lastvisited' => '请浏览$1查看你上次访问后的所有更改。',
+'enotif_lastdiff' => '请浏览$1查看该更改。',
 'enotif_anon_editor' => '匿名用户$1',
-'enotif_body' => '亲爱的 $WATCHINGUSERNAME:
+'enotif_body' => '亲爱的$WATCHINGUSERNAME:
 
-$PAGEINTRO $NEWPAGE
+你好!
 
+$PAGEINTRO$NEWPAGE
 编辑摘要:$PAGESUMMARY $PAGEMINOREDIT
 
-您可以通过以下方式联系编辑者:
+你可以通过以下方式联系编者:
 电子邮件:$PAGEEDITOR_EMAIL
-wiki: $PAGEEDITOR_WIKI
-
-在您访问该页面之前,我们不会发送新增更改的通知。您也可以重设您的监视列表中所有监视页面的通知标志。
+用户页面:$PAGEEDITOR_WIKI
 
-友好的{{SITENAME}}通知系统
+在你访问该页面之前,我们不会发送新增更改的通知。
+你也可以重设你的监视列表中所有监视页面的通知标志。
 
+{{SITENAME}}通知系统
 --
 更改邮件通知设置:
 {{canonicalurl:{{#special:Preferences}}}}
 更改监视列表设置:
 {{canonicalurl:{{#special:EditWatchlist}}}}
-从监视列表中删除本页
+从监视列表中删除该页面
 $UNWATCHURL
 反馈与其他帮助:
 {{canonicalurl:{{MediaWiki:Helppage}}}}',
@@ -2414,6 +2402,7 @@ $UNWATCHURL
 'protect-fallback' => '仅允许拥有“$1”权限的用户',
 'protect-level-autoconfirmed' => '仅允许自动确认用户',
 'protect-level-sysop' => '仅允许管理员',
+'protect-summary-desc' => '[$1=$2]($3)',
 'protect-summary-cascade' => '联锁',
 'protect-expiring' => '终止于$1(UTC)',
 'protect-expiring-local' => '$1到期',
@@ -2494,13 +2483,13 @@ $1',
 'undelete-error-long' => '恢复被删除的文件时出错:
 
 $1',
-'undelete-show-file-confirm' => '确定要查看在 $2 $3 ,"<nowiki>$1</nowiki>"的已删除修订版本吗?',
+'undelete-show-file-confirm' => '确定要查看文件“<nowiki>$1</nowiki>”于$2$3被删除版本吗?',
 'undelete-show-file-submit' => '是',
 
 # Namespace form on various pages
 'namespace' => '名字空间:',
 'invert' => '反选',
-'tooltip-invert' => '选中此复选框来隐藏选定名字空间(及其相关名字空间,若该选项也被选中)范围内的页面更改',
+'tooltip-invert' => '请选择该框以隐藏指定名字空间(及相关名字空间,若被选择)的页面更改',
 'namespace_association' => '相关名字空间',
 'tooltip-namespace_association' => '选中此复选框可包括与选定名字空间相关的讨论页或子页面',
 'blanknamespace' => '(主要)',
@@ -2519,7 +2508,7 @@ $1',
 'sp-contributions-newbies-sub' => '新手',
 'sp-contributions-newbies-title' => '新手的用户贡献',
 'sp-contributions-blocklog' => '封禁日志',
-'sp-contributions-deleted' => '删除的用户贡献',
+'sp-contributions-deleted' => '删除的用户贡献',
 'sp-contributions-uploads' => '上传',
 'sp-contributions-logs' => '日志',
 'sp-contributions-talk' => '讨论',
@@ -2576,7 +2565,7 @@ $1',
 ** 不能接受的用户名',
 'ipb-hardblock' => '阻止登录用户使用该IP地址编辑',
 'ipbcreateaccount' => '阻止创建新账号',
-'ipbemailban' => '阻止用户发送邮件',
+'ipbemailban' => '阻止用户发送电子邮件',
 'ipbenableautoblock' => '自动封禁该用户最后使用的IP地址,以及他们随后试图用于编辑的所有IP地址',
 'ipbsubmit' => '封禁该用户',
 'ipbother' => '其它时间:',
@@ -2624,9 +2613,9 @@ $1',
 'infiniteblock' => '无限期',
 'expiringblock' => '$1 $2到期',
 'anononlyblock' => '仅匿名用户',
-'noautoblockblock' => 'è\87ªå\8a¨å°\81ç¦\81å·²ç¦\81用',
-'createaccountblock' => '创建帐户已禁用',
-'emailblock' => '发送邮件已禁用',
+'noautoblockblock' => 'è\87ªå\8a¨å°\81ç¦\81å\81\9c用',
+'createaccountblock' => '账户创建停用',
+'emailblock' => '电子邮件停用',
 'blocklist-nousertalk' => '不能编辑自己的讨论页面',
 'ipblocklist-empty' => '封禁列表为空。',
 'ipblocklist-no-results' => '请求的IP地址或用户名没有被封禁。',
@@ -2634,7 +2623,7 @@ $1',
 'unblocklink' => '解封',
 'change-blocklink' => '更改封禁',
 'contribslink' => '贡献',
-'emaillink' => '发送邮件',
+'emaillink' => '发送电子邮件',
 'autoblocker' => '由于您与“[[User:$1|$1]]”共享一个IP地址而被自动封禁。
 $1被封禁的理由是:“$2”',
 'blocklogpage' => '封禁日志',
@@ -2646,8 +2635,8 @@ $1被封禁的理由是:“$2”',
 'unblocklogentry' => '解封$1',
 'block-log-flags-anononly' => '仅限匿名用户',
 'block-log-flags-nocreate' => '账户创建停用',
-'block-log-flags-noautoblock' => 'è\87ªå\8a¨å°\81ç¦\81å·²ç¦\81用',
-'block-log-flags-noemail' => '邮件功能已禁用',
+'block-log-flags-noautoblock' => 'è\87ªå\8a¨å°\81ç¦\81å\81\9c用',
+'block-log-flags-noemail' => '电子邮件停用',
 'block-log-flags-nousertalk' => '不能编辑自己的讨论页面',
 'block-log-flags-angry-autoblock' => '已启用增强型自动封禁',
 'block-log-flags-hiddenname' => '隐藏用户名',
@@ -2728,14 +2717,14 @@ $1被封禁的理由是:“$2”',
 
 在这些情况下,您在必要时必须手工移动或合并页面。",
 'movearticle' => '移动页面:',
-'moveuserpage-warning' => "'''警告:'''将移动一个用户页面。请注意,只有该页面会被移动,该用户''不''会被更名。",
+'moveuserpage-warning' => "'''警告:'''将移动一个用户页面。请注意,只有该页面会被移动,该用户''不''会被更名。",
 'movenologin' => '未登录',
 'movenologintext' => '您必须是一名登记用户并且[[Special:UserLogin|登录]]
 后才可移动一个页面。',
-'movenotallowed' => '没有权限移动页面。',
-'movenotallowedfile' => '没有权限移动文件。',
-'cant-move-user-page' => '没有权限移动用户页面(子页面除外)。',
-'cant-move-to-user-page' => '没有权限移动页面至用户页面(用户子页面除外)。',
+'movenotallowed' => '没有权限移动页面。',
+'movenotallowedfile' => '没有权限移动文件。',
+'cant-move-user-page' => '没有权限移动用户页面(子页面除外)。',
+'cant-move-to-user-page' => '没有权限移动页面至用户页面(用户子页面除外)。',
 'newtitle' => '新标题:',
 'move-watch' => '监视来源页面和目标页面',
 'movepagebtn' => '移动页面',
@@ -2897,36 +2886,36 @@ $1被封禁的理由是:“$2”',
 # JavaScriptTest
 'javascripttest' => 'JavaScript测试',
 'javascripttest-title' => '运行$1测试',
-'javascripttest-pagetext-noframework' => '此页é\9d¢è¢«ä¿\9dç\95\99ç\94¨ä½\9cæ\89§è¡\8c JavaScript 测试。',
+'javascripttest-pagetext-noframework' => 'æ\9c¬é¡µé\9d¢è¢«ä¿\9dç\95\99è¿\9bè¡\8cJavaScript测试。',
 'javascripttest-pagetext-unknownframework' => '未知的框架“$1”。',
 'javascripttest-pagetext-frameworks' => '请选择以下的框架之一:$1',
 'javascripttest-pagetext-skins' => '选择外观来运行测试:',
-'javascripttest-qunit-intro' => '请浏览 mediawiki.org 查看[$1 测试文档]。',
+'javascripttest-qunit-intro' => '请见mediawiki.org的[$1 测试说明文件]。',
 'javascripttest-qunit-heading' => 'MediaWiki JavaScript QUnit 测试套件',
 
 # Tooltip help for the actions
-'tooltip-pt-userpage' => '的用户页面',
-'tooltip-pt-anonuserpage' => '您用于编辑的 IP 地址的用户页面',
-'tooltip-pt-mytalk' => '的讨论页面',
+'tooltip-pt-userpage' => '的用户页面',
+'tooltip-pt-anonuserpage' => '你用于编辑的IP地址的用户页面',
+'tooltip-pt-mytalk' => '的讨论页面',
 'tooltip-pt-anontalk' => '有关本IP地址的编辑的讨论',
-'tooltip-pt-preferences' => '的系统设置',
-'tooltip-pt-watchlist' => '您正在监视的页面的列表',
-'tooltip-pt-mycontris' => '的贡献列表',
+'tooltip-pt-preferences' => '的系统设置',
+'tooltip-pt-watchlist' => '你正在监视更改的页面的列表',
+'tooltip-pt-mycontris' => '的贡献列表',
 'tooltip-pt-login' => '我们鼓励你登录,不过这不是强制的',
 'tooltip-pt-anonlogin' => '我们鼓励你登录,不过这不是强制的',
-'tooltip-pt-logout' => '注销',
+'tooltip-pt-logout' => '退出登录',
 'tooltip-ca-talk' => '有关内容页面的讨论',
 'tooltip-ca-edit' => '你可以编辑本页面。请在保存前使用预览按钮。',
 'tooltip-ca-addsection' => '开始新段落',
-'tooltip-ca-viewsource' => '本页面受保护。您可以查看它的源代码。',
-'tooltip-ca-history' => '本页面的历史版本',
+'tooltip-ca-viewsource' => '本页面受到保护。你可以查看其源代码。',
+'tooltip-ca-history' => '本页面过去的版本',
 'tooltip-ca-protect' => '保护本页',
 'tooltip-ca-unprotect' => '更改本页面的保护',
 'tooltip-ca-delete' => '删除本页',
 'tooltip-ca-undelete' => '将这个页面恢复到被删除以前的状态',
 'tooltip-ca-move' => '移动本页',
-'tooltip-ca-watch' => '添加本页面至的监视列表',
-'tooltip-ca-unwatch' => '从您的监视列表中删除本页',
+'tooltip-ca-watch' => '添加本页面至的监视列表',
+'tooltip-ca-unwatch' => '从你的监视列表删除本页面',
 'tooltip-search' => '在{{SITENAME}}中搜索',
 'tooltip-search-go' => '如果相同的标题存在的话便直接前往该页面',
 'tooltip-search-fulltext' => '搜索含这些文字的页面',
@@ -2963,14 +2952,14 @@ $1被封禁的理由是:“$2”',
 'tooltip-preview' => '预览您的更改,请在保存前使用此功能!',
 'tooltip-diff' => '显示您对该文字所做的更改',
 'tooltip-compareselectedversions' => '查看此页面两个选定的修订版本间的差异。',
-'tooltip-watch' => '添加本页面至的监视列表',
+'tooltip-watch' => '添加本页面至的监视列表',
 'tooltip-watchlistedit-normal-submit' => '删除标题',
 'tooltip-watchlistedit-raw-submit' => '更新监视列表',
 'tooltip-recreate' => '重建该页面,无论是否被删除。',
 'tooltip-upload' => '开始上传',
 'tooltip-rollback' => '单击“回退”恢复上一位贡献者对本页的编辑',
 'tooltip-undo' => '“撤销”可以恢复该编辑并在预览模式下打开编辑表单。它允许在摘要中加入原因。',
-'tooltip-preferences-save' => '保存设置',
+'tooltip-preferences-save' => '保存系统设置',
 'tooltip-summary' => '请输入简短的摘要',
 
 # Stylesheets
@@ -3075,7 +3064,7 @@ $1被封禁的理由是:“$2”',
 'pageinfo-protect-cascading-from' => '保护级联自',
 'pageinfo-category-info' => '分类信息',
 'pageinfo-category-pages' => '页数',
-'pageinfo-category-subcats' => '子类别数',
+'pageinfo-category-subcats' => '子分类数',
 'pageinfo-category-files' => '文件数',
 
 # Skin names
@@ -3093,8 +3082,8 @@ $1被封禁的理由是:“$2”',
 'rcpatroldisabled' => '最新更改检查被关闭',
 'rcpatroldisabledtext' => '最新更改检查的功能目前已关闭。',
 'markedaspatrollederror' => '不能标志为已检查',
-'markedaspatrollederrortext' => '您需要指定某个版本才能标记为已检查。',
-'markedaspatrollederror-noautopatrol' => '您无法将自己所作的更改标记为已检查。',
+'markedaspatrollederrortext' => '你需要指定一个版本以标记为已巡查。',
+'markedaspatrollederror-noautopatrol' => '你不能把自己的更改标记为已检查。',
 'markedaspatrollednotify' => '$1的更改已被标记为已巡查。',
 'markedaspatrollederrornotify' => '标记为已巡查失败。',
 
@@ -3119,7 +3108,7 @@ $1',
 'nextdiff' => '下一编辑→',
 
 # Media information
-'mediawarning' => "'''警告''':该类型的文件可能包含恶意代码。执行后您的系统可能会受损。",
+'mediawarning' => "'''警告''':该文件类型可能含有恶意代码。执行后你的系统可能受损。",
 'imagemaxsize' => '图像大小限制:<br /><u>(文件描述页)</u>',
 'thumbsize' => '缩略图大小:',
 'widthheightpage' => '$1×$2,$3页',
@@ -3127,11 +3116,11 @@ $1',
 'file-info-size' => '$1×$2像素,文件大小:$3,MIME类型:$4',
 'file-info-size-pages' => '$1×$2像素,文件大小:$3,MIME类型:$4,$5页',
 'file-nohires' => '没有更高的分辨率。',
-'svg-long-desc' => 'SVGæ\96\87件ï¼\8cå\9b¾å\83\8f大å°\8fï¼\9a$1 × $2像素,文件大小:$3',
-'svg-long-desc-animated' => 'å\8a¨ç\94»SVGæ\96\87件ï¼\8cå\9b¾å\83\8f大å°\8f为$1 × $2像素,文件大小:$3',
+'svg-long-desc' => 'SVGæ\96\87件ï¼\8c尺寸为$1 × $2像素,文件大小:$3',
+'svg-long-desc-animated' => 'å\8a¨ç\94»SVGæ\96\87件ï¼\8c尺寸为$1 × $2像素,文件大小:$3',
 'svg-long-error' => '无效的SVG文件:$1',
 'show-big-image' => '完全分辨率',
-'show-big-image-preview' => 'æ\9c¬é¢\84è§\88ç\9a\84大å°\8f:$1。',
+'show-big-image-preview' => 'æ\9c¬é¢\84è§\88ç\9a\84尺寸:$1。',
 'show-big-image-other' => '其他{{PLURAL:$2|分辨率}}:$1。',
 'show-big-image-size' => '$1×$2像素',
 'file-info-gif-looped' => '循环',
@@ -3163,8 +3152,8 @@ $1',
 'minutes' => '$1分',
 'hours' => '$1小时',
 'days' => '$1天',
-'months' => '{{PLURAL:$1|$1个月|$1个月}}',
-'years' => '{{PLURAL:$1|$1年|$1年}}',
+'months' => '{{PLURAL:$1|$1个月}}',
+'years' => '{{PLURAL:$1|$1年}}',
 'ago' => '$1前',
 'just-now' => '刚刚',
 
@@ -3191,11 +3180,11 @@ Variants for Chinese language
 'variantname-zh' => '不转换',
 
 # Variants for Gan language
-'variantname-gan-hans' => '‪中文(简体)',
-'variantname-gan-hant' => '‪中文(繁体)',
+'variantname-gan-hans' => 'hans',
+'variantname-gan-hant' => 'hant',
 
 # Variants for Kazakh language
-'variantname-kk-cyrl' => '',
+'variantname-kk-cyrl' => 'kk-cyrl',
 
 # Metadata
 'metadata' => '原始数据',
@@ -3637,8 +3626,8 @@ Variants for Chinese language
 'confirmemail_needlogin' => '您需要$1以确认您的邮箱地址。',
 'confirmemail_success' => '您的邮箱已经被确认。您现在可以[[Special:UserLogin|登录]]并使用此网站了。',
 'confirmemail_loggedin' => '您的邮箱地址现在已被确认。',
-'confirmemail_error' => '在确认您的过程中发生错误。',
-'confirmemail_subject' => '来自{{SITENAME}}的电子邮件地址确认函',
+'confirmemail_error' => '保存你的确认时出错。',
+'confirmemail_subject' => '{{SITENAME}}电子邮件地址确认',
 'confirmemail_body' => '来自IP地址$1的用户(可能是您)在{{SITENAME}}上创建了账户“$2”,并提交了您
 的电子邮箱地址。
 
@@ -3677,8 +3666,8 @@ $3
 $5
 
 确认码会在$4过期。',
-'confirmemail_invalidated' => '邮件地址确认已取消',
-'invalidateemail' => '取消邮件地址确认',
+'confirmemail_invalidated' => '电子邮件地址确认已取消',
+'invalidateemail' => '取消电子邮件确认',
 
 # Scary transclusion
 'scarytranscludedisabled' => '[跨网站的编码转换不可用]',
@@ -3751,13 +3740,13 @@ $5
 'lag-warn-high' => '由于数据库的过度延迟,过去$1秒的更改未必会在这个列表中显示。',
 
 # Watchlist editor
-'watchlistedit-numitems' => '不包括讨论页面,您的监视列表包含$1个标题。',
-'watchlistedit-noitems' => '的监视列表中没有标题。',
+'watchlistedit-numitems' => '不计讨论页面,你的监视列表包含$1个标题。',
+'watchlistedit-noitems' => '的监视列表中没有标题。',
 'watchlistedit-normal-title' => '编辑监视列表',
 'watchlistedit-normal-legend' => '删除监视列表中的标题',
-'watchlistedit-normal-explain' => '您的监视列表中的标题会显示在下方。要删除标题,请勾选它前面的选择框并点击“{{int:Watchlistedit-normal-submit}}”。您也可以[[Special:EditWatchlist/raw|编辑原始列表]]。',
+'watchlistedit-normal-explain' => '你的监视列表中的标题显示在下方。要删除标题,请勾选它前面选择框并单击“{{int:Watchlistedit-normal-submit}}”。你也可以[[Special:EditWatchlist/raw|编辑原始列表]]。',
 'watchlistedit-normal-submit' => '删除标题',
-'watchlistedit-normal-done' => '已从您的监视列表删除了$1个标题:',
+'watchlistedit-normal-done' => '已从你的监视列表删除$1个标题:',
 'watchlistedit-raw-title' => '编辑原始监视列表',
 'watchlistedit-raw-legend' => '编辑原始监视列表',
 'watchlistedit-raw-explain' => '您的监视列表中的标题在下面显示,同时也可以可以通过编辑这个表去加入以及移除标题;一行一个标题。当完成以后,点击{{int:Watchlistedit-raw-submit}}。您也可以使用[[Special:EditWatchlist|标准编辑器]]。',
@@ -3800,11 +3789,11 @@ $5
 'version-poweredby-credits' => "本Wiki由'''[//www.mediawiki.org/ MediaWiki]'''驱动,版权所有 © 2001-$1 $2。",
 'version-poweredby-others' => '其他',
 'version-credits-summary' => '我们感谢下列人士为[[Special:Version|MediaWiki]]作出的贡献。',
-'version-license-info' => 'MediaWiki 是一款自由软件;您可根据自由软件基金会所发表的 GNU 通用公共许可证条款规定,无论您依据的是本授权的第二版或(您自行选择的)任一日后发行的版本,将本程序再发布与/或做出修改
+'version-license-info' => "MediaWiki是自由软件,你可以依据自由软件基金会发行的'''GNU公众授权协议'''第2版或任意后续版本的条款,传播和/或修改本软件
 
-MediaWiki 是基于使用目的而加以发布,然而不负任何担保责任;也没有对适售性或特定目的适用性所为的默示性担保。详情请参照 GNU 通用公共许可证条款
+MediaWiki发表时预期有用,但对此'''无任何保证''',亦无隐含的'''可以销售'''或'''适合特定目的'''的保证。详情请见GNU公众授权协议
 
-您应已收到附随于本程序的[{{SERVER}}{{SCRIPTPATH}}/COPYING GNU 通用公共许可证副本];如果没有,请发送邮件至自由软件基金会:51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA,或[//www.gnu.org/licenses/old-licenses/gpl-2.0.html 在线阅读]。',
+你应该已经接受本程序附带的[{{SERVER}}{{SCRIPTPATH}}/COPYING GNU公众授权协议的副本]。如果没有,请写信至美国马萨诸塞州波士顿富兰克林大街51号5楼自由软件基金会,邮编MA 02110-1301(Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA),或[//www.gnu.org/licenses/old-licenses/gpl-2.0.html 在线阅读该协议]。",
 'version-software' => '已安装的软件',
 'version-software-product' => '产品',
 'version-software-version' => '版本',
@@ -3818,7 +3807,7 @@ MediaWiki 是基于使用目的而加以发布,然而不负任何担保责任
 'filepath' => '文件路径',
 'filepath-page' => '文件名:',
 'filepath-submit' => '提交',
-'filepath-summary' => 'æ­¤ç\89¹æ®\8a页é\9d¢è¿\94å\9b\9eæ\96\87件ç\9a\84å®\8cæ\95´è·¯å¾\84ã\80\82å\9b¾å\83\8fä¼\9a以å®\8cæ\95´ç\9a\84å\88\86辨ç\8e\87æ\98¾ç¤ºï¼\8cå\85¶å®\83ç\9a\84æ\96\87件类å\9e\8bä¹\9få°\86ç\9b´æ\8e¥é\80\9aè¿\87å\85³è\81\94ç\9a\84åº\94ç\94¨ç¨\8båº\8f打开。',
+'filepath-summary' => 'æ\9c¬ç\89¹æ®\8a页é\9d¢è¿\94å\9b\9eæ\96\87件ç\9a\84å®\8cæ\95´è·¯å¾\84ã\80\82å\9b¾å\83\8f以å®\8cæ\95´å\88\86辨ç\8e\87æ\98¾ç¤ºï¼\8cå\85¶å®\83æ\96\87件类å\9e\8b以å\85³è\81\94ç¨\8båº\8fç\9b´æ\8e¥打开。',
 
 # Special:FileDuplicateSearch
 'fileduplicatesearch' => '搜索重复文件',
@@ -3886,7 +3875,7 @@ MediaWiki 是基于使用目的而加以发布,然而不负任何担保责任
 'compare-submit' => '对比',
 'compare-invalid-title' => '您指定的标题无效。',
 'compare-title-not-exists' => '您指定的标题不存在。',
-'compare-revision-not-exists' => '您指定的修订版本不存在。',
+'compare-revision-not-exists' => '你指定的版本不存在。',
 
 # Database error messages
 'dberr-header' => '本wiki出现了问题',
@@ -3951,7 +3940,7 @@ MediaWiki 是基于使用目的而加以发布,然而不负任何担保责任
 'rightsnone' => '(无)',
 
 # Feedback
-'feedback-bugornote' => '如果您准备好详细描述一个技术问题,请[$1 报告bug]。或者您也可以使用下面的简单表格。您的评论将被添加至页面“[$3 $2]”,附有您的用户名和所使用的浏览器。',
+'feedback-bugornote' => '如果你准备好详细描述一个技术问题,请[$1 报告bug]。或者你可以使用下面的简单表格。你的评论将被添加至页面“[$3 $2]”,附有你的用户名和使用的浏览器。',
 'feedback-subject' => '主题:',
 'feedback-message' => '信息:',
 'feedback-cancel' => '取消',
@@ -3960,7 +3949,7 @@ MediaWiki 是基于使用目的而加以发布,然而不负任何担保责任
 'feedback-error1' => '错误:从API返回无法识别的结果',
 'feedback-error2' => '错误:编辑失败',
 'feedback-error3' => '错误:API没有响应',
-'feedback-thanks' => '谢谢!的反馈已发布至页面“[$2 $1]”。',
+'feedback-thanks' => '谢谢!的反馈已发布至页面“[$2 $1]”。',
 'feedback-close' => '完成',
 'feedback-bugcheck' => '请检查本bug是否为[$1 已知bug]。',
 'feedback-bugnew' => '我检查了。报告新bug',
@@ -4008,7 +3997,7 @@ MediaWiki 是基于使用目的而加以发布,然而不负任何担保责任
 'api-error-unknown-error' => '内部错误:尝试上传文件时出错。',
 'api-error-unknown-warning' => '未知的警告:$1',
 'api-error-unknownerror' => '未知错误:$1。',
-'api-error-uploaddisabled' => '该 wiki 禁用上传功能。',
+'api-error-uploaddisabled' => '该wiki停用上传。',
 'api-error-verification-error' => '该文件可能损坏或扩展名错误。',
 
 # Durations
index 481eb1e..e70a72e 100644 (file)
@@ -518,7 +518,7 @@ $1',
 'youhavenewmessages' => '您有$1($2)。',
 'newmessageslink' => '新訊息',
 'newmessagesdifflink' => '最後更改',
-'youhavenewmessagesfromusers' => '你有來自{{PLURAL:$3| 另一位用戶| $3位用戶}}的$1 ( $2 )。',
+'youhavenewmessagesfromusers' => '你有來自{{PLURAL:$3|另一位用戶|$3位用戶}}的$1($2)。',
 'youhavenewmessagesmanyusers' => '你有來自多位用戶的$1( $2 )。',
 'newmessageslinkplural' => '{{PLURAL:$1|一項新訊息|新訊息}}',
 'newmessagesdifflinkplural' => '最新{{PLURAL:$1|更改|更改}}',
@@ -2381,6 +2381,7 @@ $UNWATCHURL
 'protect-fallback' => '僅允許有「$1」權限的用戶',
 'protect-level-autoconfirmed' => '僅允許自動確認使用者',
 'protect-level-sysop' => '僅允許管理員',
+'protect-summary-desc' => '[$1=$2]($3)',
 'protect-summary-cascade' => '連鎖',
 'protect-expiring' => '終止於 $1 (UTC)',
 'protect-expiring-local' => '$1到期',
@@ -2673,10 +2674,8 @@ $1被封禁的理由是“$2”',
 如果您選擇不去做的話,請檢查[[Special:DoubleRedirects|雙重]]或[[Special:BrokenRedirects|損壞重定向]]連結。
 您應當負責確定所有連結依然會連到指定的頁面。
 
-注意如果新頁面已經有內容的話,頁面將'''不會'''被移動,
-除非新頁面是重定向頁,而且沒有修訂歷史。
-這意味著您再必要時可以在移動到新頁面後再移回老的頁面,
-同時您也無法覆蓋現有頁面。
+注意如果新頁面已經有內容的話,頁面將'''不會'''被移動,除非新頁面是重定向頁,而且沒有修訂歷史。
+這意味著您再必要時可以在移動到新頁面後再移回老的頁面,同時您也無法覆蓋現有頁面。
 
 '''警告!'''
 對一個經常被訪問的頁面而言這可能是一個重大與唐突的更改;
index a386bd8..b2bbf9b 100644 (file)
@@ -342,7 +342,7 @@ abstract class Maintenance {
         */
        protected function error( $err, $die = 0 ) {
                $this->outputChanneled( false );
-               if ( php_sapi_name() == 'cli' ) {
+               if ( PHP_SAPI == 'cli' ) {
                        fwrite( STDERR, $err . "\n" );
                } else {
                        print $err;
@@ -920,7 +920,7 @@ abstract class Maintenance {
                if ( !is_readable( $settingsFile ) ) {
                        $this->error( "A copy of your installation's LocalSettings.php\n" .
                                                "must exist and be readable in the source directory.\n" .
-                                               "Use --conf to specify it." , true );
+                                               "Use --conf to specify it.", true );
                }
                $wgCommandLineMode = true;
                return $settingsFile;
@@ -936,13 +936,9 @@ abstract class Maintenance {
                $dbw = $this->getDB( DB_MASTER );
                $dbw->begin( __METHOD__ );
 
-               $tbl_arc = $dbw->tableName( 'archive' );
-               $tbl_rev = $dbw->tableName( 'revision' );
-               $tbl_txt = $dbw->tableName( 'text' );
-
                # Get "active" text records from the revisions table
                $this->output( 'Searching for active text records in revisions table...' );
-               $res = $dbw->query( "SELECT DISTINCT rev_text_id FROM $tbl_rev" );
+               $res = $dbw->select( 'revision', 'rev_text_id', array(), __METHOD__, array( 'DISTINCT' ) );
                foreach ( $res as $row ) {
                        $cur[] = $row->rev_text_id;
                }
@@ -950,7 +946,7 @@ abstract class Maintenance {
 
                # Get "active" text records from the archive table
                $this->output( 'Searching for active text records in archive table...' );
-               $res = $dbw->query( "SELECT DISTINCT ar_text_id FROM $tbl_arc" );
+               $res = $dbw->select( 'archive', 'ar_text_id', array(), __METHOD__, array( 'DISTINCT' ) );
                foreach ( $res as $row ) {
                        # old pre-MW 1.5 records can have null ar_text_id's.
                        if ( $row->ar_text_id !== null ) {
@@ -961,8 +957,8 @@ abstract class Maintenance {
 
                # Get the IDs of all text records not in these sets
                $this->output( 'Searching for inactive text records...' );
-               $set = implode( ', ', $cur );
-               $res = $dbw->query( "SELECT old_id FROM $tbl_txt WHERE old_id NOT IN ( $set )" );
+               $cond = 'old_id NOT IN ( ' . $dbw->makeList( $cur ) . ' )';
+               $res = $dbw->select( 'text', 'old_id', array( $cond ), __METHOD__, array( 'DISTINCT' ) );
                $old = array();
                foreach ( $res as $row ) {
                        $old[] = $row->old_id;
@@ -976,8 +972,7 @@ abstract class Maintenance {
                # Delete as appropriate
                if ( $delete && $count ) {
                        $this->output( 'Deleting...' );
-                       $set = implode( ', ', $old );
-                       $dbw->query( "DELETE FROM $tbl_txt WHERE old_id IN ( $set )" );
+                       $dbw->delete( 'text', array( 'old_id' => $old ), __METHOD__ );
                        $this->output( "done.\n" );
                }
 
index 0e12a1c..cc0a7e1 100644 (file)
@@ -48,9 +48,9 @@ class BaseDump {
        var $infiles = null;
 
        function BaseDump( $infile ) {
-               $this->infiles = explode(';',$infile);
+               $this->infiles = explode( ';', $infile );
                $this->reader = new XMLReader();
-               $infile = array_shift($this->infiles);
+               $infile = array_shift( $this->infiles );
                if (defined( 'LIBXML_PARSEHUGE' ) ) {
                        $this->reader->open( $infile, null, LIBXML_PARSEHUGE );
                }
index f276fc1..861610b 100644 (file)
@@ -46,7 +46,7 @@ class ChangePassword extends Maintenance {
                } elseif ( $this->hasOption( "userid" ) ) {
                        $user = User::newFromId( $this->getOption( 'userid' ) );
                } else {
-                       $this->error( "A \"user\" or \"userid\" must be set to change the password for" , true );
+                       $this->error( "A \"user\" or \"userid\" must be set to change the password for", true );
                }
                if ( !$user || !$user->getId() ) {
                        $this->error( "No such user: " . $this->getOption( 'user' ), true );
index 0a22f58..1e44e23 100644 (file)
@@ -368,4 +368,3 @@ class CheckSyntax extends Maintenance {
 
 $maintClass = "CheckSyntax";
 require_once( RUN_MAINTENANCE_IF_MAIN );
-
diff --git a/maintenance/deleteEqualMessages.php b/maintenance/deleteEqualMessages.php
new file mode 100644 (file)
index 0000000..38e6956
--- /dev/null
@@ -0,0 +1,143 @@
+<?php
+/**
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ * @file
+ * @ingroup Maintenance
+ */
+
+require_once( __DIR__ . '/Maintenance.php' );
+
+/**
+ * Maintenance script that deletes all pages in the MediaWiki namespace
+ * of which the content is equal to the system default.
+ *
+ * @ingroup Maintenance
+ */
+class DeleteEqualMessages extends Maintenance {
+       public function __construct() {
+               parent::__construct();
+               $this->mDescription = "Deletes all pages in the MediaWiki namespace that are equal to the default message";
+               $this->addOption( 'delete', 'Actually delete the pages' );
+               $this->addOption( 'delete-talk', 'Don\'t leave orphaned talk pages behind' );
+               $this->addOption( 'lang-code', 'Check for subpages of this lang-code (default: root page against content language)', false, true );
+       }
+
+       public function execute() {
+               global $wgUser, $wgContLang;
+
+               $doDelete = $this->hasOption( 'delete' );
+               $doDeleteTalk = $this->hasOption( 'delete-talk' );
+               $forLangCode = $this->getOption( 'lang-code' );
+
+               if ( $forLangCode ) {
+                       $langObj = Language::factory( $forLangCode );
+                       $langCode = $langObj->getCode();
+                       $nonContLang = true;
+               } else {
+                       $langObj = $wgContLang;
+                       $langCode = $wgContLang->getCode();
+                       $nonContLang = false;
+               }
+
+               $this->output( "Checking for pages with default message..." );
+
+               /* Based on SpecialAllmessages::reallyDoQuery #filter=modified */
+
+               $messageNames = Language::getLocalisationCache()->getSubitemList( 'en', 'messages' );
+               // Normalise message names for NS_MEDIAWIKI page_title
+               $messageNames = array_map( array( $langObj, 'ucfirst' ), $messageNames );
+               // TODO: Do the below for each language code (e.g. delete /xxx subpage if equal to MessagesXxx)
+               // Right now it only takes care of the root override, which is enough since most wikis aren't multi-lang wikis.
+               $statuses = AllmessagesTablePager::getCustomisedStatuses( $messageNames, $langCode, $nonContLang );
+
+               $relevantPages = 0;
+               $equalPages = 0;
+               $equalPagesTalks = 0;
+               $results = array();
+               foreach ( $messageNames as $key ) {
+                       $customised = isset( $statuses['pages'][$key] );
+                       if ( $customised ) {
+                               $actual = wfMessage( $key )->inLanguage( $langCode )->plain();
+                               $default = wfMessage( $key )->inLanguage( $langCode )->useDatabase( false )->plain();
+
+                               $relevantPages++;
+                               if ( $actual === $default ) {
+                                       $hasTalk = isset( $statuses['talks'][$key] );
+                                       $results[] = array(
+                                               'title' => $key,
+                                               'hasTalk' => $hasTalk,
+                                       );
+                                       $equalPages++;
+                                       if ( $hasTalk ) {
+                                               $equalPagesTalks++;
+                                       }
+                               }
+                       }
+               }
+
+               if ( $equalPages === 0 ) {
+                       // No more equal messages left
+                       $this->output( "done.\n" );
+                       return;
+               }
+
+               $this->output( "\n{$relevantPages} pages in the MediaWiki namespace override messages." );
+               $this->output( "\n{$equalPages} pages are equal to the default message ({$equalPagesTalks} talk pages).\n" );
+
+               if ( !$doDelete ) {
+                       $this->output( "\nRun the script again with --delete to delete these pages" );
+                       if ( $equalPagesTalks !== 0 ) {
+                               $this->output( " (include --delete-talk to also delete the talk pages)" );
+                       }
+                       $this->output( "\n" );
+                       return;
+               }
+
+               $user = User::newFromName( 'MediaWiki default' );
+               if ( !$user ) {
+                       $this->error( "Invalid username", true );
+               }
+               $wgUser = $user;
+
+               // Hide deletions from RecentChanges
+               $user->addGroup( 'bot' );
+
+               // Handle deletion
+               $this->output( "\n...deleting equal messages (this may take a long time!)...", 'msg' );
+               $dbw = wfGetDB( DB_MASTER );
+               foreach ( $results as $result ) {
+                       wfWaitForSlaves();
+                       $dbw->ping();
+                       $dbw->begin( __METHOD__ );
+                       $title = Title::makeTitle( NS_MEDIAWIKI, $result['title'] );
+                       $page = WikiPage::factory( $title );
+                       $error = ''; // Passed by ref
+                       $page->doDeleteArticle( 'No longer required', false, 0, false, $error, $user );
+                       if ( $result['hasTalk'] && $doDeleteTalk ) {
+                               $title = Title::makeTitle( NS_MEDIAWIKI_TALK, $result['title'] );
+                               $page = WikiPage::factory( $title );
+                               $error = ''; // Passed by ref
+                               $page->doDeleteArticle( 'Orphaned talk page of no longer required message', false, 0, false, $error, $user );
+                       }
+                       $dbw->commit( __METHOD__ );
+               }
+               $this->output( "done!\n", 'msg' );
+       }
+}
+
+$maintClass = "DeleteEqualMessages";
+require_once( RUN_MAINTENANCE_IF_MAIN );
index 4f82a63..114aefd 100644 (file)
@@ -101,4 +101,3 @@ class DeleteOldRevisions extends Maintenance {
 
 $maintClass = "DeleteOldRevisions";
 require_once( RUN_MAINTENANCE_IF_MAIN );
-
index dcbf739..f0da9a8 100644 (file)
@@ -91,4 +91,3 @@ class DeleteOrphanedRevisions extends Maintenance {
 
 $maintClass = "DeleteOrphanedRevisions";
 require_once( RUN_MAINTENANCE_IF_MAIN );
-
index ac96f45..1d5070b 100644 (file)
@@ -21,7 +21,7 @@
  * @file
  */
 
-if ( php_sapi_name() != 'cli-server' ) {
+if ( PHP_SAPI != 'cli-server' ) {
        die( "This script can only be run by php's cli-server sapi." );
 }
 
index 2bb2a0f..f470aed 100644 (file)
@@ -111,8 +111,10 @@ try {
 
        // Potentially debug globals
        $maintenance->globals();
+
+       // log profiling info
+       wfLogProfilingData();
 } catch ( MWException $mwe ) {
        echo( $mwe->getText() );
        exit( 1 );
 }
-
index 153fdd7..08aae29 100644 (file)
@@ -76,4 +76,3 @@ class DumpLinks extends Maintenance {
 
 $maintClass = "DumpLinks";
 require_once( RUN_MAINTENANCE_IF_MAIN );
-
index ad4c12f..93fc3e7 100644 (file)
@@ -93,4 +93,3 @@ class EditCLI extends Maintenance {
 
 $maintClass = "EditCLI";
 require_once( RUN_MAINTENANCE_IF_MAIN );
-
index 69cf548..95f46ff 100644 (file)
@@ -80,5 +80,3 @@ while ( ( $line = Maintenance::readconsole() ) !== false ) {
 }
 
 print "\n";
-
-
index d98cfe3..4cb5e10 100644 (file)
@@ -55,7 +55,8 @@ class TestFileOpPerformance extends Maintenance {
 
                $profiler = Profiler::instance();
                $profiler->setTemplated( true );
-               $profiler->logData(); // prints
+
+               //NOTE: as of MW1.21, $profiler->logData() is called implicitly by doMaintenance.php.
        }
 
        protected function doPerfTest( FileBackend $backend ) {
index 600ca97..691ed80 100644 (file)
@@ -76,5 +76,3 @@ class MaintenanceFormatInstallDoc extends Maintenance {
 
 $maintClass = 'MaintenanceFormatInstallDoc';
 require_once( RUN_MAINTENANCE_IF_MAIN );
-
-
index b72430a..445a3fb 100644 (file)
@@ -2709,5 +2709,3 @@ for ( $count = 0; true; $count++ ) {
                break;
        }
 }
-
-
index 3ad0864..3df1169 100644 (file)
@@ -51,7 +51,7 @@ class DatabaseLag extends Maintenance {
                                unset( $lags[0] );
                                echo gmdate( 'H:i:s' ) . ' ';
                                foreach ( $lags as $lag ) {
-                                       printf( "%-12s " , $lag === false ? 'false' : $lag );
+                                       printf( "%-12s ", $lag === false ? 'false' : $lag );
                                }
                                echo "\n";
                                sleep( 5 );
@@ -61,7 +61,7 @@ class DatabaseLag extends Maintenance {
                        $lags = $lb->getLagTimes();
                        foreach ( $lags as $i => $lag ) {
                                $name = $lb->getServerName( $i );
-                               $this->output( sprintf( "%-20s %s\n" , $name, $lag === false ? 'false' : $lag ) );
+                               $this->output( sprintf( "%-20s %s\n", $name, $lag === false ? 'false' : $lag ) );
                        }
                }
        }
index e2ad6a7..0d5e238 100644 (file)
@@ -61,18 +61,80 @@ class GenerateCollationData extends Maintenance {
 
        public function execute() {
                $this->dataDir = $this->getOption( 'data-dir', '.' );
-               if ( !file_exists( "{$this->dataDir}/allkeys.txt" ) ) {
-                       $this->error( "Unable to find allkeys.txt. Please download it from " .
-                               "http://www.unicode.org/Public/UCA/latest/allkeys.txt and specify " .
-                               "its location with --data-dir=<DIR>" );
-                       exit( 1 );
-               }
-               if ( !file_exists( "{$this->dataDir}/ucd.all.grouped.xml" ) ) {
-                       $this->error( "Unable to find ucd.all.grouped.xml. Please download it " .
-                               "from http://www.unicode.org/Public/6.0.0/ucdxml/ucd.all.grouped.zip " .
-                               "and specify its location with --data-dir=<DIR>" );
+
+               $allkeysPresent = file_exists( "{$this->dataDir}/allkeys.txt" );
+               $ucdallPresent = file_exists( "{$this->dataDir}/ucd.all.grouped.xml" );
+
+               // As of January 2013, these links work for all versions of Unicode
+               // between 5.1 and 6.2, inclusive.
+               $allkeysURL = "http://www.unicode.org/Public/UCA/<Unicode version>/allkeys.txt";
+               $ucdallURL = "http://www.unicode.org/Public/<Unicode version>/ucdxml/ucd.all.grouped.zip";
+
+               if ( !$allkeysPresent || !$ucdallPresent ) {
+                       $icuVersion = IcuCollation::getICUVersion();
+                       $unicodeVersion = IcuCollation::getUnicodeVersionForICU();
+
+                       $error = "";
+
+                       if ( !$allkeysPresent ) {
+                               $error .= "Unable to find allkeys.txt. "
+                                       . "Download it and specify its location with --data-dir=<DIR>. "
+                                       . "\n\n";
+                       }
+                       if ( !$ucdallPresent ) {
+                               $error = "Unable to find ucd.all.grouped.xml. "
+                                       . "Download it, unzip, and specify its location with --data-dir=<DIR>. "
+                                       . "\n\n";
+                       }
+
+                       $versionKnown = false;
+                       if ( !$icuVersion ) {
+                               // Unknown version - either very old intl,
+                               // or PHP < 5.3.7 which does not expose this information
+                               $error .= "As MediaWiki could not determine the version of ICU library used by your PHP's "
+                                       . "intl extension it can't suggest which file version to download. "
+                                       . "This can be caused by running a very old version of intl or PHP < 5.3.7. "
+                                       . "If you are sure everything is all right, find out the ICU version "
+                                       . "by running phpinfo(), check what is the Unicode version it is using "
+                                       . "at http://site.icu-project.org/download, then try finding appropriate data file(s) at:";
+                       } elseif ( version_compare( $icuVersion, "4.0", "<" ) ) {
+                               // Extra old version
+                               $error .= "You are using outdated version of ICU ($icuVersion), intended for "
+                                       . ( $unicodeVersion ? "Unicode $unicodeVersion" : "an unknown version of Unicode" )
+                                       . "; this file might not be avalaible for it, and it's not supported by MediaWiki. "
+                                       ." You are on your own; consider upgrading PHP's intl extension or try "
+                                       . "one of the files available at:";
+                       } elseif ( version_compare( $icuVersion, "51.0", ">=" ) ) {
+                               // Extra recent version
+                               $error .= "You are using ICU $icuVersion, released after this script was last updated. "
+                                       . "Check what is the Unicode version it is using at http://site.icu-project.org/download . "
+                                       . "It can't be guaranteed everything will work, but appropriate file(s) should "
+                                       . "be available at:";
+                       } else {
+                               // ICU 4.0 to 50.x
+                               $versionKnown = true;
+                               $error .= "You are using ICU $icuVersion, intended for "
+                                       . ( $unicodeVersion ? "Unicode $unicodeVersion" : "an unknown version of Unicode" )
+                                       . ". Appropriate file(s) should be available at:";
+                       }
+                       $error .= "\n";
+
+                       if ( $versionKnown && $unicodeVersion ) {
+                               $allkeysURL = str_replace( "<Unicode version>", "$unicodeVersion.0", $allkeysURL );
+                               $ucdallURL = str_replace( "<Unicode version>", "$unicodeVersion.0", $ucdallURL );
+                       }
+
+                       if ( !$allkeysPresent ) {
+                               $error .= "* $allkeysURL\n";
+                       }
+                       if ( !$ucdallPresent ) {
+                               $error .= "* $ucdallURL\n";
+                       }
+
+                       $this->error( $error );
                        exit( 1 );
                }
+
                $debugOutFileName = $this->getOption( 'debug-output' );
                if ( $debugOutFileName ) {
                        $this->debugOutFile = fopen( $debugOutFileName, 'w' );
index b1c16ad..420e842 100644 (file)
@@ -508,7 +508,7 @@ class languages {
 
 
                        if ( isset( $messages[$key] ) ) {
-                               $messages[$key] = implode( $messages[$key],", " );
+                               $messages[$key] = implode( $messages[$key], ", " );
                        }
                }
                return $messages;
index 1ab22e2..e2997c4 100644 (file)
@@ -2702,6 +2702,7 @@ $wgMessageStructure = array(
                'pageinfo-robot-noindex',
                'pageinfo-views',
                'pageinfo-watchers',
+               'pageinfo-few-watchers',
                'pageinfo-redirects-name',
                'pageinfo-redirects-value',
                'pageinfo-subpages-name',
index 0ba9bfe..01fbac7 100644 (file)
@@ -23,7 +23,7 @@
  * @ingroup LockManager Maintenance
  */
 
-if ( php_sapi_name() !== 'cli' ) {
+if ( PHP_SAPI !== 'cli' ) {
        die( "This is not a valid entry point.\n" );
 }
 error_reporting( E_ALL );
index cea6433..62596b2 100644 (file)
@@ -82,6 +82,9 @@ class MergeMessageFileList extends Maintenance {
                if ( $this->hasOption( 'output' ) ) {
                        $mmfl['output'] = $this->getOption( 'output' );
                }
+               if ( $this->hasOption( 'quiet' ) ) {
+                       $mmfl['quiet'] = true;
+               }
        }
 }
 
@@ -92,7 +95,9 @@ foreach ( $mmfl['setupFiles'] as $fileName ) {
                continue;
        }
        $fileName = str_replace( '$IP', $IP, $fileName );
-       fwrite( STDERR, "Loading data from $fileName\n" );
+       if ( empty( $mmfl['quiet'] ) ) {
+               fwrite( STDERR, "Loading data from $fileName\n" );
+       }
        include_once( $fileName );
 }
 fwrite( STDERR, "\n" );
@@ -120,4 +125,3 @@ if ( isset( $mmfl['output'] ) ) {
 } else {
        echo $s;
 }
-
index 6e01291..5e505eb 100644 (file)
@@ -43,7 +43,7 @@
 # Variables / Configuration
 #
 
-if ( php_sapi_name() != 'cli' ) {
+if ( PHP_SAPI != 'cli' ) {
        echo 'Run "' . __FILE__ . '" from the command line.';
        die( -1 );
 }
@@ -131,7 +131,7 @@ function generateConfigFile( $doxygenTemplate, $outputDirectory, $stripFromPath,
        );
        $tmpCfg = str_replace( array_keys( $replacements ), array_values( $replacements ), $template );
        $tmpFileName = tempnam( wfTempDir(), 'mwdocgen-' );
-       file_put_contents( $tmpFileName , $tmpCfg ) or die( "Could not write doxygen configuration to file $tmpFileName\n" );
+       file_put_contents( $tmpFileName, $tmpCfg ) or die( "Could not write doxygen configuration to file $tmpFileName\n" );
 
        return $tmpFileName;
 }
index 16c6070..fc38938 100644 (file)
@@ -45,9 +45,12 @@ class nextJobDB extends Maintenance {
                } elseif ( $this->hasOption( 'type' ) ) {
                        $types = array( $this->getOption( 'type' ) );
                } else {
-                       $types = false;
+                       $types = JobQueueGroup::singleton()->getDefaultQueueTypes();
                }
 
+               // Handle any required periodic queue maintenance
+               $this->executeReadyPeriodicTasks();
+
                $memcKey = 'jobqueue:dbs:v3';
                $pendingDbInfo = $wgMemc->get( $memcKey );
 
@@ -82,24 +85,22 @@ class nextJobDB extends Maintenance {
                do {
                        $again = false;
 
-                       if ( $types === false ) {
-                               $candidates = call_user_func_array( 'array_merge', $pendingDBs );
-                       } else {
-                               $candidates = array();
-                               $possTypes = array_intersect( $types, array_keys( $pendingDBs ) );
-                               if ( $possTypes ) {
-                                       $possTypes = array_values( $possTypes );
-                                       $type = $possTypes[ mt_rand( 0, count( $possTypes ) - 1 ) ];
-                                       $candidates = $pendingDBs[$type];
+                       $candidates = array(); // list of (type, db)
+                       // Flatten the tree of candidates into a flat list so that a random
+                       // item can be selected, weighing each queue (type/db tuple) equally.
+                       foreach ( $pendingDBs as $type => $dbs ) {
+                               if ( in_array( $type, $types ) ) {
+                                       foreach ( $dbs as $db ) {
+                                               $candidates[] = array( $type, $db );
+                                       }
                                }
                        }
-                       if ( !$candidates ) {
+                       if ( !count( $candidates ) ) {
                                return; // no jobs for this type
                        }
 
-                       $candidates = array_values( $candidates );
-                       $db = $candidates[ mt_rand( 0, count( $candidates ) - 1 ) ];
-                       if ( !$this->checkJob( $type, $db ) ) {
+                       list( $type, $db ) = $candidates[ mt_rand( 0, count( $candidates ) - 1 ) ];
+                       if ( !$this->checkJob( $type, $db ) ) { // queue is actually empty?
                                $pendingDBs = $this->delistDB( $pendingDBs, $db, $type );
                                // Update the cache to remove the outdated information.
                                // Make sure that this does not race (especially with full rebuilds).
@@ -125,16 +126,16 @@ class nextJobDB extends Maintenance {
                }
        }
 
+       /**
+        * Remove a type/DB entry from the list of queues with jobs
+        *
+        * @param $pendingDBs array
+        * @param $db string
+        * @param $type string
+        * @return Array
+        */
        private function delistDB( array $pendingDBs, $db, $type ) {
-               if ( $type === false ) {
-                       // There are no jobs available in the current database
-                       foreach ( $pendingDBs as $type2 => $dbs ) {
-                               $pendingDBs[$type2] = array_diff( $pendingDBs[$type2], array( $db ) );
-                       }
-               } else {
-                       // There are no jobs of this type available in the current database
-                       $pendingDBs[$type] = array_diff( $pendingDBs[$type], array( $db ) );
-               }
+               $pendingDBs[$type] = array_diff( $pendingDBs[$type], array( $db ) );
                return $pendingDBs;
        }
 
@@ -146,17 +147,7 @@ class nextJobDB extends Maintenance {
         * @return bool
         */
        private function checkJob( $type, $dbName ) {
-               $group = JobQueueGroup::singleton( $dbName );
-               if ( $type === false ) {
-                       foreach ( $group->getDefaultQueueTypes() as $type ) {
-                               if ( !$group->get( $type )->isEmpty() ) {
-                                       return true;
-                               }
-                       }
-                       return false;
-               } else {
-                       return !$group->get( $type )->isEmpty();
-               }
+               return !JobQueueGroup::singleton( $dbName )->get( $type )->isEmpty();
        }
 
        /**
@@ -168,14 +159,36 @@ class nextJobDB extends Maintenance {
 
                $pendingDBs = array(); // (job type => (db list))
                foreach ( $wgLocalDatabases as $db ) {
-                       $types = JobQueueGroup::singleton( $db )->getQueuesWithJobs();
-                       foreach ( $types as $type ) {
+                       foreach ( JobQueueGroup::singleton( $db )->getQueuesWithJobs() as $type ) {
                                $pendingDBs[$type][] = $db;
                        }
                }
 
                return $pendingDBs;
        }
+
+       /**
+        * Do all ready periodic jobs for all databases every 5 minutes (and .1% of the time)
+        * @return integer
+        */
+       private function executeReadyPeriodicTasks() {
+               global $wgLocalDatabases, $wgMemc;
+
+               $count = 0;
+               $memcKey = 'jobqueue:periodic:lasttime';
+               $timestamp = (int)$wgMemc->get( $memcKey ); // UNIX timestamp or 0
+               if ( ( time() - $timestamp ) > 300 || mt_rand( 0, 999 ) == 0 ) { // 5 minutes
+                       if ( $wgMemc->add( "$memcKey:rebuild", 1, 1800 ) ) { // lock
+                               foreach ( $wgLocalDatabases as $db ) {
+                                       $count += JobQueueGroup::singleton( $db )->executeReadyPeriodicTasks();
+                               }
+                               $wgMemc->set( $memcKey, time() );
+                               $wgMemc->delete( "$memcKey:rebuild" ); // unlock
+                       }
+               }
+
+               return $count;
+       }
 }
 
 $maintClass = "nextJobDb";
index 059b6fe..fa9d512 100644 (file)
@@ -83,4 +83,3 @@ class PopulateLogUsertext extends LoggedUpdateMaintenance {
 
 $maintClass = "PopulateLogUsertext";
 require_once( RUN_MAINTENANCE_IF_MAIN );
-
diff --git a/maintenance/postgres/archives/patch-sites.sql b/maintenance/postgres/archives/patch-sites.sql
new file mode 100644 (file)
index 0000000..a4f9ed9
--- /dev/null
@@ -0,0 +1,31 @@
+CREATE SEQUENCE sites_site_id_seq;
+CREATE TABLE sites (
+  site_id           INTEGER     NOT NULL    PRIMARY KEY DEFAULT nextval('sites_site_id_seq'),
+  site_global_key   TEXT        NOT NULL,
+  site_type         TEXT        NOT NULL,
+  site_group        TEXT        NOT NULL,
+  site_source       TEXT        NOT NULL,
+  site_language     TEXT        NOT NULL,
+  site_protocol     TEXT        NOT NULL,
+  site_domain       TEXT        NOT NULL,
+  site_data         TEXT        NOT NULL,
+  site_forward      SMALLINT    NOT NULL,
+  site_config       TEXT        NOT NULL
+);
+CREATE UNIQUE INDEX site_global_key ON sites (site_global_key);
+CREATE INDEX site_type ON sites (site_type);
+CREATE INDEX site_group ON sites (site_group);
+CREATE INDEX site_source ON sites (site_source);
+CREATE INDEX site_language ON sites (site_language);
+CREATE INDEX site_protocol ON sites (site_protocol);
+CREATE INDEX site_domain ON sites (site_domain);
+CREATE INDEX site_forward ON sites (site_forward);
+
+CREATE TABLE site_identifiers (
+  si_site   INTEGER NOT NULL,
+  si_type   TEXT    NOT NULL,
+  si_key    TEXT    NOT NULL
+);
+CREATE UNIQUE INDEX si_type_key ON site_identifiers (si_type, si_key);
+CREATE INDEX si_site ON site_identifiers (si_site);
+CREATE INDEX si_key ON site_identifiers (si_key);
index 845193d..cb3df8d 100644 (file)
@@ -530,12 +530,14 @@ CREATE TABLE job (
   job_timestamp       TIMESTAMPTZ,
   job_params          TEXT      NOT NULL,
   job_random          INTEGER   NOT NULL DEFAULT 0,
+  job_attempts        INTEGER   NOT NULL DEFAULT 0,
   job_token           TEXT      NOT NULL DEFAULT '',
   job_token_timestamp TIMESTAMPTZ,
   job_sha1            TEXT NOT NULL DEFAULT ''
 );
 CREATE INDEX job_sha1 ON job (job_sha1);
 CREATE INDEX job_cmd_token ON job (job_cmd, job_token, job_random);
+CREATE INDEX job_cmd_token_id ON job (job_cmd, job_token, job_id);
 CREATE INDEX job_cmd_namespace_title ON job (job_cmd, job_namespace, job_title);
 CREATE INDEX job_timestamp_idx ON job (job_timestamp);
 
@@ -697,3 +699,35 @@ CREATE TABLE module_deps (
   md_deps    TEXT  NOT NULL
 );
 CREATE UNIQUE INDEX md_module_skin ON module_deps (md_module, md_skin);
+
+CREATE SEQUENCE sites_site_id_seq;
+CREATE TABLE sites (
+  site_id           INTEGER     NOT NULL    PRIMARY KEY DEFAULT nextval('sites_site_id_seq'),
+  site_global_key   TEXT        NOT NULL,
+  site_type         TEXT        NOT NULL,
+  site_group        TEXT        NOT NULL,
+  site_source       TEXT        NOT NULL,
+  site_language     TEXT        NOT NULL,
+  site_protocol     TEXT        NOT NULL,
+  site_domain       TEXT        NOT NULL,
+  site_data         TEXT        NOT NULL,
+  site_forward      SMALLINT    NOT NULL,
+  site_config       TEXT        NOT NULL
+);
+CREATE UNIQUE INDEX site_global_key ON sites (site_global_key);
+CREATE INDEX site_type ON sites (site_type);
+CREATE INDEX site_group ON sites (site_group);
+CREATE INDEX site_source ON sites (site_source);
+CREATE INDEX site_language ON sites (site_language);
+CREATE INDEX site_protocol ON sites (site_protocol);
+CREATE INDEX site_domain ON sites (site_domain);
+CREATE INDEX site_forward ON sites (site_forward);
+
+CREATE TABLE site_identifiers (
+  si_site   INTEGER NOT NULL,
+  si_type   TEXT    NOT NULL,
+  si_key    TEXT    NOT NULL
+);
+CREATE UNIQUE INDEX si_type_key ON site_identifiers (si_type, si_key);
+CREATE INDEX si_site ON site_identifiers (si_site);
+CREATE INDEX si_key ON site_identifiers (si_key);
index 87fc997..bb3d68b 100644 (file)
@@ -95,4 +95,3 @@ class PreprocessDump extends DumpIterator {
 
 $maintClass = "PreprocessDump";
 require_once( RUN_MAINTENANCE_IF_MAIN );
-
index 10892c4..2ccf703 100644 (file)
@@ -21,7 +21,7 @@
  * @ingroup Maintenance
  */
 
-if( php_sapi_name() != 'cli' ) {
+if( PHP_SAPI != 'cli' ) {
        die( 1 );
 }
 
index d6baf42..00b5008 100644 (file)
@@ -32,7 +32,7 @@ class PurgeList extends Maintenance {
        public function __construct() {
                parent::__construct();
                $this->mDescription = "Send purge requests for listed pages to squid";
-               $this->addOption( 'purge', 'Whether to update page_touched.' , false, false );
+               $this->addOption( 'purge', 'Whether to update page_touched.', false, false );
                $this->addOption( 'namespace', 'Namespace number', false, true );
                $this->setBatchSize( 100 );
        }
index a91abf9..2d79f36 100644 (file)
@@ -180,4 +180,3 @@ class ReassignEdits extends Maintenance {
 
 $maintClass = "ReassignEdits";
 require_once( RUN_MAINTENANCE_IF_MAIN );
-
index 12da7a8..55f5b4a 100644 (file)
@@ -53,7 +53,7 @@ class RefreshImageMetadata extends Maintenance {
                $this->addOption( 'start', 'Name of file to start with', false, true );
                $this->addOption( 'end', 'Name of file to end with', false, true );
 
-               $this->addOption( 'mime', '(Inefficient!) Only refresh files with this mime type. Can accept wild-card image/*' , false, true );
+               $this->addOption( 'mime', '(Inefficient!) Only refresh files with this mime type. Can accept wild-card image/*', false, true );
                $this->addOption( 'metadata-contains', '(Inefficient!) Only refresh files where the img_metadata field contains this string. Can be used if its known a specific property was being extracted incorrectly.', false, true );
 
        }
index 85b0993..a78acd5 100644 (file)
@@ -76,6 +76,12 @@ class RunJobs extends Maintenance {
                $n = 0;
 
                $group = JobQueueGroup::singleton();
+               // Handle any required periodic queue maintenance
+               $count = $group->executeReadyPeriodicTasks();
+               if ( $count > 0 ) {
+                       $this->runJobsLog( "Executed $count periodic queue task(s)." );
+               }
+
                do {
                        $job = ( $type === false )
                                ? $group->pop( JobQueueGroup::TYPE_DEFAULT, JobQueueGroup::USE_CACHE )
@@ -85,7 +91,9 @@ class RunJobs extends Maintenance {
                                $t = microtime( true );
                                $this->runJobsLog( $job->toString() . " STARTING" );
                                $status = $job->run();
-                               $group->ack( $job ); // done
+                               if ( $status ) {
+                                       $group->ack( $job ); // done
+                               }
                                $t = microtime( true ) - $t;
                                $timeMs = intval( $t * 1000 );
                                if ( !$status ) {
index 982c7cb..3036406 100644 (file)
@@ -59,7 +59,7 @@ class ShowStats extends Maintenance {
                $max_length_value = $max_length_desc = 0;
                foreach ( $fields as $field => $desc ) {
                        $max_length_value = max( $max_length_value, strlen( $stats->$field ) );
-                       $max_length_desc  = max( $max_length_desc , strlen( $desc ) ) ;
+                       $max_length_desc  = max( $max_length_desc strlen( $desc ) ) ;
                }
 
                // Show them
@@ -71,4 +71,3 @@ class ShowStats extends Maintenance {
 
 $maintClass = "ShowStats";
 require_once( RUN_MAINTENANCE_IF_MAIN );
-
index d394558..30cbcf1 100644 (file)
@@ -349,4 +349,3 @@ class FixBug20757 extends Maintenance {
 
 $maintClass = 'FixBug20757';
 require_once( RUN_MAINTENANCE_IF_MAIN );
-
index e4a2a45..1049e0c 100644 (file)
@@ -124,5 +124,3 @@ function moveToExternal( $cluster, $maxID, $minID = 1 ) {
                }
        }
 }
-
-
index fe62ddf..5e5cc8f 100644 (file)
@@ -809,4 +809,3 @@ class CgzCopyTransaction {
                }
        }
 }
-
index 0f5cd2b..414eab8 100644 (file)
@@ -110,4 +110,3 @@ function resolveStub( $id, $stubText, $flags ) {
                ), $fname
        );
 }
-
index 1afecc4..3187c31 100644 (file)
@@ -113,4 +113,3 @@ SQL;
 
 $maintClass = 'StorageTypeStats';
 require_once( RUN_MAINTENANCE_IF_MAIN );
-
index 9487bbf..e13e1b1 100644 (file)
@@ -99,4 +99,3 @@ foreach ( $keys as $id => $key ) {
 }
 $t += microtime( true );
 printf( "Decompression time: %5.2f ms\n", $t * 1000 );
-
index 1cb97f9..c52f07c 100644 (file)
@@ -70,4 +70,3 @@ class DummyTermColorer {
                return '';
        }
 }
-
index 2181e44..1e1f24b 100644 (file)
@@ -33,4 +33,3 @@ $uo = new userOptions( $options, $args );
 $uo->run();
 
 print "Done.\n";
-
index 95f028a..4e8a1a2 100644 (file)
@@ -65,7 +65,7 @@ print Xml::element( 'Image',
                'height' => 16,
                'width' => 16,
                'type' => 'image/x-icon' ),
-       wfExpandUrl( $wgFavicon , PROTO_CURRENT ) );
+       wfExpandUrl( $wgFavicon, PROTO_CURRENT ) );
 
 $urls = array();
 
index cbbf2ab..885a9e9 100644 (file)
@@ -221,9 +221,9 @@ class profile_point {
                <td class="mw-profileinfo-count"><?php echo $this->count(); ?></td>
                <td class="mw-profileinfo-cpr"><?php echo round( sprintf( '%.2f', $this->callsPerRequest() ), 2 ); ?></td>
                <td class="mw-profileinfo-tpc"><?php echo round( sprintf( '%.2f', $this->timePerCall() ), 2 ); ?></td>
-               <td class="mw-profileinfo-mpc"><?php echo round( sprintf( '%.2f' ,$this->memoryPerCall() / 1024 ), 2 ); ?></td>
+               <td class="mw-profileinfo-mpc"><?php echo round( sprintf( '%.2f'$this->memoryPerCall() / 1024 ), 2 ); ?></td>
                <td class="mw-profileinfo-tpr"><?php echo @round( sprintf( '%.2f', $this->time() / self::$totalcount ), 2 ); ?></td>
-               <td class="mw-profileinfo-mpr"><?php echo @round( sprintf( '%.2f' ,$this->memory() / self::$totalcount / 1024 ), 2 ); ?></td>
+               <td class="mw-profileinfo-mpr"><?php echo @round( sprintf( '%.2f'$this->memory() / self::$totalcount / 1024 ), 2 ); ?></td>
                </tr>
                <?php
                if ( $ex ) {
index 672f457..7efb1b5 100644 (file)
@@ -199,6 +199,7 @@ return array(
        ),
        'jquery.json' => array(
                'scripts' => 'resources/jquery/jquery.json.js',
+               'targets' => array( 'mobile', 'desktop' ),
        ),
        'jquery.localize' => array(
                'scripts' => 'resources/jquery/jquery.localize.js',
index cddd4ec..b0bd685 100644 (file)
                                        // Strings which precede a version number in a user agent string - combined and used as match 1 in
                                        // version detectection
                                        versionPrefixes = [
-                                               'camino', 'chrome', 'firefox', 'netscape', 'netscape6', 'opera', 'version', 'konqueror',
+                                               'camino', 'chrome', 'firefox', 'iceweasel', 'netscape', 'netscape6', 'opera', 'version', 'konqueror',
                                                'lynx', 'msie', 'safari', 'ps3'
                                        ],
                                        // Used as matches 2, 3 and 4 in version extraction - 3 is used as actual version number
                                        versionSuffix = '(\\/|\\;?\\s|)([a-z0-9\\.\\+]*?)(\\;|dev|rel|\\)|\\s|$)',
                                        // Names of known browsers
                                        names = [
-                                               'camino', 'chrome', 'firefox', 'netscape', 'konqueror', 'lynx', 'msie', 'opera',
+                                               'camino', 'chrome', 'firefox', 'iceweasel', 'netscape', 'konqueror', 'lynx', 'msie', 'opera',
                                                'safari', 'ipod', 'iphone', 'blackberry', 'ps3', 'rekonq'
                                        ],
                                        // Tanslations for conforming browser names
index 6297f9a..8320304 100644 (file)
@@ -86,7 +86,7 @@
                return false;
        }
 
-       function getElementText( node ) {
+       function getElementSortKey( node ) {
                var $node = $( node ),
                        // Use data-sort-value attribute.
                        // Use data() instead of attr() so that live value changes
                        // like charAt, toLowerCase and split are expected.
                        return String( data );
                } else {
-                       return $node.text();
+                       if ( node.tagName.toLowerCase() === 'img' ) {
+                               return $node.attr( 'alt' ) || ''; // handle undefined alt
+                       } else {
+                               return $.map( $.makeArray( node.childNodes ), function( elem ) {
+                                       // 1 is for document.ELEMENT_NODE (the constant is undefined on old browsers)
+                                       if ( elem.nodeType === 1 ) {
+                                               return getElementSortKey( elem );
+                                       } else {
+                                               return $.text( elem );
+                                       }
+                               } ).join( '' );
+                       }
                }
        }
 
        function getTextFromRowAndCellIndex( rows, rowIndex, cellIndex ) {
                if ( rows[rowIndex] && rows[rowIndex].cells[cellIndex] ) {
-                       return $.trim( getElementText( rows[rowIndex].cells[cellIndex] ) );
+                       return $.trim( getElementSortKey( rows[rowIndex].cells[cellIndex] ) );
                } else {
                        return '';
                }
                        cache.row.push( $row );
 
                        for ( var j = 0; j < totalCells; ++j ) {
-                               cols.push( parsers[j].format( getElementText( $row[0].cells[j] ), table, $row[0].cells[j] ) );
+                               cols.push( parsers[j].format( getElementSortKey( $row[0].cells[j] ), table, $row[0].cells[j] ) );
                        }
 
                        cols.push( cache.normalized.length ); // add position for rowCache
index c15fa0d..727a525 100644 (file)
@@ -1,10 +1,12 @@
 /**
- * This module enables double-click-to-edit functionality
+ * This module enables double-click-to-edit functionality.
  */
 ( function ( mw, $ ) {
-       mw.util.$content.dblclick( function ( e ) {
-               e.preventDefault();
-               // Trigger native HTMLElement click instead of opening URL (bug 43052)
-               $( '#ca-edit a' ).get( 0 ).click();
+       $( function () {
+               mw.util.$content.dblclick( function ( e ) {
+                       e.preventDefault();
+                       // Trigger native HTMLElement click instead of opening URL (bug 43052)
+                       $( '#ca-edit a' ).get( 0 ).click();
+               } );
        } );
 }( mediaWiki, jQuery ) );
index 46384a8..6eaec6a 100644 (file)
@@ -180,4 +180,20 @@ jQuery( document ).ready( function ( $ ) {
                $tzTextbox.blur( updateTimezoneSelection );
                updateTimezoneSelection();
        }
+
+       // Preserve the tab after saving the preferences
+       // Not using cookies, because their deletion results are inconsistent.
+       // Not using jStorage due to its enormous size (for this feature)
+       if ( window.sessionStorage ) {
+               if ( sessionStorage.getItem( 'mediawikiPreferencesTab' ) !== null ) {
+                       switchPrefTab( sessionStorage.getItem( 'mediawikiPreferencesTab' ), 'noHash' );
+               }
+               // Deleting the key, the tab states should be reset until we press Save
+               sessionStorage.removeItem( 'mediawikiPreferencesTab' );
+
+               $( '#mw-prefs-form' ).submit( function () {
+                       var storageData = $( $preftoc ).find( 'li.selected a' ).attr( 'id' ).replace( 'preftab-', '' );
+                       sessionStorage.setItem( 'mediawikiPreferencesTab', storageData );
+               } );
+       }
 } );
index 934e906..67a63ca 100644 (file)
 
                /**
                 * Tranform parsed structure into a int: (interface language) message include
-                * Invoked by putting {{MediaWiki:othermessage}} into a message
+                * Invoked by putting {{int:othermessage}} into a message
                 * @param {Array} of nodes
                 * @return {string} Other message
                 */
                // Caching is somewhat problematic, because we do need different message functions for different maps, so
                // we'd have to cache the parser as a member of this.map, which sounds a bit ugly.
                // Do not use mw.jqueryMsg unless required
-               if ( !/\{\{|\[/.test(this.map.get( this.key ) ) ) {
+               if ( this.format === 'plain' || !/\{\{|\[/.test(this.map.get( this.key ) ) ) {
                        // Fall back to mw.msg's simple parser
                        return oldParser.apply( this );
                }
index b0abc9e..658487e 100644 (file)
@@ -180,11 +180,7 @@ var mw = ( function ( $, undefined ) {
                                return '<' + this.key + '>';
                        }
 
-                       if ( this.format === 'plain' ) {
-                               // @todo FIXME: Although not applicable to core Message,
-                               // Plugins like jQueryMsg should be able to distinguish
-                               // between 'plain' (only variable replacement and plural/gender)
-                               // and actually parsing wikitext to HTML.
+                       if ( this.format === 'plain' || this.format === 'parse' ) {
                                text = this.parser();
                        }
 
@@ -193,10 +189,6 @@ var mw = ( function ( $, undefined ) {
                                text = mw.html.escape( text );
                        }
 
-                       if ( this.format === 'parse' ) {
-                               text = this.parser();
-                       }
-
                        return text;
                },
 
index 5c5c87e..3b2a59c 100644 (file)
@@ -61,7 +61,7 @@
                 *
                 * @return String: Random set of 32 alpha-numeric characters
                 */
-               function generateId() {
+               this.generateRandomSessionId = function () {
                        var i, r,
                                id = '',
                                seed = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz';
@@ -70,7 +70,7 @@
                                id += seed.substring( r, r + 1 );
                        }
                        return id;
-               }
+               };
 
                /**
                 * Gets the current user's name.
                this.sessionId = function () {
                        var sessionId = $.cookie( 'mediaWiki.user.sessionId' );
                        if ( typeof sessionId === 'undefined' || sessionId === null ) {
-                               sessionId = generateId();
+                               sessionId = user.generateRandomSessionId();
                                $.cookie( 'mediaWiki.user.sessionId', sessionId, { 'expires': null, 'path': '/' } );
                        }
                        return sessionId;
                        }
                        id = $.cookie( 'mediaWiki.user.id' );
                        if ( typeof id === 'undefined' || id === null ) {
-                               id = generateId();
+                               id = user.generateRandomSessionId();
                        }
                        // Set cookie if not set, or renew it if already set
                        $.cookie( 'mediaWiki.user.id', id, {
index 0be614a..09aec79 100644 (file)
@@ -93,4 +93,3 @@ function unixLineEndings( $var ) {
        }
        return $var;
 }
-
index 34d3357..1fe750e 100644 (file)
@@ -313,6 +313,11 @@ input#wpSummary {
        padding-left: 0.25em;
        border-left: none;
 }
+
+/* (bug 5346) make category redirects italic */
+.catlinks li a.mw-redirect {
+       font-style: italic;
+}
 /**
  * Hidden categories
  */
@@ -826,6 +831,7 @@ div.gallerytext {
 
 /* Language specific height correction for titles. Ref Bug 29405 and Bug 30809 */
 /* Languages like hi or ml require slightly more vertical space to show diacritics properly */
+h1:lang(anp),
 h1:lang(as),
 h1:lang(bh), /* Macrolanguage, used on bh.wikipedia.org, should be removed one day */
 h1:lang(bho),
@@ -833,16 +839,22 @@ h1:lang(bn),
 h1:lang(gu),
 h1:lang(hi),
 h1:lang(kn),
+h1:lang(ks),
 h1:lang(ml),
 h1:lang(mr),
 h1:lang(my),
+h1:lang(mai),
+h1:lang(ne),
+h1:lang(new),
 h1:lang(or),
 h1:lang(pa),
+h1:lang(pi),
 h1:lang(sa),
 h1:lang(ta),
 h1:lang(te) {
        line-height: 1.6em !important;
 }
+h2:lang(anp), h3:lang(anp), h4:lang(anp), h5:lang(anp), h6:lang(anp),
 h2:lang(as), h3:lang(as), h4:lang(as), h5:lang(as), h6:lang(as),
 h2:lang(bho), h3:lang(bho), h4:lang(bho), h5:lang(bho), h6:lang(bho),
 h2:lang(bh), h3:lang(bh), h4:lang(bh), h5:lang(bh), h6:lang(bh),
@@ -850,11 +862,16 @@ h2:lang(bn), h3:lang(bn), h4:lang(bn), h5:lang(bn), h6:lang(bn),
 h2:lang(gu), h3:lang(gu), h4:lang(gu), h5:lang(gu), h6:lang(gu),
 h2:lang(hi), h3:lang(hi), h4:lang(hi), h5:lang(hi), h6:lang(hi),
 h2:lang(kn), h3:lang(kn), h4:lang(kn), h5:lang(kn), h6:lang(kn),
+h2:lang(ks), h3:lang(ks), h4:lang(ks), h5:lang(ks), h6:lang(ks),
 h2:lang(ml), h3:lang(ml), h4:lang(ml), h5:lang(ml), h6:lang(ml),
 h2:lang(mr), h3:lang(mr), h4:lang(mr), h5:lang(mr), h6:lang(mr),
 h2:lang(my), h3:lang(my), h4:lang(my), h5:lang(my), h6:lang(my),
+h2:lang(mai), h3:lang(mai), h4:lang(mai), h5:lang(mai), h6:lang(mai),
+h2:lang(ne), h3:lang(ne), h4:lang(ne), h5:lang(ne), h6:lang(ne),
+h2:lang(new), h3:lang(new), h4:lang(new), h5:lang(new), h6:lang(new),
 h2:lang(or), h3:lang(or), h4:lang(or), h5:lang(or), h6:lang(or),
 h2:lang(pa), h3:lang(pa), h4:lang(pa), h5:lang(pa), h6:lang(pa),
+h2:lang(pi), h3:lang(pi), h4:lang(pi), h5:lang(pi), h6:lang(pi),
 h2:lang(sa), h3:lang(sa), h4:lang(sa), h5:lang(sa), h6:lang(sa),
 h2:lang(ta), h3:lang(ta), h4:lang(ta), h5:lang(ta), h6:lang(ta),
 h2:lang(te), h3:lang(te), h4:lang(te), h5:lang(te), h6:lang(te) {
@@ -1068,8 +1085,8 @@ table.floatleft {
 }
 
 .editsection, .toctoggle {
-    -moz-user-select: none;
-    -webkit-user-select: none;
-    -ms-user-select: none;
-    user-select: none;
+       -moz-user-select: none;
+       -webkit-user-select: none;
+       -ms-user-select: none;
+       user-select: none;
 }
diff --git a/skins/vector/images/border.png b/skins/vector/images/border.png
deleted file mode 100644 (file)
index f9ca8cc..0000000
Binary files a/skins/vector/images/border.png and /dev/null differ
diff --git a/skins/vector/images/page-base.png b/skins/vector/images/page-base.png
deleted file mode 100644 (file)
index b3ecd30..0000000
Binary files a/skins/vector/images/page-base.png and /dev/null differ
diff --git a/skins/vector/images/preferences-base.png b/skins/vector/images/preferences-base.png
deleted file mode 100644 (file)
index 8e0082b..0000000
Binary files a/skins/vector/images/preferences-base.png and /dev/null differ
diff --git a/skins/vector/images/preferences-edge.png b/skins/vector/images/preferences-edge.png
deleted file mode 100644 (file)
index 411a1aa..0000000
Binary files a/skins/vector/images/preferences-edge.png and /dev/null differ
index 26967a5..2e09ee1 100644 (file)
@@ -21,18 +21,17 @@ body {
        font-size: 1em;
 }
 body {
-       background-color: #f3f3f3;
-       /* @embed */
-       background-image: url(images/page-base.png);
+       background-color: #f6f6f6;
 }
 /* Content */
 div#content {
        margin-left: 10em;
        padding: 1em;
-       /* @embed */
-       background-image: url(images/border.png);
-       background-position: top left;
-       background-repeat: repeat-y;
+       /* Border on top, left, and bottom side */
+       border: 1px solid #a7d7f9;
+       border-right-width: 0;
+       /* Merge the border with tabs' one (in their background image) */
+       margin-top: -1px;
        background-color: white;
        color: black;
        direction: ltr;
@@ -55,10 +54,6 @@ div#content {
        margin-top: -5em;
        margin-left: 10em;
        height: 5em;
-       /* @embed */
-       background-image: url(images/border.png);
-       background-position: bottom left;
-       background-repeat: repeat-x;
 }
 div#mw-head {
        position: absolute;
@@ -528,10 +523,6 @@ div#footer {
        margin-left: 10em;
        margin-top: 0;
        padding: 0.75em;
-       /* @embed */
-       background-image: url(images/border.png);
-       background-position: top left;
-       background-repeat: repeat-x;
        direction: ltr;
 }
 div#footer ul {
@@ -654,9 +645,7 @@ div#footer #footer-places li {
        margin-top: -2px;
        clear: both;
        border: solid 1px #ccc;
-       background-color: #f9f9f9;
-       /* @embed */
-       background-image: url(images/preferences-base.png);
+       background-color: #fafafa;
 }
 #preferences fieldset {
        border: none;
index 30b9f94..264ba69 100644 (file)
@@ -101,4 +101,3 @@ $wgAutoloadClasses += array(
        'SeleniumTestSuite' => "$testDir/selenium/SeleniumTestSuite.php",
        'SeleniumConfig' => "$testDir/selenium/SeleniumConfig.php",
 );
-
index ea1b290..05a6f15 100644 (file)
@@ -155,6 +155,9 @@ class ParserTest {
                        'name'          => 'fsLockManager',
                        'class'         => 'FSLockManager',
                        'lockDirectory' => wfTempDir() . '/test-repo/lockdir',
+               ), array(
+                       'name'          => 'nullLockManager',
+                       'class'         => 'NullLockManager',
                ) );
                $wgLocalFileRepo = array(
                        'class'           => 'LocalRepo',
@@ -634,11 +637,14 @@ class ParserTest {
                        'wgScriptPath' => '/',
                        'wgArticlePath' => '/wiki/$1',
                        'wgActionPaths' => array(),
-                       'wgLockManagers' => array(
+                       'wgLockManagers' => array( array(
                                'name'          => 'fsLockManager',
                                'class'         => 'FSLockManager',
                                'lockDirectory' => $this->uploadDir . '/lockdir',
-                       ),
+                       ), array(
+                               'name'          => 'nullLockManager',
+                               'class'         => 'NullLockManager',
+                       ) ),
                        'wgLocalFileRepo' => array(
                                'class' => 'LocalRepo',
                                'name' => 'local',
@@ -966,7 +972,7 @@ class ParserTest {
        private function teardownGlobals() {
                RepoGroup::destroySingleton();
                FileBackendGroup::destroySingleton();
-               LockManagerGroup::destroySingleton();
+               LockManagerGroup::destroySingletons();
                LinkCache::singleton()->clear();
 
                foreach ( $this->savedGlobals as $var => $val ) {
index 365ace1..1f84aae 100644 (file)
@@ -4258,6 +4258,25 @@ disabled
 </li></ol>
 !! end
 
+!!test
+List embedded in a non-block tag
+(Ugly Parsoid output -- worth fixing; Disabled for PHP parser since it relies on Tidy)
+!! options
+disabled
+!!input
+<small>
+* foo
+</small>
+!!result
+<p><small></small></p>
+<small>
+<ul>
+<li> foo</li>
+</ul>
+</small>
+<p><small></small></p>
+!!end
+
 !! test
 List items are not parsed correctly following a <pre> block (bug 785)
 !! input
@@ -11013,6 +11032,22 @@ Both [[Dunav]] and [[Дунав]] are names for this river.
 </p>
 !!end
 
+!! article
+Дуна
+!! text
+content
+!! endarticle
+
+!! test
+Link to another existing title shouldn't be parsed as self-link even if it's a variant of this title
+!! options
+title=[[Duna]] language=sr
+!! input
+[[Дуна]] is not a self-link while [[Duna]] and [[Dуна]] are still self-links.
+!! result
+<p><a href="/wiki/%D0%94%D1%83%D0%BD%D0%B0" title="Дуна">Дуна</a> is not a self-link while <strong class="selflink">Duna</strong> and <strong class="selflink">Dуна</strong> are still self-links.
+</p>
+!! end
 
 !! test
 Link to pages in language variants
@@ -11771,17 +11806,6 @@ Multibyte character in padright
 </p>
 !! end
 
-!! test
-Formatted date
-!! config
-wgUseDynamicDates=1
-!! input
-[[2009-03-24]]
-!! result
-<p><span class="mw-formatted-date" title="2009-03-24"><a href="/index.php?title=2009&amp;action=edit&amp;redlink=1" class="new" title="2009 (page does not exist)">2009</a>-<a href="/index.php?title=March_24&amp;action=edit&amp;redlink=1" class="new" title="March 24 (page does not exist)">03-24</a></span>
-</p>
-!!end
-
 !!test
 formatdate parser function
 !!input
@@ -11800,17 +11824,6 @@ formatdate parser function, with default format
 </p>
 !! end
 
-!! test
-Linked date with autoformatting disabled
-!! config
-wgUseDynamicDates=false
-!! input
-[[2009-03-24]]
-!! result
-<p><a href="/index.php?title=2009-03-24&amp;action=edit&amp;redlink=1" class="new" title="2009-03-24 (page does not exist)">2009-03-24</a>
-</p>
-!! end
-
 !! test
 Spacing of numbers in formatted dates
 !! input
@@ -11820,17 +11833,6 @@ Spacing of numbers in formatted dates
 </p>
 !! end
 
-!! test
-Spacing of numbers in formatted dates (linked)
-!! config
-wgUseDynamicDates=true
-!! input
-[[January 15]]
-!! result
-<p><span class="mw-formatted-date" title="01-15"><a href="/index.php?title=January_15&amp;action=edit&amp;redlink=1" class="new" title="January 15 (page does not exist)">January 15</a></span>
-</p>
-!! end
-
 !! test
 formatdate parser function, with default format and on a page of which the content language is always English and different from the wiki content language
 !! options
@@ -13655,6 +13657,51 @@ disabled
 
 !! end
 
+!!test
+Accept empty td cell attribute
+!!input
+{|
+| align="center" | foo ||  |
+|}
+!!result
+<table>
+<tr>
+<td align="center"> foo </td>
+<td>
+</td></tr></table>
+
+!!end
+
+!!test
+Non-empty attributes in th-cells
+!!input
+{|
+! Foo !! style="color: red" | Bar
+|}
+!!result
+<table>
+<tr>
+<th> Foo </th>
+<th style="color: red"> Bar
+</th></tr></table>
+
+!!end
+
+!!test
+Accept empty attributes in th-cells
+!!input
+{|
+!| foo !!| bar
+|}
+!!result
+<table>
+<tr>
+<th> foo </th>
+<th> bar
+</th></tr></table>
+
+!!end
+
 TODO:
 more images
 more tables
diff --git a/tests/parser/preprocess/NestedTemplates.expected b/tests/parser/preprocess/NestedTemplates.expected
new file mode 100644 (file)
index 0000000..645626d
--- /dev/null
@@ -0,0 +1,90 @@
+<root><template><title>vorlage</title></template>
+
+<tplarg lineStart="1"><title>argument</title></tplarg>
+
+Nach [[:meta:Help:Expansion#XML parse tree]]
+{<tplarg><title>vorlagenname</title></tplarg>}
+<template lineStart="1"><title> <template><title>vorlagenname</title></template></title></template>
+<template lineStart="1"><title><template><title>vorlagenname</title></template> </title></template>
+<template lineStart="1"><title><template><title>vorlagenname</title></template>erweiterung</title></template>
+
+<template lineStart="1"><title><tplarg><title>vorlagenname</title></tplarg></title></template>
+<tplarg lineStart="1"><title> <template><title>vorlagenname</title></template></title></tplarg>
+<template lineStart="1"><title> <tplarg><title>vorlagenname</title></tplarg></title></template>
+<tplarg lineStart="1"><title><template><title>vorlagenname</title></template> </title></tplarg>
+<template lineStart="1"><title><tplarg><title>vorlagenname</title></tplarg> </title></template>
+
+nur etwas erweitert
+<tplarg lineStart="1"><title><tplarg><title>vorlagenname</title></tplarg></title></tplarg>
+<tplarg lineStart="1"><title> <tplarg><title>vorlagenname</title></tplarg></title></tplarg>
+<tplarg lineStart="1"><title><tplarg><title>vorlagenname</title></tplarg> </title></tplarg>
+<template lineStart="1"><title> {<tplarg><title>vorlagenname</title></tplarg></title></template>}
+{<tplarg><title> <template><title>vorlagenname</title></template></title></tplarg>}
+<template lineStart="1"><title> <template><title> <template><title>vorlagenname</title></template></title></template></title></template>
+{<tplarg><title> <template><title>vorlagenname</title></template>} </title></tplarg>
+{<template><title><tplarg><title>vorlagenname</title></tplarg>} </title></template>
+{<tplarg><title><template><title>vorlagenname</title></template> </title></tplarg>}
+<template lineStart="1"><title> <template><title><template><title>vorlagenname</title></template> </title></template></title></template>
+<tplarg lineStart="1"><title> {<template><title>vorlagenname</title></template> </title></tplarg>}
+
+{<tplarg><title><tplarg><title> </title></tplarg></title></tplarg>}
+
+<template lineStart="1"><title><tplarg><title><tplarg><title> </title></tplarg></title></tplarg></title></template>
+<tplarg lineStart="1"><title><tplarg><title><template><title> </title></template> </title></tplarg></title></tplarg>
+<template lineStart="1"><title><tplarg><title><tplarg><title> </title></tplarg> </title></tplarg></title></template>
+{{<tplarg><title><tplarg><title> </title></tplarg>} </title></tplarg>}
+<tplarg lineStart="1"><title><template><title><tplarg><title> </title></tplarg></title></template> </title></tplarg>
+<template lineStart="1"><title><tplarg><title><tplarg><title> </title></tplarg></title></tplarg> </title></template>
+{<tplarg><title><template><title><template><title> </title></template> </title></template> </title></tplarg>}
+{<template><title><tplarg><title><template><title> </title></template> </title></tplarg>} </title></template>
+{<template><title><template><title><tplarg><title> </title></tplarg>} </title></template> </title></template>
+<template lineStart="1"><title><tplarg><title><tplarg><title> </title></tplarg> </title></tplarg> </title></template>
+<tplarg lineStart="1"><title><template><title><tplarg><title> </title></tplarg> </title></template> </title></tplarg>
+<tplarg lineStart="1"><title><tplarg><title><template><title> </title></template> </title></tplarg> </title></tplarg>
+<template lineStart="1"><title><template><title><template><title><template><title> </title></template> </title></template> </title></template> </title></template>
+
+<template lineStart="1"><title>vorlage</title></template>
+
+<tplarg lineStart="1"><title>argument</title></tplarg>
+
+Nach [[:meta:Help:Expansion#XML parse tree]]
+{<tplarg><title>vorlagenname</title></tplarg>}
+<template lineStart="1"><title> <template><title>vorlagenname</title></template></title></template>
+<template lineStart="1"><title><template><title>vorlagenname</title></template> </title></template>
+<template lineStart="1"><title><template><title>vorlagenname</title></template>erweiterung</title></template>
+
+<template lineStart="1"><title><tplarg><title>vorlagenname</title></tplarg></title></template>
+<tplarg lineStart="1"><title> <template><title>vorlagenname</title></template></title></tplarg>
+<template lineStart="1"><title> <tplarg><title>vorlagenname</title></tplarg></title></template>
+<tplarg lineStart="1"><title><template><title>vorlagenname</title></template> </title></tplarg>
+<template lineStart="1"><title><tplarg><title>vorlagenname</title></tplarg> </title></template>
+
+nur etwas erweitert
+<tplarg lineStart="1"><title><tplarg><title>vorlagenname</title></tplarg></title></tplarg>
+<tplarg lineStart="1"><title> <tplarg><title>vorlagenname</title></tplarg></title></tplarg>
+<tplarg lineStart="1"><title><tplarg><title>vorlagenname</title></tplarg> </title></tplarg>
+<template lineStart="1"><title> {<tplarg><title>vorlagenname</title></tplarg></title></template>}
+{<tplarg><title> <template><title>vorlagenname</title></template></title></tplarg>}
+<template lineStart="1"><title> <template><title> <template><title>vorlagenname</title></template></title></template></title></template>
+{<tplarg><title> <template><title>vorlagenname</title></template>} </title></tplarg>
+{<template><title><tplarg><title>vorlagenname</title></tplarg>} </title></template>
+{<tplarg><title><template><title>vorlagenname</title></template> </title></tplarg>}
+<template lineStart="1"><title> <template><title><template><title>vorlagenname</title></template> </title></template></title></template>
+<tplarg lineStart="1"><title> {<template><title>vorlagenname</title></template> </title></tplarg>}
+
+{<tplarg><title><tplarg><title> </title></tplarg></title></tplarg>}
+
+<template lineStart="1"><title><tplarg><title><tplarg><title> </title></tplarg></title></tplarg></title></template>
+<tplarg lineStart="1"><title><tplarg><title><template><title> </title></template> </title></tplarg></title></tplarg>
+<template lineStart="1"><title><tplarg><title><tplarg><title> </title></tplarg> </title></tplarg></title></template>
+{{<tplarg><title><tplarg><title> </title></tplarg>} </title></tplarg>}
+<tplarg lineStart="1"><title><template><title><tplarg><title> </title></tplarg></title></template> </title></tplarg>
+<template lineStart="1"><title><tplarg><title><tplarg><title> </title></tplarg></title></tplarg> </title></template>
+{<tplarg><title><template><title><template><title> </title></template> </title></template> </title></tplarg>}
+{<template><title><tplarg><title><template><title> </title></template> </title></tplarg>} </title></template>
+{<template><title><template><title><tplarg><title> </title></tplarg>} </title></template> </title></template>
+<template lineStart="1"><title><tplarg><title><tplarg><title> </title></tplarg> </title></tplarg> </title></template>
+<tplarg lineStart="1"><title><template><title><tplarg><title> </title></tplarg> </title></template> </title></tplarg>
+<tplarg lineStart="1"><title><tplarg><title><template><title> </title></template> </title></tplarg> </title></tplarg>
+<template lineStart="1"><title><template><title><template><title><template><title> </title></template> </title></template> </title></template> </title></template>
+</root>
\ No newline at end of file
diff --git a/tests/parser/preprocess/NestedTemplates.txt b/tests/parser/preprocess/NestedTemplates.txt
new file mode 100644 (file)
index 0000000..aa9a472
--- /dev/null
@@ -0,0 +1,89 @@
+{{vorlage}}
+
+{{{argument}}}
+
+Nach [[:meta:Help:Expansion#XML parse tree]]
+{{{{vorlagenname}}}}
+{{ {{vorlagenname}}}}
+{{{{vorlagenname}} }}
+{{{{vorlagenname}}erweiterung}}
+
+{{{{{vorlagenname}}}}}
+{{{ {{vorlagenname}}}}}
+{{ {{{vorlagenname}}}}}
+{{{{{vorlagenname}} }}}
+{{{{{vorlagenname}}} }}
+
+nur etwas erweitert
+{{{{{{vorlagenname}}}}}}
+{{{ {{{vorlagenname}}}}}}
+{{{{{{vorlagenname}}} }}}
+{{ {{{{vorlagenname}}}}}}
+{{{{ {{vorlagenname}}}}}}
+{{ {{ {{vorlagenname}}}}}}
+{{{{ {{vorlagenname}}} }}}
+{{{{{{vorlagenname}}}} }}
+{{{{{{vorlagenname}} }}}}
+{{ {{{{vorlagenname}} }}}}
+{{{ {{{vorlagenname}} }}}}
+
+{{{{{{{ }}}}}}}
+
+{{{{{{{{ }}}}}}}}
+{{{{{{{{ }} }}}}}}
+{{{{{{{{ }}} }}}}}
+{{{{{{{{ }}}} }}}}
+{{{{{{{{ }}}}} }}}
+{{{{{{{{ }}}}}} }}
+{{{{{{{{ }} }} }}}}
+{{{{{{{{ }} }}}} }}
+{{{{{{{{ }}}} }} }}
+{{{{{{{{ }}} }}} }}
+{{{{{{{{ }}} }} }}}
+{{{{{{{{ }} }}} }}}
+{{{{{{{{ }} }} }} }}
+
+{{vorlage}}
+
+{{{argument}}}
+
+Nach [[:meta:Help:Expansion#XML parse tree]]
+{{{{vorlagenname}}}}
+{{ {{vorlagenname}}}}
+{{{{vorlagenname}} }}
+{{{{vorlagenname}}erweiterung}}
+
+{{{{{vorlagenname}}}}}
+{{{ {{vorlagenname}}}}}
+{{ {{{vorlagenname}}}}}
+{{{{{vorlagenname}} }}}
+{{{{{vorlagenname}}} }}
+
+nur etwas erweitert
+{{{{{{vorlagenname}}}}}}
+{{{ {{{vorlagenname}}}}}}
+{{{{{{vorlagenname}}} }}}
+{{ {{{{vorlagenname}}}}}}
+{{{{ {{vorlagenname}}}}}}
+{{ {{ {{vorlagenname}}}}}}
+{{{{ {{vorlagenname}}} }}}
+{{{{{{vorlagenname}}}} }}
+{{{{{{vorlagenname}} }}}}
+{{ {{{{vorlagenname}} }}}}
+{{{ {{{vorlagenname}} }}}}
+
+{{{{{{{ }}}}}}}
+
+{{{{{{{{ }}}}}}}}
+{{{{{{{{ }} }}}}}}
+{{{{{{{{ }}} }}}}}
+{{{{{{{{ }}}} }}}}
+{{{{{{{{ }}}}} }}}
+{{{{{{{{ }}}}}} }}
+{{{{{{{{ }} }} }}}}
+{{{{{{{{ }} }}}} }}
+{{{{{{{{ }}}} }} }}
+{{{{{{{{ }}} }}} }}
+{{{{{{{{ }}} }} }}}
+{{{{{{{{ }} }}} }}}
+{{{{{{{{ }} }} }} }}
index 105ce6d..1219d43 100644 (file)
@@ -425,15 +425,6 @@ class GlobalTest extends MediaWikiTestCase {
 
        }
 
-
-       function testInStringTest() {
-       
-               $this->assertTrue( in_string( 'foo', 'foobar' ), 'foo is in foobar' );
-               $this->assertFalse( in_string( 'Bar', 'foobar' ), 'Case-sensitive by default' );
-               $this->assertTrue( in_string( 'Foo', 'foobar', true ), 'Case-insensitive when asked' );
-       
-       }
-
        /**
         * test @see wfShorthandToInteger()
         * @dataProvider provideShorthand
index 47fa5f4..32b791e 100644 (file)
@@ -165,22 +165,22 @@ class HtmlTest extends MediaWikiTestCase {
                $this->assertEquals(
                        ' empty_string=""',
                        Html::expandAttributes( array( 'empty_string' => '' ) ),
-                       'Attribtue values are always quoted (wgWellFormedXml): Empty string'
+                       'Attribute values are always quoted (wgWellFormedXml): Empty string'
                );
                $this->assertEquals(
                        ' key="value"',
                        Html::expandAttributes( array( 'key' => 'value' ) ),
-                       'Attribtue values are always quoted (wgWellFormedXml): Simple string'
+                       'Attribute values are always quoted (wgWellFormedXml): Simple string'
                );
                $this->assertEquals(
                        ' one="1"',
                        Html::expandAttributes( array( 'one' => 1 ) ),
-                       'Attribtue values are always quoted (wgWellFormedXml): Number 1'
+                       'Attribute values are always quoted (wgWellFormedXml): Number 1'
                );
                $this->assertEquals(
                        ' zero="0"',
                        Html::expandAttributes( array( 'zero' => 0 ) ),
-                       'Attribtue values are always quoted (wgWellFormedXml): Number 0'
+                       'Attribute values are always quoted (wgWellFormedXml): Number 0'
                );
        }
 
diff --git a/tests/phpunit/includes/ParserOptionsTest.php b/tests/phpunit/includes/ParserOptionsTest.php
deleted file mode 100644 (file)
index 5b2adaf..0000000
+++ /dev/null
@@ -1,37 +0,0 @@
-<?php
-
-class ParserOptionsTest extends MediaWikiTestCase {
-
-       private $popts;
-       private $pcache;
-
-       protected function setUp() {
-               global $wgLanguageCode, $wgUser;
-               parent::setUp();
-
-               $langObj = Language::factory( $wgLanguageCode );
-
-               $this->setMwGlobals( array(
-                       'wgContLang' => $langObj,
-                       'wgUseDynamicDates' => true,
-               ) );
-
-               $this->popts = ParserOptions::newFromUserAndLang( $wgUser, $langObj );
-               $this->pcache = ParserCache::singleton();
-       }
-
-       /**
-        * ParserOptions::optionsHash was not giving consistent results when $wgUseDynamicDates was set
-        * @group Database
-        */
-       function testGetParserCacheKeyWithDynamicDates() {
-               $title = Title::newFromText( "Some test article" );
-               $page = WikiPage::factory( $title );
-
-               $pcacheKeyBefore = $this->pcache->getKey( $page, $this->popts );
-               $this->assertNotNull( $this->popts->getDateFormat() );
-
-               $pcacheKeyAfter = $this->pcache->getKey( $page, $this->popts );
-               $this->assertEquals( $pcacheKeyBefore, $pcacheKeyAfter );
-       }
-}
diff --git a/tests/phpunit/includes/UIDGeneratorTest.php b/tests/phpunit/includes/UIDGeneratorTest.php
new file mode 100644 (file)
index 0000000..23553ca
--- /dev/null
@@ -0,0 +1,76 @@
+<?php
+
+class UIDGeneratorTest extends MediaWikiTestCase {
+       /**
+        * @dataProvider provider_testTimestampedUID
+        */
+       public function testTimestampedUID( $method, $digitlen, $bits, $tbits, $hostbits ) {
+               $id = call_user_func( array( 'UIDGenerator', $method ) );
+               $this->assertEquals( true, ctype_digit( $id ), "UID made of digit characters" );
+               $this->assertLessThanOrEqual( $digitlen, strlen( $id ),
+                       "UID has the right number of digits" );
+               $this->assertLessThanOrEqual( $bits, strlen( wfBaseConvert( $id, 10, 2 ) ),
+                       "UID has the right number of bits" );
+
+               $ids = array();
+               for ( $i = 0; $i < 300; $i++ ) {
+                       $ids[] = call_user_func( array( 'UIDGenerator', $method ) );
+               }
+
+               $lastId = array_shift( $ids );
+               if ( $hostbits ) {
+                       $lastHost = substr( wfBaseConvert( $lastId, 10, 2, $bits ), -$hostbits );
+               }
+
+               $this->assertArrayEquals( array_unique( $ids ), $ids, "All generated IDs are unique." );
+
+               foreach ( $ids as $id ) {
+                       $id_bin = wfBaseConvert( $id, 10, 2 );
+                       $lastId_bin = wfBaseConvert( $lastId, 10, 2 );
+
+                       $this->assertGreaterThanOrEqual(
+                               substr( $id_bin, 0, $tbits ),
+                               substr( $lastId_bin, 0, $tbits ),
+                               "New ID timestamp ($id_bin) >= prior one ($lastId_bin)." );
+
+                       if ( $hostbits ) {
+                               $this->assertEquals(
+                                       substr( $id_bin, 0, -$hostbits ),
+                                       substr( $lastId_bin, 0, -$hostbits ),
+                                       "Host ID of ($id_bin) is same as prior one ($lastId_bin)." );
+                       }
+
+                       $lastId = $id;
+               }
+       }
+
+       /**
+        * array( method, length, bits, hostbits )
+        */
+       public static function provider_testTimestampedUID() {
+               return array(
+                       array( 'newTimestampedUID128', 39, 128, 46, 48 ),
+                       array( 'newTimestampedUID128', 39, 128, 46, 48 ),
+                       array( 'newTimestampedUID88', 27, 88, 46, 32 ),
+               );
+       }
+
+       public function testUUIDv4() {
+               for ( $i = 0; $i < 100; $i++ ) {
+                       $id = UIDGenerator::newUUIDv4();
+                       $this->assertEquals( true,
+                               preg_match( '!^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$!', $id ),
+                               "UID $id has the right format" );
+
+                       $id = UIDGenerator::newRawUUIDv4();
+                       $this->assertEquals( true,
+                               preg_match( '!^[0-9a-f]{12}4[0-9a-f]{3}[89ab][0-9a-f]{15}$!', $id ),
+                               "UID $id has the right format" );
+
+                       $id = UIDGenerator::newRawUUIDv4( UIDGenerator::QUICK_RAND );
+                       $this->assertEquals( true,
+                               preg_match( '!^[0-9a-f]{12}4[0-9a-f]{3}[89ab][0-9a-f]{15}$!', $id ),
+                               "UID $id has the right format" );
+               }
+       }
+}
index e5a8717..445969b 100644 (file)
@@ -39,7 +39,7 @@ class ApiGeneratorTest extends MediaWikiTestCase {
         */
        public function provideApiquerygeneratorbaseChilds() {
                $cases = array();
-               $modules = $this->getApiQuery()->getModules();
+               $modules = $this->getApiQuery()->getModuleManager()->getNamesWithClasses();
                foreach( $modules as $moduleName => $moduleClass ) {
                        if( !is_subclass_of( $moduleClass, 'ApiQueryGeneratorBase' ) ) {
                                continue;
@@ -55,7 +55,7 @@ class ApiGeneratorTest extends MediaWikiTestCase {
        public function testGeneratorsAreApiquerygeneratorbaseSubclasses(
                $generatorName, $generatorClass
        ) {
-               $modules = $this->getApiQuery()->getModules();
+               $modules = $this->getApiQuery()->getModuleManager()->getNamesWithClasses();
                $this->assertArrayHasKey( $generatorName, $modules,
                        "Class '$generatorClass' of generator '$generatorName' must be a subclass of 'ApiQueryGeneratorBase'. Listed either in ApiQuery::\$mQueryGenerators or in \$wgAPIGeneratorModules."
                );
diff --git a/tests/phpunit/includes/api/ApiQueryRevisionsTest.php b/tests/phpunit/includes/api/ApiQueryRevisionsTest.php
deleted file mode 100644 (file)
index 19da81c..0000000
+++ /dev/null
@@ -1,42 +0,0 @@
-<?php
-
-/**
- * @group API
- * @group Database
- * @group medium
- */
-class ApiQueryRevisionsTest extends ApiTestCase {
-
-       /**
-        * @group medium
-        */
-       function testContentComesWithContentModelAndFormat() {
-
-               $pageName = 'Help:' . __METHOD__ ;
-               $title = Title::newFromText( $pageName );
-               $page = WikiPage::factory( $title );
-               $page->doEdit( 'Some text', 'inserting content' );
-
-               $apiResult = $this->doApiRequest( array(
-                       'action' => 'query',
-                       'prop' => 'revisions',
-                       'titles' => $pageName,
-                       'rvprop' => 'content',
-               ) );
-               $this->assertArrayHasKey( 'query', $apiResult[0] );
-               $this->assertArrayHasKey( 'pages', $apiResult[0]['query'] );
-               foreach( $apiResult[0]['query']['pages'] as $page ) {
-                       $this->assertArrayHasKey( 'revisions', $page );
-                       foreach( $page['revisions'] as $revision ) {
-                               $this->assertArrayHasKey( 'contentformat', $revision,
-                                       'contentformat should be included when asking content so'
-                                       . ' client knows how to interpretate it'
-                               );
-                               $this->assertArrayHasKey( 'contentmodel', $revision,
-                                       'contentmodel should be included when asking content so'
-                                       . ' client knows how to interpretate it'
-                               );
-                       }
-               }
-       }
-}
diff --git a/tests/phpunit/includes/api/ApiQueryTest.php b/tests/phpunit/includes/api/ApiQueryTest.php
deleted file mode 100644 (file)
index 1b1886e..0000000
+++ /dev/null
@@ -1,69 +0,0 @@
-<?php
-
-/**
- * @group API
- * @group Database
- * @group medium
- */
-class ApiQueryTest extends ApiTestCase {
-
-       protected function setUp() {
-               parent::setUp();
-               $this->doLogin();
-       }
-
-       function testTitlesGetNormalized() {
-
-               global $wgMetaNamespace;
-
-               $data = $this->doApiRequest( array(
-                       'action' => 'query',
-                       'titles' => 'Project:articleA|article_B' ) );
-
-
-               $this->assertArrayHasKey( 'query', $data[0] );
-               $this->assertArrayHasKey( 'normalized', $data[0]['query'] );
-
-               // Forge a normalized title
-               $to = Title::newFromText( $wgMetaNamespace.':ArticleA' );
-
-               $this->assertEquals(
-                       array(
-                               'from' => 'Project:articleA',
-                               'to' => $to->getPrefixedText(),
-                       ),
-                       $data[0]['query']['normalized'][0]
-               );
-
-               $this->assertEquals(
-                       array(
-                               'from' => 'article_B',
-                               'to' => 'Article B'
-                       ),
-                       $data[0]['query']['normalized'][1]
-               );
-
-       }
-
-       function testTitlesAreRejectedIfInvalid() {
-               $title = false;
-               while( !$title || Title::newFromText( $title )->exists() ) {
-                       $title = md5( mt_rand( 0, 10000 ) + rand( 0, 999000 ) );
-               }
-
-               $data = $this->doApiRequest( array(
-                       'action' => 'query',
-                       'titles' => $title . '|Talk:' ) );
-
-               $this->assertArrayHasKey( 'query', $data[0] );
-               $this->assertArrayHasKey( 'pages', $data[0]['query'] );
-               $this->assertEquals( 2, count( $data[0]['query']['pages'] ) );
-
-               $this->assertArrayHasKey( -2, $data[0]['query']['pages'] );
-               $this->assertArrayHasKey( -1, $data[0]['query']['pages'] );
-
-               $this->assertArrayHasKey( 'missing', $data[0]['query']['pages'][-2] );
-               $this->assertArrayHasKey( 'invalid', $data[0]['query']['pages'][-1] );
-       }
-
-}
index fcd581a..4e3f6e5 100644 (file)
@@ -9,14 +9,10 @@ abstract class ApiTestCase extends MediaWikiLangTestCase {
        protected $apiContext;
 
        protected function setUp() {
-               global $wgContLang, $wgAuth, $wgMemc, $wgRequest, $wgUser, $wgServer;
+               global $wgServer;
 
                parent::setUp();
                self::$apiUrl = $wgServer . wfScript( 'api' );
-               $wgMemc = new EmptyBagOStuff();
-               $wgContLang = Language::factory( 'en' );
-               $wgAuth = new StubObject( 'wgAuth', 'AuthPlugin' );
-               $wgRequest = new FauxRequest( array() );
 
                ApiQueryInfo::resetTokenCache(); // tokens are invalid because we cleared the session
 
@@ -35,10 +31,28 @@ abstract class ApiTestCase extends MediaWikiLangTestCase {
                        )
                );
 
-               $wgUser = self::$users['sysop']->user;
+               $this->setMwGlobals( array(
+                       'wgMemc' => new EmptyBagOStuff(),
+                       'wgAuth' => new StubObject( 'wgAuth', 'AuthPlugin' ),
+                       'wgRequest' => new FauxRequest( array() ),
+                       'wgUser' => self::$users['sysop']->user,
+               ) );
 
                $this->apiContext = new ApiTestContext();
+       }
 
+       /**
+        * Edits or creates a page/revision
+        * @param $pageName string page title
+        * @param $text string content of the page
+        * @param $summary string optional summary string for the revision
+        * @param $defaultNs int optional namespace id
+        * @return array as returned by WikiPage::doEditContent()
+        */
+       protected function editPage( $pageName, $text, $summary = '', $defaultNs = NS_MAIN ) {
+               $title = Title::newFromText( $pageName, $defaultNs );
+               $page = WikiPage::factory( $title );
+               return $page->doEditContent( ContentHandler::makeContent( $text, $title ), $summary );
        }
 
        /**
@@ -102,6 +116,8 @@ abstract class ApiTestCase extends MediaWikiLangTestCase {
         * @param $params Array: key-value API params
         * @param $session Array|null: session array
         * @param $user User|null A User object for the context
+        * @return result of the API call
+        * @throws Exception in case wsToken is not set in the session
         */
        protected function doApiRequestWithToken( array $params, array $session = null, User $user = null ) {
                global $wgRequest;
@@ -161,7 +177,9 @@ abstract class ApiTestCase extends MediaWikiLangTestCase {
 }
 
 class UserWrapper {
-       public $userName, $password, $user;
+       public $userName;
+       public $password;
+       public $user;
 
        public function __construct( $userName, $password, $group = '' ) {
                $this->userName = $userName;
index 642fed0..89c0c00 100644 (file)
@@ -349,8 +349,9 @@ class ApiUploadTest extends ApiTestCaseUpload {
         * @depends testLogin
         */
        public function testUploadStash( $session ) {
-               global $wgUser;
-               $wgUser = self::$users['uploader']->user; // @todo FIXME: still used somewhere
+               $this->setMwGlobals( array(
+                       'wgUser' => self::$users['uploader']->user, // @todo FIXME: still used somewhere
+               ) );
 
                $extension = 'png';
                $mimeType = 'image/png';
@@ -433,9 +434,10 @@ class ApiUploadTest extends ApiTestCaseUpload {
         * @depends testLogin
         */
        public function testUploadChunks( $session ) {
-               global $wgUser;
-               $wgUser = self::$users['uploader']->user; // @todo FIXME: still used somewhere
-               
+               $this->setMwGlobals( array(
+                       'wgUser' => self::$users['uploader']->user, // @todo FIXME: still used somewhere
+               ) );
+
                $chunkSize = 1048576;
                // Download a large image file
                // ( using RandomImageGenerator for large files is not stable )
index 3bacb05..d9be85e 100644 (file)
@@ -9,7 +9,7 @@ class PrefixUniquenessTest extends MediaWikiTestCase {
        public function testPrefixes() {
                $main = new ApiMain( new FauxRequest() );
                $query = new ApiQuery( $main, 'foo', 'bar' );
-               $modules = $query->getModules();
+               $modules = $query->getModuleManager()->getNamesWithClasses();
                $prefixes = array();
 
                foreach ( $modules as $name => $class ) {
diff --git a/tests/phpunit/includes/api/query/ApiQueryBasicTest.php b/tests/phpunit/includes/api/query/ApiQueryBasicTest.php
new file mode 100644 (file)
index 0000000..b7dac06
--- /dev/null
@@ -0,0 +1,392 @@
+<?php
+/**
+ *
+ *
+ * Created on Feb 6, 2013
+ *
+ * Copyright © 2013 Yuri Astrakhan "<Firstname><Lastname>@gmail.com"
+ *
+ * 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
+ *
+ * These tests validate basic functionality of the api query module
+ *
+ * @group API
+ * @group Database
+ * @group medium
+ */
+class ApiQueryBasicTest extends ApiTestCase {
+
+       /**
+        * Create a set of pages. These must not change, otherwise the tests might give wrong results.
+        * @see MediaWikiTestCase::addDBData()
+        */
+       function addDBData() {
+               try {
+                       if ( Title::newFromText( 'AQBT-All' )->exists() ) {
+                               return;
+                       }
+
+                       // Ordering is important, as it will be returned in the same order as stored in the index
+                       $this->editPage( 'AQBT-All', '[[Category:AQBT-Cat]] [[AQBT-Links]] {{AQBT-T}}' );
+                       $this->editPage( 'AQBT-Categories', '[[Category:AQBT-Cat]]' );
+                       $this->editPage( 'AQBT-Links', '[[AQBT-All]] [[AQBT-Categories]] [[AQBT-Templates]]' );
+                       $this->editPage( 'AQBT-Templates', '{{AQBT-T}}' );
+                       $this->editPage( 'AQBT-T', 'Content', '', NS_TEMPLATE );
+
+                       // Refresh due to the bug with listing transclusions as links if they don't exist
+                       $this->editPage( 'AQBT-All', '[[Category:AQBT-Cat]] [[AQBT-Links]] {{AQBT-T}}' );
+                       $this->editPage( 'AQBT-Templates', '{{AQBT-T}}' );
+               } catch ( Exception $e ) {
+                       $this->exceptionFromAddDBData = $e;
+               }
+       }
+
+       private static $links = array(
+               array( 'prop' => 'links', 'titles' => 'AQBT-All' ),
+               array( 'pages' => array(
+                       '1' => array(
+                               'pageid' => 1,
+                               'ns' => 0,
+                               'title' => 'AQBT-All',
+                               'links' => array(
+                                       array( 'ns' => 0, 'title' => 'AQBT-Links' ),
+       ) ) ) ) );
+
+       private static $templates = array(
+               array( 'prop' => 'templates', 'titles' => 'AQBT-All' ),
+               array( 'pages' => array(
+                       '1' => array(
+                               'pageid' => 1,
+                               'ns' => 0,
+                               'title' => 'AQBT-All',
+                               'templates' => array(
+                                       array( 'ns' => 10, 'title' => 'Template:AQBT-T' ),
+       ) ) ) ) );
+
+       private static $categories = array(
+               array( 'prop' => 'categories', 'titles' => 'AQBT-All' ),
+               array( 'pages' => array(
+                       '1' => array(
+                               'pageid' => 1,
+                               'ns' => 0,
+                               'title' => 'AQBT-All',
+                               'categories' => array(
+                                       array( 'ns' => 14, 'title' => 'Category:AQBT-Cat' ),
+       ) ) ) ) );
+
+       private static $allpages = array(
+               array( 'list' => 'allpages', 'apprefix' => 'AQBT-' ),
+               array( 'allpages' => array(
+                       array( 'pageid' => 1, 'ns' => 0, 'title' => 'AQBT-All' ),
+                       array( 'pageid' => 2, 'ns' => 0, 'title' => 'AQBT-Categories' ),
+                       array( 'pageid' => 3, 'ns' => 0, 'title' => 'AQBT-Links' ),
+                       array( 'pageid' => 4, 'ns' => 0, 'title' => 'AQBT-Templates' ),
+       ) ) );
+
+       private static $alllinks = array(
+               array( 'list' => 'alllinks', 'alprefix' => 'AQBT-' ),
+               array( 'alllinks' => array(
+                       array( 'ns' => 0, 'title' => 'AQBT-All' ),
+                       array( 'ns' => 0, 'title' => 'AQBT-Categories' ),
+                       array( 'ns' => 0, 'title' => 'AQBT-Links' ),
+                       array( 'ns' => 0, 'title' => 'AQBT-Templates' ),
+       ) ) );
+
+       private static $alltransclusions = array(
+               array( 'list' => 'alltransclusions', 'atprefix' => 'AQBT-' ),
+               array( 'alltransclusions' => array(
+                       array( 'ns' => 10, 'title' => 'Template:AQBT-T' ),
+                       array( 'ns' => 10, 'title' => 'Template:AQBT-T' ),
+       ) ) );
+
+       private static $allcategories = array(
+               array( 'list' => 'allcategories', 'acprefix' => 'AQBT-' ),
+               array( 'allcategories' => array(
+                       array( '*' => 'AQBT-Cat' ),
+       ) ) );
+
+       private static $backlinks = array(
+               array( 'list' => 'backlinks', 'bltitle' => 'AQBT-Links' ),
+               array( 'backlinks' => array(
+                       array( 'pageid' => 1, 'ns' => 0, 'title' => 'AQBT-All' ),
+       ) ) );
+
+       private static $embeddedin = array(
+               array( 'list' => 'embeddedin', 'eititle' => 'Template:AQBT-T' ),
+               array( 'embeddedin' => array(
+                       array( 'pageid' => 1, 'ns' => 0, 'title' => 'AQBT-All' ),
+                       array( 'pageid' => 4, 'ns' => 0, 'title' => 'AQBT-Templates' ),
+       ) ) );
+
+       private static $categorymembers = array(
+               array( 'list' => 'categorymembers', 'cmtitle' => 'Category:AQBT-Cat' ),
+               array( 'categorymembers' => array(
+                       array( 'pageid' => 1, 'ns' => 0, 'title' => 'AQBT-All' ),
+                       array( 'pageid' => 2, 'ns' => 0, 'title' => 'AQBT-Categories' ),
+       ) ) );
+
+       private static $generatorAllpages = array(
+               array( 'generator' => 'allpages', 'gapprefix' => 'AQBT-' ),
+               array( 'pages' => array(
+                       '1' => array(
+                               'pageid' => 1,
+                               'ns' => 0,
+                               'title' => 'AQBT-All' ),
+                       '2' => array(
+                               'pageid' => 2,
+                               'ns' => 0,
+                               'title' => 'AQBT-Categories' ),
+                       '3' => array(
+                               'pageid' => 3,
+                               'ns' => 0,
+                               'title' => 'AQBT-Links' ),
+                       '4' => array(
+                               'pageid' => 4,
+                               'ns' => 0,
+                               'title' => 'AQBT-Templates' ),
+       ) ) );
+
+       private static $generatorLinks = array(
+               array( 'generator' => 'links', 'titles' => 'AQBT-Links' ),
+               array( 'pages' => array(
+                       '1' => array(
+                               'pageid' => 1,
+                               'ns' => 0,
+                               'title' => 'AQBT-All' ),
+                       '2' => array(
+                               'pageid' => 2,
+                               'ns' => 0,
+                               'title' => 'AQBT-Categories' ),
+                       '4' => array(
+                               'pageid' => 4,
+                               'ns' => 0,
+                               'title' => 'AQBT-Templates' ),
+       ) ) );
+
+       private static $generatorLinksPropLinks = array(
+               array( 'prop' => 'links' ),
+               array( 'pages' => array(
+                       '1' => array( 'links' => array(
+                               array( 'ns' => 0, 'title' => 'AQBT-Links' ),
+       ) ) ) ) );
+
+       private static $generatorLinksPropTemplates = array(
+               array( 'prop' => 'templates' ),
+               array( 'pages' => array(
+                       '1' => array( 'templates' => array(
+                               array( 'ns' => 10, 'title' => 'Template:AQBT-T' ) ) ),
+                       '4' => array( 'templates' => array(
+                               array( 'ns' => 10, 'title' => 'Template:AQBT-T' ) ) ),
+               ) ) );
+
+       /**
+        * Test basic props
+        */
+       public function testProps() {
+               $this->check( self::$links );
+               $this->check( self::$templates );
+               $this->check( self::$categories );
+       }
+
+       /**
+        * Test basic lists
+        */
+       public function testLists() {
+               $this->check( self::$allpages );
+               $this->check( self::$alllinks );
+               $this->check( self::$alltransclusions );
+               // This test is temporarily disabled until a sqlite bug is fixed
+               // $this->check( self::$allcategories );
+               $this->check( self::$backlinks );
+               $this->check( self::$embeddedin );
+               $this->check( self::$categorymembers );
+       }
+
+       /**
+        * Test basic lists
+        */
+       public function testAllTogether() {
+
+               // All props together
+               $this->check( $this->merge(
+                       self::$links,
+                       self::$templates,
+                       self::$categories
+               ) );
+
+               // All lists together
+               $this->check( $this->merge(
+                       self::$allpages,
+                       self::$alllinks,
+                       self::$alltransclusions,
+                       // This test is temporarily disabled until a sqlite bug is fixed
+                       // self::$allcategories,
+                       self::$backlinks,
+                       self::$embeddedin,
+                       self::$categorymembers
+               ) );
+
+               // All props+lists together
+               $this->check( $this->merge(
+                       self::$links,
+                       self::$templates,
+                       self::$categories,
+                       self::$allpages,
+                       self::$alllinks,
+                       self::$alltransclusions,
+                       // This test is temporarily disabled until a sqlite bug is fixed
+                       // self::$allcategories,
+                       self::$backlinks,
+                       self::$embeddedin,
+                       self::$categorymembers
+               ) );
+       }
+
+       /**
+        * Test basic lists
+        */
+       public function testGenerator() {
+               // generator=allpages
+               $this->check( self::$generatorAllpages );
+               // generator=allpages & list=allpages
+               $this->check( $this->merge(
+                       self::$generatorAllpages,
+                       self::$allpages ) );
+               // generator=links
+               $this->check( self::$generatorLinks );
+               // generator=links & prop=links
+               $this->check( $this->merge(
+                       self::$generatorLinks,
+                       self::$generatorLinksPropLinks ) );
+               // generator=links & prop=templates
+               $this->check( $this->merge(
+                       self::$generatorLinks,
+                       self::$generatorLinksPropTemplates ) );
+               // generator=links & prop=links|templates
+               $this->check( $this->merge(
+                       self::$generatorLinks,
+                       self::$generatorLinksPropLinks,
+                       self::$generatorLinksPropTemplates ) );
+               // generator=links & prop=links|templates & list=allpages|...
+               $this->check( $this->merge(
+                       self::$generatorLinks,
+                       self::$generatorLinksPropLinks,
+                       self::$generatorLinksPropTemplates,
+                       self::$allpages,
+                       self::$alllinks,
+                       self::$alltransclusions,
+                       // This test is temporarily disabled until a sqlite bug is fixed
+                       // self::$allcategories,
+                       self::$backlinks,
+                       self::$embeddedin,
+                       self::$categorymembers ) );
+       }
+
+       /**
+        * Merges all requests (parameter arrays) into one
+        * @return array
+        */
+       private function merge( /*...*/ ) {
+               $request = array();
+               $expected = array();
+               foreach ( func_get_args() as $v ) {
+                       $request = array_merge_recursive( $request, $v[0] );
+                       $this->mergeExpected( $expected, $v[1] );
+               }
+               return array( $request, $expected );
+       }
+
+       /**
+        * Recursively merges the expected values in the $item into the $all
+        */
+       private function mergeExpected( &$all, $item ) {
+               foreach ( $item as $k => $v ) {
+                       if ( array_key_exists( $k, $all ) ) {
+                               if ( is_array ( $all[$k] ) ) {
+                                       $this->mergeExpected( $all[$k], $v );
+                               } else {
+                                       $this->assertEquals( $all[$k], $v );
+                               }
+                       } else {
+                               $all[$k] = $v;
+                       }
+               }
+       }
+
+       /**
+        * Checks that the request's result matches the expected results.
+        * @param $values array is a two element array( request, expected_results )
+        * @throws Exception
+        */
+       private function check( $values ) {
+               $request = $values[0];
+               $expected = $values[1];
+               if ( !array_key_exists( 'action', $request ) ) {
+                       $request['action'] = 'query';
+               }
+               foreach ( $request as &$val ) {
+                       if ( is_array( $val ) ) {
+                               $val = implode( '|', array_unique( $val ) );
+                       }
+               }
+               $result = $this->doApiRequest( $request );
+               $result = $result[0];
+               $expected = array( 'query' => $expected );
+               try {
+                       $this->assertQueryResults( $expected, $result );
+               } catch (Exception $e) {
+                       print("\nRequest:\n");
+                       print_r( $request );
+                       print("\nExpected:\n");
+                       print_r( $expected );
+                       print("\nResult:\n");
+                       print_r( $result );
+                       throw $e; // rethrow it
+               }
+       }
+
+       /**
+        * Recursively compare arrays, ignoring mismatches in numeric key and pageids.
+        * @param $expected array expected values
+        * @param $result array returned values
+        */
+       private function assertQueryResults( $expected, $result ) {
+               reset( $expected );
+               reset( $result );
+               while ( true ) {
+                       $e = each( $expected );
+                       $r = each( $result );
+                       // If either of the arrays is shorter, abort. If both are done, success.
+                       $this->assertEquals( (bool)$e, (bool)$r );
+                       if ( !$e ) {
+                               break; // done
+                       }
+                       // continue only if keys are identical or both keys are numeric
+                       $this->assertTrue( $e['key'] === $r['key'] || ( is_numeric( $e['key'] ) && is_numeric( $r['key'] ) ) );
+                       // don't compare pageids
+                       if ( $e['key'] !== 'pageid' ) {
+                               // If values are arrays, compare recursively, otherwise compare with ===
+                               if ( is_array( $e['value'] ) && is_array( $r['value'] ) ) {
+                                       $this->assertQueryResults( $e['value'], $r['value'] );
+                               } else {
+                                       $this->assertEquals( $e['value'], $r['value'] );
+                               }
+                       }
+               }
+       }
+}
diff --git a/tests/phpunit/includes/api/query/ApiQueryRevisionsTest.php b/tests/phpunit/includes/api/query/ApiQueryRevisionsTest.php
new file mode 100644 (file)
index 0000000..594dc66
--- /dev/null
@@ -0,0 +1,40 @@
+<?php
+
+/**
+ * @group API
+ * @group Database
+ * @group medium
+ */
+class ApiQueryRevisionsTest extends ApiTestCase {
+
+       /**
+        * @group medium
+        */
+       function testContentComesWithContentModelAndFormat() {
+
+               $pageName = 'Help:' . __METHOD__ ;
+               $title = Title::newFromText( $pageName );
+               $page = WikiPage::factory( $title );
+               $page->doEdit( 'Some text', 'inserting content' );
+
+               $apiResult = $this->doApiRequest( array(
+                       'action' => 'query',
+                       'prop' => 'revisions',
+                       'titles' => $pageName,
+                       'rvprop' => 'content',
+               ) );
+               $this->assertArrayHasKey( 'query', $apiResult[0] );
+               $this->assertArrayHasKey( 'pages', $apiResult[0]['query'] );
+               foreach( $apiResult[0]['query']['pages'] as $page ) {
+                       $this->assertArrayHasKey( 'revisions', $page );
+                       foreach( $page['revisions'] as $revision ) {
+                               $this->assertArrayHasKey( 'contentformat', $revision,
+                                       'contentformat should be included when asking content so client knows how to interpret it'
+                               );
+                               $this->assertArrayHasKey( 'contentmodel', $revision,
+                                       'contentmodel should be included when asking content so client knows how to interpret it'
+                               );
+                       }
+               }
+       }
+}
diff --git a/tests/phpunit/includes/api/query/ApiQueryTest.php b/tests/phpunit/includes/api/query/ApiQueryTest.php
new file mode 100644 (file)
index 0000000..1b1886e
--- /dev/null
@@ -0,0 +1,69 @@
+<?php
+
+/**
+ * @group API
+ * @group Database
+ * @group medium
+ */
+class ApiQueryTest extends ApiTestCase {
+
+       protected function setUp() {
+               parent::setUp();
+               $this->doLogin();
+       }
+
+       function testTitlesGetNormalized() {
+
+               global $wgMetaNamespace;
+
+               $data = $this->doApiRequest( array(
+                       'action' => 'query',
+                       'titles' => 'Project:articleA|article_B' ) );
+
+
+               $this->assertArrayHasKey( 'query', $data[0] );
+               $this->assertArrayHasKey( 'normalized', $data[0]['query'] );
+
+               // Forge a normalized title
+               $to = Title::newFromText( $wgMetaNamespace.':ArticleA' );
+
+               $this->assertEquals(
+                       array(
+                               'from' => 'Project:articleA',
+                               'to' => $to->getPrefixedText(),
+                       ),
+                       $data[0]['query']['normalized'][0]
+               );
+
+               $this->assertEquals(
+                       array(
+                               'from' => 'article_B',
+                               'to' => 'Article B'
+                       ),
+                       $data[0]['query']['normalized'][1]
+               );
+
+       }
+
+       function testTitlesAreRejectedIfInvalid() {
+               $title = false;
+               while( !$title || Title::newFromText( $title )->exists() ) {
+                       $title = md5( mt_rand( 0, 10000 ) + rand( 0, 999000 ) );
+               }
+
+               $data = $this->doApiRequest( array(
+                       'action' => 'query',
+                       'titles' => $title . '|Talk:' ) );
+
+               $this->assertArrayHasKey( 'query', $data[0] );
+               $this->assertArrayHasKey( 'pages', $data[0]['query'] );
+               $this->assertEquals( 2, count( $data[0]['query']['pages'] ) );
+
+               $this->assertArrayHasKey( -2, $data[0]['query']['pages'] );
+               $this->assertArrayHasKey( -1, $data[0]['query']['pages'] );
+
+               $this->assertArrayHasKey( 'missing', $data[0]['query']['pages'][-2] );
+               $this->assertArrayHasKey( 'invalid', $data[0]['query']['pages'][-1] );
+       }
+
+}
index db369fc..3e71603 100644 (file)
@@ -378,4 +378,12 @@ class DatabaseSqliteTest extends MediaWikiTestCase {
                ksort( $indexes );
                return $indexes;
        }
+
+       function testCaseInsensitiveLike() {
+               // TODO: Test this for all databases
+               $db = new DatabaseSqliteStandalone( ':memory:' );\r
+               $res = $db->query( 'SELECT "a" LIKE "A" AS a' );\r
+               $row = $res->fetchRow();\r
+               $this->assertFalse( (bool)$row['a'] );\r
+       }
 }
diff --git a/tests/phpunit/includes/jobqueue/JobQueueTest.php b/tests/phpunit/includes/jobqueue/JobQueueTest.php
new file mode 100644 (file)
index 0000000..46ba974
--- /dev/null
@@ -0,0 +1,270 @@
+<?php
+
+/**
+ * @group JobQueue
+ * @group medium
+ * @group Database
+ */
+class JobQueueTest extends MediaWikiTestCase {
+       protected $old = array();
+
+       function  __construct( $name = null, array $data = array(), $dataName = '' ) {
+               parent::__construct( $name, $data, $dataName );
+
+               $this->tablesUsed[] = 'job';
+       }
+
+       protected function setUp() {
+               global $wgMemc;
+               parent::setUp();
+               $this->old['wgMemc'] = $wgMemc;
+               $wgMemc = new HashBagOStuff();
+               $this->queueRand = JobQueue::factory( array( 'class' => 'JobQueueDB',
+                       'wiki' => wfWikiID(), 'type' => 'null', 'order' => 'random' ) );
+               $this->queueRandTTL = JobQueue::factory( array( 'class' => 'JobQueueDB',
+                       'wiki' => wfWikiID(), 'type' => 'null', 'order' => 'random', 'claimTTL' => 10 ) );
+               $this->queueFifo = JobQueue::factory( array( 'class' => 'JobQueueDB',
+                       'wiki' => wfWikiID(), 'type' => 'null', 'order' => 'fifo' ) );
+               $this->queueFifoTTL = JobQueue::factory( array( 'class' => 'JobQueueDB',
+                       'wiki' => wfWikiID(), 'type' => 'null', 'order' => 'fifo', 'claimTTL' => 10 ) );
+       }
+
+       protected function tearDown() {
+               global $wgMemc;
+               parent::tearDown();
+               foreach ( array( 'queueRand', 'queueRandTTL', 'queueFifo', 'queueFifoTTL' ) as $q ) {
+                       do {
+                               $job = $this->$q->pop();
+                               if ( $job ) $this->$q->ack( $job );
+                       } while ( $job );
+               }
+               $this->queueRand = null;
+               $this->queueRandTTL = null;
+               $this->queueFifo = null;
+               $this->queueFifoTTL = null;
+               $wgMemc = $this->old['wgMemc'];
+       }
+
+       /**
+        * @dataProvider provider_queueLists
+        */
+       function testProperties( $queue, $order, $recycles, $desc ) {
+               $queue = $this->$queue;
+
+               $this->assertEquals( wfWikiID(), $queue->getWiki(), "Proper wiki ID ($desc)" );
+               $this->assertEquals( 'null', $queue->getType(), "Proper job type ($desc)" );
+       }
+
+       /**
+        * @dataProvider provider_queueLists
+        */
+       function testBasicOperations( $queue, $order, $recycles, $desc ) {
+               $queue = $this->$queue;
+               $this->assertTrue( $queue->isEmpty(), "Queue is empty ($desc)" );
+
+               $queue->flushCaches();
+               $this->assertEquals( 0, $queue->getSize(), "Queue is empty ($desc)" );
+               $this->assertEquals( 0, $queue->getAcquiredCount(), "Queue is empty ($desc)" );
+
+               $this->assertTrue( $queue->push( $this->newJob() ), "Push worked ($desc)" );
+               $this->assertTrue( $queue->batchPush( array( $this->newJob() ) ), "Push worked ($desc)" );
+
+               $this->assertFalse( $queue->isEmpty(), "Queue is not empty ($desc)" );
+
+               $queue->flushCaches();
+               $this->assertEquals( 2, $queue->getSize(), "Queue size is correct ($desc)" );
+               $this->assertEquals( 0, $queue->getAcquiredCount(), "No jobs active ($desc)" );
+
+               $job1 = $queue->pop();
+               $this->assertFalse( $queue->isEmpty(), "Queue is not empty ($desc)" );
+
+               $queue->flushCaches();
+               $this->assertEquals( 1, $queue->getSize(), "Queue size is correct ($desc)" );
+
+               $queue->flushCaches();
+               if ( $recycles ) {
+                       $this->assertEquals( 1, $queue->getAcquiredCount(), "Active job count ($desc)" );
+               } else {
+                       $this->assertEquals( 0, $queue->getAcquiredCount(), "Active job count ($desc)" );
+               }
+
+               $job2 = $queue->pop();
+               $this->assertTrue( $queue->isEmpty(), "Queue is empty ($desc)" );
+               $this->assertEquals( 0, $queue->getSize(), "Queue is empty ($desc)" );
+
+               $queue->flushCaches();
+               if ( $recycles ) {
+                       $this->assertEquals( 2, $queue->getAcquiredCount(), "Active job count ($desc)" );
+               } else {
+                       $this->assertEquals( 0, $queue->getAcquiredCount(), "Active job count ($desc)" );
+               }
+
+               $queue->ack( $job1 );
+
+               $queue->flushCaches();
+               if ( $recycles ) {
+                       $this->assertEquals( 1, $queue->getAcquiredCount(), "Active job count ($desc)" );
+               } else {
+                       $this->assertEquals( 0, $queue->getAcquiredCount(), "Active job count ($desc)" );
+               }
+
+               $queue->ack( $job2 );
+
+               $queue->flushCaches();
+               $this->assertEquals( 0, $queue->getAcquiredCount(), "Active job count ($desc)" );
+       }
+
+       /**
+        * @dataProvider provider_queueLists
+        */
+       function testBasicDeduplication( $queue, $order, $recycles, $desc ) {
+               $queue = $this->$queue;
+
+               $this->assertTrue( $queue->isEmpty(), "Queue is empty ($desc)" );
+
+               $queue->flushCaches();
+               $this->assertEquals( 0, $queue->getSize(), "Queue is empty ($desc)" );
+               $this->assertEquals( 0, $queue->getAcquiredCount(), "Queue is empty ($desc)" );
+
+               $this->assertTrue( $queue->batchPush(
+                       array( $this->newDedupedJob(), $this->newDedupedJob(), $this->newDedupedJob() ) ),
+                       "Push worked ($desc)" );
+
+               $this->assertFalse( $queue->isEmpty(), "Queue is not empty ($desc)" );
+
+               $queue->flushCaches();
+               $this->assertEquals( 1, $queue->getSize(), "Queue size is correct ($desc)" );
+               $this->assertEquals( 0, $queue->getAcquiredCount(), "No jobs active ($desc)" );
+
+               $this->assertTrue( $queue->batchPush(
+                       array( $this->newDedupedJob(), $this->newDedupedJob(), $this->newDedupedJob() ) ),
+                       "Push worked ($desc)" );
+
+               $this->assertFalse( $queue->isEmpty(), "Queue is not empty ($desc)" );
+
+               $queue->flushCaches();
+               $this->assertEquals( 1, $queue->getSize(), "Queue size is correct ($desc)" );
+               $this->assertEquals( 0, $queue->getAcquiredCount(), "No jobs active ($desc)" );
+
+               $job1 = $queue->pop();
+               $this->assertTrue( $queue->isEmpty(), "Queue is empty ($desc)" );
+
+               $queue->flushCaches();
+               $this->assertEquals( 0, $queue->getSize(), "Queue is empty ($desc)" );
+               if ( $recycles ) {
+                       $this->assertEquals( 1, $queue->getAcquiredCount(), "Active job count ($desc)" );
+               } else {
+                       $this->assertEquals( 0, $queue->getAcquiredCount(), "Active job count ($desc)" );
+               }
+
+               $queue->ack( $job1 );
+
+               $queue->flushCaches();
+               $this->assertEquals( 0, $queue->getAcquiredCount(), "Active job count ($desc)" );
+       }
+
+       /**
+        * @dataProvider provider_queueLists
+        */
+       function testRootDeduplication( $queue, $order, $recycles, $desc ) {
+               $queue = $this->$queue;
+
+               $this->assertTrue( $queue->isEmpty(), "Queue is empty ($desc)" );
+
+               $queue->flushCaches();
+               $this->assertEquals( 0, $queue->getSize(), "Queue is empty ($desc)" );
+               $this->assertEquals( 0, $queue->getAcquiredCount(), "Queue is empty ($desc)" );
+
+               $id = wfRandomString( 32 );
+               $root1 = Job::newRootJobParams( "nulljobspam:$id" ); // task ID/timestamp
+               for ( $i=0; $i<5; ++$i ) {
+                       $this->assertTrue( $queue->push( $this->newJob( 0, $root1 ) ), "Push worked ($desc)" );
+               }
+               $queue->deduplicateRootJob( $this->newJob( 0, $root1 ) );
+               sleep( 1 ); // roo job timestamp will increase
+               $root2 = Job::newRootJobParams( "nulljobspam:$id" ); // task ID/timestamp
+               $this->assertNotEquals( $root1['rootJobTimestamp'], $root2['rootJobTimestamp'],
+                       "Root job signatures have different timestamps." );
+               for ( $i=0; $i<5; ++$i ) {
+                       $this->assertTrue( $queue->push( $this->newJob( 0, $root2 ) ), "Push worked ($desc)" );
+               }
+               $queue->deduplicateRootJob( $this->newJob( 0, $root2 ) );
+
+               $this->assertFalse( $queue->isEmpty(), "Queue is not empty ($desc)" );
+
+               $queue->flushCaches();
+               $this->assertEquals( 10, $queue->getSize(), "Queue size is correct ($desc)" );
+               $this->assertEquals( 0, $queue->getAcquiredCount(), "No jobs active ($desc)" );
+
+               $dupcount = 0;
+               $jobs = array();
+               do {
+                       $job = $queue->pop();
+                       if ( $job ) {
+                               $jobs[] = $job;
+                               $queue->ack( $job );
+                       }
+                       if ( $job instanceof DuplicateJob ) ++$dupcount;
+               } while ( $job );
+
+               $this->assertEquals( 10, count( $jobs ), "Correct number of jobs popped ($desc)" );
+               $this->assertEquals( 5, $dupcount, "Correct number of duplicate jobs popped ($desc)" );
+       }
+
+       /**
+        * @dataProvider provider_fifoQueueLists
+        */
+       function testJobOrder( $queue, $recycles, $desc ) {
+               $queue = $this->$queue;
+
+               $this->assertTrue( $queue->isEmpty(), "Queue is empty ($desc)" );
+
+               $queue->flushCaches();
+               $this->assertEquals( 0, $queue->getSize(), "Queue is empty ($desc)" );
+               $this->assertEquals( 0, $queue->getAcquiredCount(), "Queue is empty ($desc)" );
+
+               for ( $i=0; $i<10; ++$i ) {
+                       $this->assertTrue( $queue->push( $this->newJob( $i ) ), "Push worked ($desc)" );
+               }
+
+               for ( $i=0; $i<10; ++$i ) {
+                       $job = $queue->pop();
+                       $this->assertTrue( $job instanceof Job, "Jobs popped from queue ($desc)" );
+                       $params = $job->getParams();
+                       $this->assertEquals( $i, $params['i'], "Job popped from queue is FIFO ($desc)" );
+                       $queue->ack( $job );
+               }
+
+               $this->assertFalse( $queue->isEmpty(), "Queue is not empty ($desc)" );
+
+               $queue->flushCaches();
+               $this->assertEquals( 0, $queue->getSize(), "Queue is empty ($desc)" );
+               $this->assertEquals( 0, $queue->getAcquiredCount(), "No jobs active ($desc)" );
+       }
+
+       function provider_queueLists() {
+               return array(
+                       array( 'queueRand', 'rand', false, 'Random queue without ack()' ),
+                       array( 'queueRandTTL', 'rand', true, 'Random queue with ack()' ),
+                       array( 'queueFifo', 'fifo', false, 'Ordered queue without ack()' ),
+                       array( 'queueFifoTTL', 'fifo', true, 'Ordered queue with ack()' )
+               );
+       }
+
+       function provider_fifoQueueLists() {
+               return array(
+                       array( 'queueFifo', false, 'Ordered queue without ack()' ),
+                       array( 'queueFifoTTL', true, 'Ordered queue with ack()' )
+               );
+       }
+
+       function newJob( $i = 0, $rootJob = array() ) {
+               return new NullJob( Title::newMainPage(),
+                       array( 'lives' => 0, 'usleep' => 0, 'removeDuplicates' => 0, 'i' => $i ) + $rootJob );
+       }
+
+       function newDedupedJob( $i = 0, $rootJob = array() ) {
+               return new NullJob( Title::newMainPage(),
+                       array( 'lives' => 0, 'usleep' => 0, 'removeDuplicates' => 1, 'i' => $i ) + $rootJob );
+       }
+}
index c3a251f..4b1f519 100644 (file)
@@ -154,6 +154,7 @@ class PreprocessorTest extends MediaWikiTestCase {
                        array( "Factorial" ), # http://en.wikipedia.org/w/index.php?title=Template:Factorial&oldid=98548758 GFDL + CC-BY-SA by Polonium
                        array( "All_system_messages" ), # http://tl.wiktionary.org/w/index.php?title=Suleras:All_system_messages&oldid=2765 GPL text generated by MediaWiki
                        array( "Fundraising" ), # http://tl.wiktionary.org/w/index.php?title=MediaWiki:Sitenotice&oldid=5716 GFDL + CC-BY-SA, copied there by Sky Harbor.
+                       array( "NestedTemplates" ), # bug 27936
                );
        }
 
index f545a13..0792f75 100644 (file)
@@ -16,7 +16,7 @@ class LanguageRuTest extends LanguageClassesTestCase {
        }
 
        function providePluralFourForms() {
-               return array (
+               return array(
                        array( 'one', 1 ),
                        array( 'many', 11 ),
                        array( 'one', 91 ),
@@ -30,17 +30,49 @@ class LanguageRuTest extends LanguageClassesTestCase {
                        array( 'many', 120 ),
                );
        }
+
        /** @dataProvider providePluralTwoForms */
        function testPluralTwoForms( $result, $value ) {
-               $forms =  array( 'one', 'several' );
+               $forms = array( 'one', 'several' );
                $this->assertEquals( $result, $this->getLang()->convertPlural( $value, $forms ) );
        }
+
        function providePluralTwoForms() {
-               return array (
+               return array(
                        array( 'one', 1 ),
                        array( 'several', 11 ),
                        array( 'several', 91 ),
                        array( 'several', 121 ),
                );
        }
+
+       /** @dataProvider providerGrammar */
+       function testGrammar( $result, $word, $case ) {
+               $this->assertEquals( $result, $this->getLang()->convertGrammar( $word, $case ) );
+       }
+
+       function providerGrammar() {
+               return array(
+                       array(
+                               'Википедии',
+                               'Википедия',
+                               'genitive',
+                       ),
+                       array(
+                               'Викитеки',
+                               'Викитека',
+                               'genitive',
+                       ),
+                       array(
+                               'Викитеке',
+                               'Викитека',
+                               'prepositional',
+                       ),
+                       array(
+                               'Викиданных',
+                               'Викиданные',
+                               'prepositional',
+                       ),
+               );
+       }
 }
index 29c6657..44aaefd 100644 (file)
                                        rtl: true
                                }
                        },
+                       // Iceweasel 10.0.6
+                       'Mozilla/5.0 (X11; Linux i686; rv:10.0.6) Gecko/20100101 Iceweasel/10.0.6': {
+                               title: 'Iceweasel 10.0.6',
+                               platform: 'Linux',
+                               profile: {
+                                       name: 'iceweasel',
+                                       layout: 'gecko',
+                                       layoutVersion: 20100101,
+                                       platform: 'linux',
+                                       version: '10.0.6',
+                                       versionBase: '10',
+                                       versionNumber: 10
+                               },
+                               wikiEditor: {
+                                       ltr: true,
+                                       rtl: true
+                               }
+                       },
                        // Firefox 5
                        // Safari 3
                        // Safari 4
index 0000f0c..b8d816e 100644 (file)
                }
        );
 
+QUnit.test( 'Sorting images using alt text', function ( assert ) {
+       var $table = $(
+               '<table class="sortable">' +
+               '<tr><th>THEAD</th></tr>' +
+               '<tr><td><img alt="2"/></td></tr>' +
+               '<tr><td>1</td></tr>' +
+               '</table>'
+       );
+       $table.tablesorter().find( '.headerSort:eq(0)' ).click();
+
+       assert.equal(
+               $table.find( 'td' ).first().text(),
+               '1',
+               'Applied correct sorting order'
+       );
+} );
+
+QUnit.test( 'Sorting images using alt text (complex)', function ( assert ) {
+       var $table = $(
+               '<table class="sortable">' +
+               '<tr><th>THEAD</th></tr>' +
+               '<tr><td><img alt="D" />A</td></tr>' +
+               '<tr><td>CC</td></tr>' +
+               '<tr><td><a><img alt="A" /></a>F</tr>' +
+               '<tr><td><img alt="A" /><strong>E</strong></tr>' +
+               '<tr><td><strong><img alt="A" />D</strong></tr>' +
+               '<tr><td><img alt="A" />C</tr>' +
+               '</table>'
+       );
+       $table.tablesorter().find( '.headerSort:eq(0)' ).click();
+
+       assert.equal(
+               $table.find( 'td' ).text(),
+               'CDEFCCA',
+               'Applied correct sorting order'
+       );
+} );
+
+QUnit.test( 'Sorting images using alt text (with format autodetection)', function ( assert ) {
+       var $table = $(
+               '<table class="sortable">' +
+               '<tr><th>THEAD</th></tr>' +
+               '<tr><td><img alt="1" />7</td></tr>' +
+               '<tr><td>1<img alt="6" /></td></tr>' +
+               '<tr><td>5</td></tr>' +
+               '<tr><td>4</td></tr>' +
+               '</table>'
+       );
+       $table.tablesorter().find( '.headerSort:eq(0)' ).click();
+
+       assert.equal(
+               $table.find( 'td' ).text(),
+               '4517',
+               'Applied correct sorting order'
+       );
+} );
+
 }( jQuery, mediaWiki ) );
index d7c73e5..6e9379e 100644 (file)
@@ -1,6 +1,6 @@
 ( function ( mw, $ ) {
 
-var mwLanguageCache = {}, oldGetOuterHtml, formatnumTests;
+var mwLanguageCache = {}, oldGetOuterHtml, formatnumTests, specialCharactersPageName;
 
 QUnit.module( 'mediawiki.jqueryMsg', QUnit.newMwEnvironment( {
        setup: function () {
@@ -15,6 +15,17 @@ QUnit.module( 'mediawiki.jqueryMsg', QUnit.newMwEnvironment( {
                        $div = undefined;
                        return html;
                };
+
+               // Messages that are reused in multiple tests
+               // They are also all part of regression tests based on actual extensions.  The actual messages have the same key,
+               // but without jquerymsg-test-.
+               mw.messages.set( {
+                       'jquerymsg-test-pagetriage-del-talk-page-notify-summary': 'Notifying author of deletion nomination for [[$1]]',
+                       'jquerymsg-test-categorytree-collapse-bullet': '[<b>−</b>]',
+                       'jquerymsg-test-wikieditor-toolbar-help-content-signature-result': '<a href=\'#\' title=\'{{#special:mypage}}\'>Username</a> (<a href=\'#\' title=\'{{#special:mytalk}}\'>talk</a>)'
+               } );
+
+               specialCharactersPageName = '"Who" wants to be a millionaire & live on \'Exotic Island\'?';
        },
        teardown: function () {
                mw.language = this.orgMwLangauge;
@@ -94,9 +105,9 @@ QUnit.test( 'Replace', 9, function ( assert ) {
                'HTMLElement[] arrays are preserved as raw html'
        );
 
-       mw.messages.set( 'wikilink-replace', 'Foo [$1 bar]' );
+       mw.messages.set( 'external-link-replace', 'Foo [$1 bar]' );
        assert.equal(
-               parser( 'wikilink-replace', 'http://example.org/?x=y&z' ),
+               parser( 'external-link-replace', 'http://example.org/?x=y&z' ),
                'Foo <a href="http://example.org/?x=y&amp;z">bar</a>',
                'Href is not double-escaped in wikilink function'
        );
@@ -217,20 +228,19 @@ QUnit.test( 'Match PHP parser', mw.libs.phpParserData.tests.length, function ( a
        } );
 });
 
-QUnit.test( 'Wikilink', 6, function ( assert ) {
+QUnit.test( 'Links', 6, function ( assert ) {
        var parser = mw.jqueryMsg.getMessageFunction(),
                expectedListUsers,
                expectedDisambiguationsText,
                expectedMultipleBars,
-               expectedSpecialCharacters,
-               specialCharactersPageName;
+               expectedSpecialCharacters;
 
        /*
         The below three are all identical to or based on real messages.  For disambiguations-text,
         the bold was removed because it is not yet implemented.
        */
 
-       mw.messages.set( 'statistics-users', '注册[[Special:ListUsers|用户]]' );
+       mw.messages.set( 'jquerymsg-test-statistics-users', '注册[[Special:ListUsers|用户]]' );
 
        expectedListUsers = '注册' + $( '<a>' ).attr( {
                title: 'Special:ListUsers',
@@ -238,7 +248,7 @@ QUnit.test( 'Wikilink', 6, function ( assert ) {
        } ).text( '用户' ).getOuterHtml();
 
        assert.equal(
-               parser( 'statistics-users' ),
+               parser( 'jquerymsg-test-statistics-users' ),
                expectedListUsers,
                'Piped wikilink'
        );
@@ -255,9 +265,9 @@ QUnit.test( 'Wikilink', 6, function ( assert ) {
                'Wikilink without pipe'
        );
 
-       mw.messages.set( 'version-entrypoints-index-php', '[https://www.mediawiki.org/wiki/Manual:index.php index.php]' );
+       mw.messages.set( 'jquerymsg-test-version-entrypoints-index-php', '[https://www.mediawiki.org/wiki/Manual:index.php index.php]' );
        assert.equal(
-               parser( 'version-entrypoints-index-php' ),
+               parser( 'jquerymsg-test-version-entrypoints-index-php' ),
                '<a href="https://www.mediawiki.org/wiki/Manual:index.php">index.php</a>',
                'External link'
        );
@@ -281,7 +291,6 @@ QUnit.test( 'Wikilink', 6, function ( assert ) {
                'Bar in anchor'
        );
 
-       specialCharactersPageName = '"Who" wants to be a millionaire & live on \'Exotic Island\'?';
        expectedSpecialCharacters = $( '<a>' ).attr( {
                title: specialCharactersPageName,
                href: mw.util.wikiGetlink( specialCharactersPageName )
@@ -295,6 +304,38 @@ QUnit.test( 'Wikilink', 6, function ( assert ) {
        );
 });
 
+// Output for format plain when calling main (mediawiki.js) API.
+// We're testing here to ensure our monkey-patching of mw.Message.prototype.parser doesn't
+// cause breakage.
+
+// Some of the tests use mw.msg, while others have mw.message(...).plain().  These two
+// syntaxes should have identical behavior.
+QUnit.test( 'Plain', 4, function ( assert ) {
+       assert.equal(
+               mw.message( 'jquerymsg-test-pagetriage-del-talk-page-notify-summary' ).plain(),
+               'Notifying author of deletion nomination for [[$1]]',
+               'Square brackets in plain with no parameters'
+       );
+
+       assert.equal(
+               mw.msg( 'jquerymsg-test-pagetriage-del-talk-page-notify-summary', specialCharactersPageName ),
+               'Notifying author of deletion nomination for [[' + specialCharactersPageName + ']]',
+               'Square brackets in plain with one parameter'
+       );
+
+       assert.equal(
+               mw.msg( 'jquerymsg-test-categorytree-collapse-bullet' ),
+               mw.messages.get( 'jquerymsg-test-categorytree-collapse-bullet' ),
+               'Message with single square brackets is not changed'
+       );
+
+       assert.equal(
+               mw.message( 'jquerymsg-test-wikieditor-toolbar-help-content-signature-result' ).plain(),
+               mw.messages.get( 'jquerymsg-test-wikieditor-toolbar-help-content-signature-result' ),
+               'HTML message with curly braces is not changed'
+       );
+} );
+
 QUnit.test( 'Int', 4, function ( assert ) {
        var parser = mw.jqueryMsg.getMessageFunction(),
            newarticletextSource = 'You have followed a link to a page that does not exist yet. To create the page, start typing in the box below (see the [[{{Int:Helppage}}|help page]] for more info). If you are here by mistake, click your browser\'s back button.',
@@ -342,14 +383,12 @@ QUnit.test( 'Int', 4, function ( assert ) {
        );
 });
 
-// Tests that getMessageFunction is used for messages with curly braces or square brackets,
-// but not otherwise.
-QUnit.test( 'mw.msg()', 8, function ( assert ) {
-       // Should be
-       var map, oldGMF, outerCalled, innerCalled;
+// Tests that getMessageFunction is used for non-plain messages with curly braces or
+// square brackets, but not otherwise.
+QUnit.test( 'mw.msg()', 22, function ( assert ) {
+       var oldGMF, outerCalled, innerCalled;
 
-       map = new mw.Map();
-       map.set( {
+       mw.messages.set( {
                'curly-brace': '{{int:message}}',
                'single-square-bracket': '[https://www.mediawiki.org/ MediaWiki]',
                'double-square-bracket': '[[Some page]]',
@@ -365,18 +404,31 @@ QUnit.test( 'mw.msg()', 8, function ( assert ) {
                };
        };
 
-       function verifyGetMessageFunction( key, shouldCall ) {
+       function verifyGetMessageFunction( key, format, shouldCall ) {
+               var message;
                outerCalled = false;
                innerCalled = false;
-               ( new mw.Message( map, key ) ).parser();
+               message = mw.message( key );
+               message[format]();
                assert.strictEqual( outerCalled, shouldCall, 'Outer function called for ' + key );
                assert.strictEqual( innerCalled, shouldCall, 'Inner function called for ' + key );
        }
 
-       verifyGetMessageFunction( 'curly-brace', true );
-       verifyGetMessageFunction( 'single-square-bracket', true );
-       verifyGetMessageFunction( 'double-square-bracket', true );
-       verifyGetMessageFunction( 'regular', false );
+       verifyGetMessageFunction( 'curly-brace', 'parse', true );
+       verifyGetMessageFunction( 'curly-brace', 'plain', false );
+
+       verifyGetMessageFunction( 'single-square-bracket', 'parse', true );
+       verifyGetMessageFunction( 'single-square-bracket', 'plain', false );
+
+       verifyGetMessageFunction( 'double-square-bracket', 'parse', true );
+       verifyGetMessageFunction( 'double-square-bracket', 'plain', false );
+
+       verifyGetMessageFunction( 'regular', 'parse', false );
+       verifyGetMessageFunction( 'regular', 'plain', false );
+
+       verifyGetMessageFunction( 'jquerymsg-test-pagetriage-del-talk-page-notify-summary', 'plain', false );
+       verifyGetMessageFunction( 'jquerymsg-test-categorytree-collapse-bullet', 'plain', false );
+       verifyGetMessageFunction( 'jquerymsg-test-wikieditor-toolbar-help-content-signature-result', 'plain', false );
 
        mw.jqueryMsg.getMessageFunction = oldGMF;
 } );