Merge "(bug 44385) move jquery.collapsibleTabs module to Vector extension"
authorjenkins-bot <jenkins-bot@gerrit.wikimedia.org>
Fri, 15 Feb 2013 18:55:33 +0000 (18:55 +0000)
committerGerrit Code Review <gerrit@wikimedia.org>
Fri, 15 Feb 2013 18:55:33 +0000 (18:55 +0000)
527 files changed:
INSTALL
RELEASE-NOTES-1.21
StartProfiler.sample
api.php
bin/ulimit5.sh [deleted file]
composer.json
docs/hooks.txt
img_auth.php
includes/Article.php
includes/AutoLoader.php
includes/Collation.php
includes/DefaultSettings.php
includes/Defines.php
includes/EditPage.php
includes/Export.php
includes/FeedUtils.php
includes/GlobalFunctions.php
includes/Html.php
includes/HttpFunctions.php
includes/IP.php
includes/ImageGallery.php
includes/ImagePage.php
includes/Import.php
includes/MimeMagic.php
includes/OutputPage.php
includes/Preferences.php
includes/RecentChange.php
includes/Sanitizer.php
includes/Setup.php
includes/SiteStats.php
includes/SqlDataUpdate.php
includes/Title.php
includes/UIDGenerator.php [new file with mode: 0644]
includes/User.php
includes/WebRequest.php
includes/WebStart.php
includes/WikiPage.php
includes/Xml.php
includes/actions/InfoAction.php
includes/actions/RawAction.php
includes/api/ApiBase.php
includes/api/ApiHelp.php
includes/api/ApiMain.php
includes/api/ApiModuleManager.php [new file with mode: 0644]
includes/api/ApiPageSet.php
includes/api/ApiParamInfo.php
includes/api/ApiParse.php
includes/api/ApiPurge.php
includes/api/ApiQuery.php
includes/api/ApiQueryAllImages.php
includes/api/ApiQueryAllMessages.php
includes/api/ApiQueryBase.php
includes/api/ApiQueryDeletedrevs.php
includes/api/ApiQueryImageInfo.php
includes/api/ApiQueryInfo.php
includes/api/ApiQuerySiteinfo.php
includes/api/ApiQueryStashImageInfo.php
includes/api/ApiSetNotificationTimestamp.php
includes/api/ApiUpload.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/context/RequestContext.php
includes/db/Database.php
includes/db/DatabaseMssql.php
includes/db/DatabaseOracle.php
includes/db/DatabasePostgres.php
includes/externalstore/ExternalStoreMedium.php
includes/externalstore/ExternalStoreMwstore.php [new file with mode: 0644]
includes/filebackend/FileBackend.php
includes/filebackend/FileBackendMultiWrite.php
includes/filebackend/SwiftFileBackend.php
includes/filebackend/lockmanager/DBLockManager.php
includes/filebackend/lockmanager/LockManager.php
includes/filerepo/ForeignAPIRepo.php
includes/filerepo/file/ArchivedFile.php
includes/filerepo/file/LocalFile.php
includes/installer/InstallDocFormatter.php
includes/installer/Installer.i18n.php
includes/installer/PostgresUpdater.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/DuplicateJob.php
includes/limit.sh [new file with mode: 0644]
includes/logging/LogEventsList.php
includes/logging/LogFormatter.php
includes/media/DjVuImage.php
includes/media/Exif.php
includes/media/ExifBitmap.php
includes/media/FormatMetadata.php
includes/media/IPTC.php
includes/media/MediaHandler.php
includes/media/XMP.php
includes/media/XMPValidate.php
includes/normal/Utf8CaseGenerate.php
includes/normal/UtfNormal.php
includes/objectcache/ObjectCache.php
includes/objectcache/SqlBagOStuff.php
includes/parser/LinkHolderArray.php
includes/parser/Parser.php
includes/parser/ParserOptions.php
includes/parser/Parser_LinkHooks.php
includes/parser/Preprocessor_DOM.php
includes/parser/Preprocessor_Hash.php
includes/parser/Preprocessor_HipHop.hphp [deleted file]
includes/revisiondelete/RevisionDelete.php
includes/site/MediaWikiSite.php
includes/site/Site.php
includes/site/SiteList.php
includes/site/SiteSQLStore.php
includes/specials/SpecialChangePassword.php
includes/specials/SpecialContributions.php
includes/specials/SpecialEditWatchlist.php
includes/specials/SpecialExport.php
includes/specials/SpecialListusers.php
includes/specials/SpecialPopularpages.php
includes/specials/SpecialPrefixindex.php
includes/specials/SpecialSearch.php
includes/specials/SpecialUndelete.php
includes/specials/SpecialUserlogin.php
includes/upload/UploadBase.php
includes/upload/UploadFromChunks.php
languages/Language.php
languages/Names.php
languages/classes/LanguageHy.php
languages/classes/LanguageKu.php
languages/classes/LanguageRu.php
languages/classes/LanguageSr.php
languages/data/plurals.xml
languages/messages/MessagesAce.php
languages/messages/MessagesAr.php
languages/messages/MessagesArc.php
languages/messages/MessagesAst.php
languages/messages/MessagesBe.php
languages/messages/MessagesBe_tarask.php
languages/messages/MessagesBho.php
languages/messages/MessagesBn.php
languages/messages/MessagesCa.php
languages/messages/MessagesCkb.php
languages/messages/MessagesCs.php
languages/messages/MessagesCy.php
languages/messages/MessagesDa.php
languages/messages/MessagesDe.php
languages/messages/MessagesDiq.php
languages/messages/MessagesDsb.php
languages/messages/MessagesDv.php
languages/messages/MessagesEl.php
languages/messages/MessagesEn.php
languages/messages/MessagesEs.php
languages/messages/MessagesFa.php
languages/messages/MessagesFi.php
languages/messages/MessagesFr.php
languages/messages/MessagesFrp.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/MessagesIs.php
languages/messages/MessagesIt.php
languages/messages/MessagesJa.php
languages/messages/MessagesKa.php
languages/messages/MessagesKn.php
languages/messages/MessagesKo.php
languages/messages/MessagesKrc.php
languages/messages/MessagesKu_latn.php
languages/messages/MessagesLb.php
languages/messages/MessagesLez.php
languages/messages/MessagesMai.php
languages/messages/MessagesMg.php
languages/messages/MessagesMin.php
languages/messages/MessagesMk.php
languages/messages/MessagesMl.php
languages/messages/MessagesMs.php
languages/messages/MessagesMt.php
languages/messages/MessagesMzn.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/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/MessagesSe.php
languages/messages/MessagesSl.php
languages/messages/MessagesSv.php
languages/messages/MessagesSw.php
languages/messages/MessagesTh.php
languages/messages/MessagesTk.php
languages/messages/MessagesTr.php
languages/messages/MessagesTyv.php
languages/messages/MessagesUg_arab.php
languages/messages/MessagesUk.php
languages/messages/MessagesUz.php
languages/messages/MessagesVi.php
languages/messages/MessagesVo.php
languages/messages/MessagesYi.php
languages/messages/MessagesZh_hans.php
languages/messages/MessagesZh_hant.php
maintenance/7zip.inc
maintenance/Maintenance.php
maintenance/backupPrefetch.inc
maintenance/benchmarks/bench_strtr_str_replace.php
maintenance/changePassword.php
maintenance/lag.php
maintenance/language/generateCollationData.php
maintenance/language/languages.inc
maintenance/language/messages.inc
maintenance/mwdocgen.php
maintenance/nextJobDB.php
maintenance/purgeList.php
maintenance/refreshImageMetadata.php
maintenance/runJobs.php
maintenance/showStats.php
maintenance/sql.php
maintenance/userDupes.inc
maintenance/waitForSlave.php
opensearch_desc.php
profileinfo.php
resources/Resources.php
resources/jquery/jquery.suggestions.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
skins/Vector.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/RunSeleniumTests.php
tests/parser/parserTest.inc
tests/parser/parserTests.txt
tests/parser/parserTestsParserHook.php
tests/parser/preprocess/NestedTemplates.expected [new file with mode: 0644]
tests/parser/preprocess/NestedTemplates.txt [new file with mode: 0644]
tests/parserTests.php
tests/phpunit/MediaWikiLangTestCase.php
tests/phpunit/MediaWikiPHPUnitCommand.php
tests/phpunit/MediaWikiTestCase.php
tests/phpunit/StructureTest.php
tests/phpunit/bootstrap.php
tests/phpunit/docs/ExportDemoTest.php
tests/phpunit/includes/ArticleTest.php
tests/phpunit/includes/BlockTest.php
tests/phpunit/includes/EditPageTest.php
tests/phpunit/includes/ExtraParserTest.php
tests/phpunit/includes/FormOptionsInitializationTest.php
tests/phpunit/includes/FormOptionsTest.php
tests/phpunit/includes/GlobalFunctions/GlobalTest.php
tests/phpunit/includes/GlobalFunctions/wfAssembleUrlTest.php
tests/phpunit/includes/GlobalFunctions/wfBCP47Test.php
tests/phpunit/includes/GlobalFunctions/wfBaseConvertTest.php
tests/phpunit/includes/GlobalFunctions/wfBaseNameTest.php
tests/phpunit/includes/GlobalFunctions/wfExpandUrlTest.php
tests/phpunit/includes/GlobalFunctions/wfGetCallerTest.php
tests/phpunit/includes/GlobalFunctions/wfShorthandToIntegerTest.php
tests/phpunit/includes/GlobalFunctions/wfTimestampTest.php
tests/phpunit/includes/GlobalFunctions/wfUrlencodeTest.php
tests/phpunit/includes/HtmlTest.php
tests/phpunit/includes/HttpTest.php
tests/phpunit/includes/IPTest.php
tests/phpunit/includes/JsonTest.php
tests/phpunit/includes/LanguageConverterTest.php
tests/phpunit/includes/LicensesTest.php
tests/phpunit/includes/LinkerTest.php
tests/phpunit/includes/LocalFileTest.php
tests/phpunit/includes/MWFunctionTest.php
tests/phpunit/includes/MWNamespaceTest.php
tests/phpunit/includes/OutputPageTest.php
tests/phpunit/includes/ParserOptionsTest.php [deleted file]
tests/phpunit/includes/PathRouterTest.php
tests/phpunit/includes/PreferencesTest.php
tests/phpunit/includes/Providers.php
tests/phpunit/includes/RecentChangeTest.php
tests/phpunit/includes/ResourceLoaderTest.php
tests/phpunit/includes/RevisionStorageTest.php
tests/phpunit/includes/RevisionStorageTest_ContentHandlerUseDB.php
tests/phpunit/includes/RevisionTest.php
tests/phpunit/includes/SampleTest.php
tests/phpunit/includes/SanitizerTest.php
tests/phpunit/includes/SanitizerValidateEmailTest.php
tests/phpunit/includes/SeleniumConfigurationTest.php
tests/phpunit/includes/StringUtilsTest.php
tests/phpunit/includes/TimeAdjustTest.php
tests/phpunit/includes/TimestampTest.php
tests/phpunit/includes/TitlePermissionTest.php
tests/phpunit/includes/TitleTest.php
tests/phpunit/includes/UIDGeneratorTest.php [new file with mode: 0644]
tests/phpunit/includes/UserTest.php
tests/phpunit/includes/WebRequestTest.php
tests/phpunit/includes/WikiPageTest.php
tests/phpunit/includes/XmlSelectTest.php
tests/phpunit/includes/XmlTest.php
tests/phpunit/includes/ZipDirectoryReaderTest.php
tests/phpunit/includes/api/ApiAccountCreationTest.php
tests/phpunit/includes/api/ApiBlockTest.php
tests/phpunit/includes/api/ApiEditPageTest.php
tests/phpunit/includes/api/ApiGeneratorTest.php
tests/phpunit/includes/api/ApiParseTest.php
tests/phpunit/includes/api/ApiPurgeTest.php
tests/phpunit/includes/api/ApiQueryRevisionsTest.php [deleted file]
tests/phpunit/includes/api/ApiQueryTest.php [deleted file]
tests/phpunit/includes/api/ApiTest.php
tests/phpunit/includes/api/ApiTestCase.php
tests/phpunit/includes/api/ApiTestCaseUpload.php
tests/phpunit/includes/api/ApiUploadTest.php
tests/phpunit/includes/api/ApiWatchTest.php
tests/phpunit/includes/api/PrefixUniquenessTest.php
tests/phpunit/includes/api/RandomImageGenerator.php
tests/phpunit/includes/api/format/ApiFormatTestBase.php
tests/phpunit/includes/api/generateRandomImages.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/cache/GenderCacheTest.php
tests/phpunit/includes/cache/ProcessCacheLRUTest.php
tests/phpunit/includes/content/ContentHandlerTest.php
tests/phpunit/includes/content/CssContentTest.php
tests/phpunit/includes/content/JavaScriptContentTest.php
tests/phpunit/includes/content/TextContentTest.php
tests/phpunit/includes/content/WikitextContentHandlerTest.php
tests/phpunit/includes/content/WikitextContentTest.php
tests/phpunit/includes/db/DatabaseSQLTest.php
tests/phpunit/includes/db/DatabaseSqliteTest.php
tests/phpunit/includes/db/DatabaseTest.php
tests/phpunit/includes/debug/MWDebugTest.php
tests/phpunit/includes/filebackend/FileBackendTest.php
tests/phpunit/includes/filerepo/FileRepoTest.php
tests/phpunit/includes/filerepo/StoreBatchTest.php
tests/phpunit/includes/installer/InstallDocFormatterTest.php
tests/phpunit/includes/jobqueue/JobQueueTest.php [new file with mode: 0644]
tests/phpunit/includes/json/ServicesJsonTest.php
tests/phpunit/includes/libs/CSSJanusTest.php
tests/phpunit/includes/libs/GenericArrayObjectTest.php
tests/phpunit/includes/libs/IEUrlExtensionTest.php
tests/phpunit/includes/libs/JavaScriptMinifierTest.php
tests/phpunit/includes/logging/LogFormatterTest.php
tests/phpunit/includes/logging/LogTests.i18n.php
tests/phpunit/includes/media/BitmapMetadataHandlerTest.php
tests/phpunit/includes/media/BitmapScalingTest.php
tests/phpunit/includes/media/ExifBitmapTest.php
tests/phpunit/includes/media/ExifRotationTest.php
tests/phpunit/includes/media/ExifTest.php
tests/phpunit/includes/media/FormatMetadataTest.php
tests/phpunit/includes/media/GIFMetadataExtractorTest.php
tests/phpunit/includes/media/GIFTest.php
tests/phpunit/includes/media/IPTCTest.php
tests/phpunit/includes/media/JpegMetadataExtractorTest.php
tests/phpunit/includes/media/PNGMetadataExtractorTest.php
tests/phpunit/includes/media/PNGTest.php
tests/phpunit/includes/media/SVGMetadataExtractorTest.php
tests/phpunit/includes/media/XMPTest.php
tests/phpunit/includes/normal/CleanUpTest.php
tests/phpunit/includes/objectcache/BagOStuffTest.php
tests/phpunit/includes/parser/MagicVariableTest.php
tests/phpunit/includes/parser/MediaWikiParserTest.php
tests/phpunit/includes/parser/NewParserTest.php
tests/phpunit/includes/parser/ParserMethodsTest.php
tests/phpunit/includes/parser/ParserPreloadTest.php
tests/phpunit/includes/parser/PreprocessorTest.php
tests/phpunit/includes/parser/TagHooksTest.php
tests/phpunit/includes/search/SearchEngineTest.php
tests/phpunit/includes/site/SiteListTest.php
tests/phpunit/includes/site/SiteTest.php
tests/phpunit/includes/specials/QueryAllSpecialPagesTest.php
tests/phpunit/includes/specials/SpecialRecentchangesTest.php
tests/phpunit/includes/specials/SpecialSearchTest.php
tests/phpunit/includes/upload/UploadFromUrlTest.php
tests/phpunit/includes/upload/UploadStashTest.php
tests/phpunit/includes/upload/UploadTest.php
tests/phpunit/languages/LanguageAmTest.php
tests/phpunit/languages/LanguageArTest.php
tests/phpunit/languages/LanguageBeTest.php
tests/phpunit/languages/LanguageBe_taraskTest.php
tests/phpunit/languages/LanguageBhoTest.php
tests/phpunit/languages/LanguageBsTest.php
tests/phpunit/languages/LanguageClassesTestCase.php
tests/phpunit/languages/LanguageCsTest.php
tests/phpunit/languages/LanguageCuTest.php
tests/phpunit/languages/LanguageCyTest.php
tests/phpunit/languages/LanguageDsbTest.php
tests/phpunit/languages/LanguageFrTest.php
tests/phpunit/languages/LanguageGaTest.php
tests/phpunit/languages/LanguageGdTest.php
tests/phpunit/languages/LanguageGvTest.php
tests/phpunit/languages/LanguageHeTest.php
tests/phpunit/languages/LanguageHiTest.php
tests/phpunit/languages/LanguageHrTest.php
tests/phpunit/languages/LanguageHsbTest.php
tests/phpunit/languages/LanguageHuTest.php
tests/phpunit/languages/LanguageHyTest.php
tests/phpunit/languages/LanguageKshTest.php
tests/phpunit/languages/LanguageLnTest.php
tests/phpunit/languages/LanguageLtTest.php
tests/phpunit/languages/LanguageLvTest.php
tests/phpunit/languages/LanguageMgTest.php
tests/phpunit/languages/LanguageMkTest.php
tests/phpunit/languages/LanguageMlTest.php
tests/phpunit/languages/LanguageMoTest.php
tests/phpunit/languages/LanguageMtTest.php
tests/phpunit/languages/LanguageNsoTest.php
tests/phpunit/languages/LanguagePlTest.php
tests/phpunit/languages/LanguageRoTest.php
tests/phpunit/languages/LanguageRuTest.php
tests/phpunit/languages/LanguageSeTest.php
tests/phpunit/languages/LanguageSgsTest.php
tests/phpunit/languages/LanguageShTest.php
tests/phpunit/languages/LanguageSkTest.php
tests/phpunit/languages/LanguageSlTest.php
tests/phpunit/languages/LanguageSmaTest.php
tests/phpunit/languages/LanguageSrTest.php
tests/phpunit/languages/LanguageTest.php
tests/phpunit/languages/LanguageTiTest.php
tests/phpunit/languages/LanguageTlTest.php
tests/phpunit/languages/LanguageTrTest.php
tests/phpunit/languages/LanguageUkTest.php
tests/phpunit/languages/LanguageUzTest.php
tests/phpunit/languages/LanguageWaTest.php
tests/phpunit/languages/utils/CLDRPluralRuleEvaluatorTest.php
tests/phpunit/maintenance/DumpTestCase.php
tests/phpunit/maintenance/MaintenanceTest.php
tests/phpunit/maintenance/backupPrefetchTest.php
tests/phpunit/maintenance/backupTextPassTest.php
tests/phpunit/maintenance/backup_LogTest.php
tests/phpunit/maintenance/backup_PageTest.php
tests/phpunit/maintenance/fetchTextTest.php
tests/phpunit/phpunit.php
tests/phpunit/resources/ResourcesTest.php
tests/phpunit/skins/SideBarTest.php
tests/phpunit/suites/ExtensionsTestSuite.php
tests/phpunit/suites/UploadFromUrlTestSuite.php
tests/qunit/data/generateJqueryMsgData.php
tests/qunit/data/qunitOkCall.js
tests/qunit/data/styleTest.css.php
tests/qunit/data/testrunner.js
tests/qunit/suites/resources/jquery/jquery.autoEllipsis.test.js
tests/qunit/suites/resources/jquery/jquery.byteLength.test.js
tests/qunit/suites/resources/jquery/jquery.byteLimit.test.js
tests/qunit/suites/resources/jquery/jquery.client.test.js
tests/qunit/suites/resources/jquery/jquery.colorUtil.test.js
tests/qunit/suites/resources/jquery/jquery.delayedBind.test.js
tests/qunit/suites/resources/jquery/jquery.getAttrs.test.js
tests/qunit/suites/resources/jquery/jquery.hidpi.test.js
tests/qunit/suites/resources/jquery/jquery.localize.test.js
tests/qunit/suites/resources/jquery/jquery.mwExtension.test.js
tests/qunit/suites/resources/jquery/jquery.tabIndex.test.js
tests/qunit/suites/resources/jquery/jquery.tablesorter.test.js
tests/qunit/suites/resources/jquery/jquery.textSelection.test.js
tests/qunit/suites/resources/mediawiki.api/mediawiki.api.parse.test.js
tests/qunit/suites/resources/mediawiki.api/mediawiki.api.test.js
tests/qunit/suites/resources/mediawiki.special/mediawiki.special.recentchanges.test.js
tests/qunit/suites/resources/mediawiki/mediawiki.Title.test.js
tests/qunit/suites/resources/mediawiki/mediawiki.Uri.test.js
tests/qunit/suites/resources/mediawiki/mediawiki.cldr.test.js
tests/qunit/suites/resources/mediawiki/mediawiki.jqueryMsg.test.js
tests/qunit/suites/resources/mediawiki/mediawiki.jscompat.test.js
tests/qunit/suites/resources/mediawiki/mediawiki.language.test.js
tests/qunit/suites/resources/mediawiki/mediawiki.test.js
tests/qunit/suites/resources/mediawiki/mediawiki.user.test.js
tests/qunit/suites/resources/mediawiki/mediawiki.util.test.js
tests/selenium/Selenium.php
tests/selenium/SeleniumConfig.php
tests/selenium/SeleniumServerManager.php
tests/selenium/SeleniumTestCase.php
tests/selenium/SeleniumTestListener.php
tests/selenium/SeleniumTestSuite.php
tests/selenium/installer/MediaWikiButtonsAvailabilityTestCase.php
tests/selenium/installer/MediaWikiDifferentDatabaseAccountTestCase.php
tests/selenium/installer/MediaWikiDifferntDatabasePrefixTestCase.php
tests/selenium/installer/MediaWikiErrorsConnectToDatabasePageTestCase.php
tests/selenium/installer/MediaWikiErrorsNamepageTestCase.php
tests/selenium/installer/MediaWikiHelpFieldHintTestCase.php
tests/selenium/installer/MediaWikiInstallationCommonFunction.php
tests/selenium/installer/MediaWikiInstallationConfig.php
tests/selenium/installer/MediaWikiInstallationMessage.php
tests/selenium/installer/MediaWikiInstallationVariables.php
tests/selenium/installer/MediaWikiInstallerTestSuite.php
tests/selenium/installer/MediaWikiMySQLDataBaseTestCase.php
tests/selenium/installer/MediaWikiMySQLiteDataBaseTestCase.php
tests/selenium/installer/MediaWikiOnAlreadyInstalledTestCase.php
tests/selenium/installer/MediaWikiRestartInstallationTestCase.php
tests/selenium/installer/MediaWikiRightFrameworkLinksTestCase.php
tests/selenium/installer/MediaWikiUpgradeExistingDatabaseTestCase.php
tests/selenium/installer/MediaWikiUserInterfaceTestCase.php
tests/selenium/suites/AddContentToNewPageTestCase.php
tests/selenium/suites/AddNewPageTestCase.php
tests/selenium/suites/CreateAccountTestCase.php
tests/selenium/suites/DeletePageAdminTestCase.php
tests/selenium/suites/EmailPasswordTestCase.php
tests/selenium/suites/MediaWikiEditorConfig.php
tests/selenium/suites/MediaWikiEditorTestSuite.php
tests/selenium/suites/MediaWikiExtraTestSuite.php
tests/selenium/suites/MediawikiCoreSmokeTestCase.php
tests/selenium/suites/MediawikiCoreSmokeTestSuite.php
tests/selenium/suites/MovePageTestCase.php
tests/selenium/suites/MyContributionsTestCase.php
tests/selenium/suites/MyWatchListTestCase.php
tests/selenium/suites/PageDeleteTestSuite.php
tests/selenium/suites/PageSearchTestCase.php
tests/selenium/suites/PreviewPageTestCase.php
tests/selenium/suites/SavePageTestCase.php
tests/selenium/suites/SimpleSeleniumConfig.php
tests/selenium/suites/SimpleSeleniumTestCase.php
tests/selenium/suites/SimpleSeleniumTestSuite.php
tests/selenium/suites/UserPreferencesTestCase.php
tests/testHelpers.inc
thumb.php

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 c3111ba..7e06218 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,10 +87,18 @@ 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.
+* 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.
+* WikiText now permits the use of WAI-ARIA's role="presentation" inside of
+  html elements and tables. This allows presentational markup, especially
+  tables. To be marked up as such.
 
 === Bug fixes in 1.21 ===
 * (bug 40353) SpecialDoubleRedirect should support interwiki redirects.
@@ -158,6 +168,7 @@ production.
   ca-edit click instead opening URL directly.
 * (bug 43964) Invalid value of "link" parameter in <gallery> no longer produces
   a fatal error.
+* (bug 44775) The username field is not pre-filled when creating an account.
 
 === API changes in 1.21 ===
 * prop=revisions can now report the contentmodel and contentformat.
@@ -194,11 +205,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 ===
 
index ba8fe8b..db5e0ff 100644 (file)
@@ -15,5 +15,3 @@
  *
  * Configuration of the profiler output can be done in LocalSettings.php
  */
-
-
diff --git a/api.php b/api.php
index 4efcdba..abf601f 100644 (file)
--- a/api.php
+++ b/api.php
@@ -60,7 +60,7 @@ if ( !$wgEnableAPI ) {
        header( $_SERVER['SERVER_PROTOCOL'] . ' 500 MediaWiki configuration Error', true, 500 );
        echo( 'MediaWiki API is not enabled for this site. Add the following line to your LocalSettings.php'
                . '<pre><b>$wgEnableAPI=true;</b></pre>' );
-       die(1);
+       die( 1 );
 }
 
 // Set a dummy $wgTitle, because $wgTitle == null breaks various things
@@ -87,10 +87,10 @@ wfLogProfilingData();
 // Log the request
 if ( $wgAPIRequestLog ) {
        $items = array(
-                       wfTimestamp( TS_MW ),
-                       $endtime - $starttime,
-                       $wgRequest->getIP(),
-                       $_SERVER['HTTP_USER_AGENT']
+               wfTimestamp( TS_MW ),
+               $endtime - $starttime,
+               $wgRequest->getIP(),
+               $_SERVER['HTTP_USER_AGENT']
        );
        $items[] = $wgRequest->wasPosted() ? 'POST' : 'GET';
        $module = $processor->getModule();
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
index e480ab6..fa42c29 100644 (file)
@@ -1,6 +1,5 @@
 {
        "name": "mediawiki/core",
-       "version": "1.21-alpha",
        "description": "Free software wiki application developed by the Wikimedia Foundation and others",
        "keywords": ["mediawiki", "wiki"],
        "homepage": "https://www.mediawiki.org/",
                }
        ],
        "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",
        "require": {
                "php": ">=5.3.2"
        },
+       "require-dev": {
+               "phpunit/phpunit": "*"
+       },
        "suggest": {
                "ext-fileinfo": "*",
                "ext-mbstring": "*",
-               "ext-wikidiff2": "*"
+               "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..ccaa8af 100644 (file)
@@ -60,8 +60,8 @@ function wfImageAuthMain() {
 
        // See if this is a public Wiki (no protections).
        if ( $wgImgAuthPublicTest
-               && in_array( 'read', User::getGroupPermissions( array( '*' ) ), true ) )
-       {
+               && in_array( 'read', User::getGroupPermissions( array( '*' ) ), true )
+       {
                // This is a public wiki, so disable this script (for private wikis only)
                wfForbidden( 'img-auth-accessdenied', 'img-auth-public' );
                return;
@@ -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;
        }
 
@@ -130,7 +130,7 @@ function wfImageAuthMain() {
        }
 
        // Stream the requested file
-       wfDebugLog( 'img_auth', "Streaming `".$filename."`." );
+       wfDebugLog( 'img_auth', "Streaming `" . $filename . "`." );
        $repo->streamFile( $filename, array( 'Cache-Control: private', 'Vary: Cookie' ) );
 }
 
@@ -153,8 +153,8 @@ function wfForbidden( $msg1, $msg2 ) {
        $detailMsg = wfMessage( $detailMsgKey, $args )->escaped();
 
        wfDebugLog( 'img_auth',
-               "wfForbidden Hdr:" . wfMessage( $msg1 )->inLanguage( 'en' )->text() . " Msg: ".
-               wfMessage( $msg2, $args )->inLanguage( 'en' )->text()
+               "wfForbidden Hdr: " . wfMessage( $msg1 )->inLanguage( 'en' )->text() . " Msg: " .
+                       wfMessage( $msg2, $args )->inLanguage( 'en' )->text()
        );
 
        header( 'HTTP/1.0 403 Forbidden' );
index 75008ce..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()
@@ -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(),
index 1ee8da7..23cf411 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',
@@ -575,6 +583,7 @@ $wgAutoloadLocalClasses = array(
        'MemcLockManager' => 'includes/filebackend/lockmanager/MemcLockManager.php',
        'QuorumLockManager' => 'includes/filebackend/lockmanager/QuorumLockManager.php',
        'MySqlLockManager'=> 'includes/filebackend/lockmanager/DBLockManager.php',
+       'PostgreSqlLockManager'=> 'includes/filebackend/lockmanager/DBLockManager.php',
        'NullLockManager' => 'includes/filebackend/lockmanager/LockManager.php',
        'FileOp' => 'includes/filebackend/FileOp.php',
        'FileOpBatch' => 'includes/filebackend/FileOpBatch.php',
@@ -654,6 +663,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 +785,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 +812,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
index f53ce02..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,4 +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 68c4542..fc8168d 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
@@ -122,8 +122,7 @@ $wgScriptPath       = '/wiki';
  * you have customized it, having this incorrectly set to true can cause
  * redirect loops when "pretty URLs" are used.
  */
-$wgUsePathInfo =
-       ( strpos( PHP_SAPI, 'cgi' ) === false ) &&
+$wgUsePathInfo = ( strpos( PHP_SAPI, 'cgi' ) === false ) &&
        ( strpos( PHP_SAPI, 'apache2filter' ) === false ) &&
        ( strpos( PHP_SAPI, 'isapi' ) === false );
 
@@ -134,7 +133,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';
 
 
 /**@}*/
@@ -583,7 +582,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
@@ -684,7 +683,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
@@ -742,10 +741,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
 );
 
@@ -754,18 +753,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
 );
 
 /**
@@ -848,7 +847,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';
@@ -944,8 +943,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 */
@@ -1002,16 +1001,14 @@ $wgAntivirus = null;
 $wgAntivirusSetup = array(
 
        #setup for clamav
-       'clamav' => array (
-               'command' => "clamscan --no-summary ",
-
-               'codemap' => array (
-                       "0" =>  AV_NO_VIRUS, # no virus
-                       "1" =>  AV_VIRUS_FOUND, # virus found
+       'clamav' => array(
+               'command' => 'clamscan --no-summary ',
+               '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',
        ),
 );
@@ -1024,13 +1021,13 @@ $wgAntivirusRequired = true;
 $wgVerifyMimeType = true;
 
 /** Sets the mime type definition file to use by MimeMagic.php. */
-$wgMimeTypeFile = "includes/mime.types";
-#$wgMimeTypeFile= "/etc/mime.types";
-#$wgMimeTypeFile= null; #use built-in defaults only.
+$wgMimeTypeFile = 'includes/mime.types';
+#$wgMimeTypeFile = '/etc/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= null; #use built-in defaults only.
+$wgMimeInfoFile = 'includes/mime.info';
+#$wgMimeInfoFile = null; #use built-in defaults only.
 
 /**
  * Switch for loading the FileInfo extension by PECL at runtime.
@@ -1063,11 +1060,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?
 );
 
 /**
@@ -1103,7 +1100,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")
@@ -1268,12 +1265,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
  */
@@ -1627,7 +1624,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
  *
@@ -2189,7 +2186,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';
 
 /**
@@ -2352,16 +2363,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.
@@ -2414,9 +2420,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/Главна_страна
@@ -2449,7 +2455,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();
@@ -2983,21 +2989,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;
@@ -3178,13 +3184,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.
@@ -3226,7 +3232,7 @@ $wgCapitalLinks = true;
  *
  * @par Example:
  * @code
- *     $wgCapitalLinkOverrides[ NS_FILE ] = false;
+ *     $wgCapitalLinkOverrides[ NS_FILE ] = false;
  * @endcode
  */
 $wgCapitalLinkOverrides = array();
@@ -3235,18 +3241,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
 );
 
 /**
@@ -3348,7 +3354,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
@@ -3424,7 +3430,7 @@ $wgAlwaysUseTidy = false;
 /** @see $wgUseTidy */
 $wgTidyBin = 'tidy';
 /** @see $wgUseTidy */
-$wgTidyConf = $IP.'/includes/tidy.conf';
+$wgTidyConf = $IP . '/includes/tidy.conf';
 /** @see $wgUseTidy */
 $wgTidyOpts = '';
 /** @see $wgUseTidy */
@@ -3620,68 +3626,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 */
@@ -3770,6 +3776,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 }
 
 /************************************************************************//**
@@ -3899,85 +3912,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;
@@ -4158,11 +4171,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
  *
@@ -4221,7 +4234,8 @@ $wgDeleteRevisionsLimit = 0;
 /**
  * Number of accounts each IP address may create, 0 to disable.
  *
- * @warning Requires memcached */
+ * @warning Requires memcached
+ */
 $wgAccountCreationThrottle = 0;
 
 /**
@@ -4312,25 +4326,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.
@@ -4415,7 +4429,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"
@@ -4477,7 +4491,7 @@ $wgCacheVaryCookies = array();
 /** Override to customise the session name */
 $wgSessionName = false;
 
-/** @} */  # end of cookie settings }
+/** @} */ # end of cookie settings }
 
 /************************************************************************//**
  * @name   LaTeX (mathematical formulas)
@@ -4867,7 +4881,7 @@ $wgNamespacesToBeSearchedDefault = array(
  */
 $wgNamespacesToBeSearchedHelp = array(
        NS_PROJECT => true,
-       NS_HELP    => true,
+       NS_HELP => true,
 );
 
 /**
@@ -4894,10 +4908,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;
@@ -5001,7 +5015,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 */
@@ -5175,7 +5189,7 @@ $wgOverrideSiteFeed = array();
  * $wgOut->isSyndicated() is true.
  */
 $wgFeedClasses = array(
-       'rss'  => 'RSSFeed',
+       'rss' => 'RSSFeed',
        'atom' => 'AtomFeed',
 );
 
@@ -5332,8 +5346,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;
 
 /**
@@ -5350,13 +5364,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 }
@@ -5491,19 +5505,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.
  *
@@ -5648,7 +5661,7 @@ $wgLogRestrictions = array(
  *
  * @par Example:
  * @code
- *   $wgFilterLogTypes => array(
+ *   $wgFilterLogTypes = array(
  *      'move' => true,
  *      'import' => false,
  *   );
@@ -5675,16 +5688,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',
 );
 
@@ -5698,16 +5711,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',
 );
 
@@ -5718,21 +5731,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',
 );
 
 /**
@@ -5742,17 +5755,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',
 );
 
@@ -5784,107 +5797,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 */
@@ -5921,24 +5934,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,
 );
 
 /**
@@ -5986,8 +5999,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
  *
@@ -6098,7 +6111,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
@@ -6140,10 +6153,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
  */
@@ -6186,6 +6199,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.
  */
@@ -6436,9 +6474,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 80c091e..4e3ea49 100644 (file)
@@ -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>' );
                        }
                }
        }
@@ -2960,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() . ']]';
index 8893c6c..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;
@@ -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;
        }
 }
 
index 66f6275..67011d2 100644 (file)
@@ -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
                );
@@ -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 c57018e..3fa816f 100644 (file)
@@ -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';
 
@@ -2776,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 ) ) {
@@ -2835,8 +2837,15 @@ function wfShellExec( $cmd, &$retval = null, $environ = array(), $limits = array
                $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 cc9b54b..60be863 100644 (file)
@@ -929,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 9e9f0da..6a348a6 100644 (file)
@@ -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" );
                }
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 2a3e8e8..0b814ec 100644 (file)
@@ -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' ),
@@ -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 ) );
@@ -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
+       }
 }
 
 /**
index cc642e4..15e6620 100644 (file)
@@ -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;
                        }
 
index 108ba1d..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
@@ -701,7 +701,7 @@ class MimeMagic {
                }
 
                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 ) );
index 89d7c0b..577d610 100644 (file)
@@ -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
index 1e4f85f..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
index 0470426..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 = '';
                }
index cf6c106..c2d34b0 100644 (file)
@@ -736,6 +736,16 @@ class Sanitizer {
                                $value = Sanitizer::escapeId( $value, 'noninitial' );
                        }
 
+                       # WAI-ARIA
+                       # http://www.w3.org/TR/wai-aria/
+                       # http://www.whatwg.org/specs/web-apps/current-work/multipage/elements.html#wai-aria
+                       # For now we only support role="presentation" until we work out what roles should be
+                       # usable by content and we ensure that our code explicitly rejects patterns that
+                       # violate HTML5's ARIA restrictions.
+                       if ( $attribute === 'role' && $value !== 'presentation' ) {
+                               continue;
+                       }
+
                        //RDFa and microdata properties allow URLs, URIs and/or CURIs. check them for sanity
                        if ( $attribute === 'rel' || $attribute === 'rev' ||
                                $attribute === 'about' || $attribute === 'property' || $attribute === 'resource' || #RDFa
@@ -1059,10 +1069,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 +1237,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 +1357,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
@@ -1416,7 +1426,18 @@ class Sanitizer {
                        return $whitelist;
                }
 
-               $common = array( 'id', 'class', 'lang', 'dir', 'title', 'style' );
+               $common = array(
+                       # HTML
+                       'id',
+                       'class',
+                       'style',
+                       'lang',
+                       'dir',
+                       'title',
+
+                       # WAI-ARIA
+                       'role',
+               );
 
                if ( $wgAllowRdfaAttributes ) {
                        #RDFa attributes as specified in section 9 of http://www.w3.org/TR/2008/REC-rdfa-syntax-20081014
@@ -1736,8 +1757,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 +1767,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 273d75b..7f4d634 100644 (file)
@@ -65,7 +65,7 @@ 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";
index 01841b6..addaddd 100644 (file)
@@ -294,8 +294,6 @@ class SiteStatsUpdate implements DeferrableUpdate {
                        $this->doUpdatePendingDeltas();
                } else {
                        $dbw = wfGetDB( DB_MASTER );
-                       // Need a separate transaction because this a global lock
-                       $dbw->begin( __METHOD__ );
 
                        $lockKey = wfMemcKey( 'site_stats' ); // prepend wiki ID
                        if ( $rate ) {
@@ -316,6 +314,9 @@ class SiteStatsUpdate implements DeferrableUpdate {
                                $this->images   += ( $pd['ss_images']['+'] - $pd['ss_images']['-'] );
                        }
 
+                       // Need a separate transaction because this a global lock
+                       $dbw->begin( __METHOD__ );
+
                        // Build up an SQL query of deltas and apply them...
                        $updates = '';
                        $this->appendUpdate( $updates, 'ss_total_views', $this->views );
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 6aa4cd2..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 ) {
@@ -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..99642b7
--- /dev/null
@@ -0,0 +1,350 @@
+<?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 309d755..c2af93c 100644 (file)
@@ -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' );
index 4cc28c3..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 );
                        }
index 28cc949..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',
index 57007eb..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
 
        /**
index 59d4222..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 );
@@ -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 1cca95c..ebedde3 100644 (file)
@@ -125,8 +125,7 @@ class InfoAction extends FormlessAction {
         * @return string The HTML.
         */
        protected function makeHeader( $header ) {
-               global $wgParser;
-               $spanAttribs = array( 'class' => 'mw-headline', 'id' => $wgParser->guessSectionNameFromWikiText( $header ) );
+               $spanAttribs = array( 'class' => 'mw-headline', 'id' => Sanitizer::escapeId( $header ) );
                return Html::rawElement( 'h2', array(), Html::element( 'span', $spanAttribs, $header ) );
        }
 
@@ -274,6 +273,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 68302b1..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;
        }
 
@@ -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 86f8112..9cafc5b 100644 (file)
@@ -43,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 );
        }
@@ -114,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)',
                );
        }
 
@@ -134,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 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 4dbccc6..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,7 +708,7 @@ 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' );
@@ -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 1e9e503..b81e5c7 100644 (file)
@@ -101,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() );
 
@@ -157,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 fa888c9..bd92077 100644 (file)
  */
 class ApiPurge extends ApiBase {
 
+       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' );
@@ -112,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() {
@@ -153,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
+                               ),
                        )
                );
        }
@@ -167,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 addcf07..59e6652 100644 (file)
@@ -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 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 4b9bc98..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() {
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 3b4220c..593d6e7 100644 (file)
@@ -96,6 +96,9 @@ class ApiQuerySiteinfo extends ApiQueryBase {
                                case 'variables':
                                        $fit = $this->appendVariables( $p );
                                        break;
+                               case 'protocols':
+                                       $fit = $this->appendProtocols( $p );
+                                       break;
                                default:
                                        ApiBase::dieDebug( __METHOD__, "Unknown prop=$p" );
                        }
@@ -530,7 +533,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 );
        }
@@ -549,6 +552,12 @@ class ApiQuerySiteinfo extends ApiQueryBase {
                return $this->getResult()->addValue( 'query', $property, $variables );
        }
 
+       public function appendProtocols( $property ) {
+               global $wgUrlProtocols;
+               $this->getResult()->setIndexedTagName( $wgUrlProtocols, 'p' );
+               return $this->getResult()->addValue( 'query', $property, $wgUrlProtocols );
+       }
+
        private function formatParserTags( $item ) {
                return "<{$item}>";
        }
@@ -601,6 +610,7 @@ class ApiQuerySiteinfo extends ApiQueryBase {
                                        'functionhooks',
                                        'showhooks',
                                        'variables',
+                                       'protocols',
                                )
                        ),
                        'filteriw' => array(
@@ -638,6 +648,7 @@ class ApiQuerySiteinfo extends ApiQueryBase {
                                ' functionhooks         - Returns a list of parser function hooks',
                                ' showhooks             - Returns a list of all subscribed hooks (contents of $wgHooks)',
                                ' variables             - Returns a list of variable IDs',
+                               ' protocols             - Returns a list of protocols that are allowed in external links.',
                        ),
                        'filteriw' =>  'Return only local or only nonlocal entries of the interwiki map',
                        'showalldb' => 'List all database servers, not just the one lagging the most',
index 7128920..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.
index 7a47a0c..3f5ebfe 100644 (file)
@@ -31,6 +31,8 @@
  */
 class ApiSetNotificationTimestamp extends ApiBase {
 
+       private $mPageSet;
+
        public function execute() {
                $user = $this->getUser();
 
@@ -41,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 );
 
@@ -92,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'] = '';
@@ -157,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;
        }
@@ -173,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'
                        ),
@@ -190,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)',
@@ -249,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 2627396..a0da765 100644 (file)
@@ -278,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;
@@ -658,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' );
                }
        }
 
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 6476646..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();
index bd4ce22..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() );
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 7341602..e14fb56 100644 (file)
@@ -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 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 7e865c1..bf619a7 100644 (file)
@@ -3013,18 +3013,18 @@ abstract class DatabaseBase implements DatabaseType {
 
                if ( $this->mTrxLevel ) { // implicit commit
                        if ( !$this->mTrxAutomatic ) {
-                               // We want to warn about inadvertently nested begin/commit pairs, but not about auto-committing
-                               // implicit transactions that were started by query() because DBO_TRX was set.
-
-                               wfWarn( "$fname: Transaction already in progress (from {$this->mTrxFname}), " .
-                                       " performing implicit commit!" );
+                               // We want to warn about inadvertently nested begin/commit pairs, but not about
+                               // auto-committing implicit transactions that were started by query() via DBO_TRX
+                               $msg = "$fname: Transaction already in progress (from {$this->mTrxFname}), " .
+                                       " performing implicit commit!";
+                               wfWarn( $msg );
+                               wfLogDBError( $msg );
                        } else {
                                // if the transaction was automatic and has done write operations,
                                // log it if $wgDebugDBTransactions is enabled.
-
                                if ( $this->mTrxDoneWrites && $wgDebugDBTransactions ) {
-                                       wfDebug( "$fname: Automatic transaction with writes in progress (from {$this->mTrxFname}), " .
-                                               " performing implicit commit!\n" );
+                                       wfDebug( "$fname: Automatic transaction with writes in progress" .
+                                               " (from {$this->mTrxFname}), performing implicit commit!\n" );
                                }
                        }
 
index 57ffd4f..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)
@@ -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 {
@@ -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;
        }
 
        /**
@@ -1132,6 +1132,5 @@ class MssqlResult {
 
        public function free() {
                unset( $this->mRows );
-               return;
        }
 }
index 5195a83..626d841 100644 (file)
@@ -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() {
@@ -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 ) {
index 86b8e8a..2cbcc4b 100644 (file)
@@ -393,6 +393,9 @@ class DatabasePostgres extends DatabaseBase {
                $this->query( "SET datestyle = 'ISO, YMD'", __METHOD__ );
                $this->query( "SET timezone = 'GMT'", __METHOD__ );
                $this->query( "SET standard_conforming_strings = on", __METHOD__ );
+               if ( $this->getServerVersion() >= 9.0 ) {
+                       $this->query( "SET bytea_output = 'escape'", __METHOD__ ); // PHP bug 53127
+               }
 
                global $wgDBmwschema;
                $this->determineCoreSchema( $wgDBmwschema );
@@ -1436,4 +1439,65 @@ SQL;
                }
                return parent::streamStatementEnd( $sql, $newLine );
        }
+
+       /**
+        * Check to see if a named lock is available. This is non-blocking.
+        * See http://www.postgresql.org/docs/8.2/static/functions-admin.html#FUNCTIONS-ADVISORY-LOCKS
+        *
+        * @param $lockName String: name of lock to poll
+        * @param $method String: name of method calling us
+        * @return Boolean
+        * @since 1.20
+        */
+       public function lockIsFree( $lockName, $method ) {
+               $key = $this->addQuotes( $this->bigintFromLockName( $lockName ) );
+               $result = $this->query( "SELECT (CASE(pg_try_advisory_lock($key))
+                       WHEN 'f' THEN 'f' ELSE pg_advisory_unlock($key) END) AS lockstatus", $method );
+               $row = $this->fetchObject( $result );
+               return ( $row->lockstatus === 't' );
+       }
+
+       /**
+        * See http://www.postgresql.org/docs/8.2/static/functions-admin.html#FUNCTIONS-ADVISORY-LOCKS
+        * @param $lockName string
+        * @param $method string
+        * @param $timeout int
+        * @return bool
+        */
+       public function lock( $lockName, $method, $timeout = 5 ) {
+               $key = $this->addQuotes( $this->bigintFromLockName( $lockName ) );
+               for ( $attempts=1; $attempts <= $timeout; ++$attempts ) {
+                       $result = $this->query(
+                               "SELECT pg_try_advisory_lock($key) AS lockstatus", $method );
+                       $row = $this->fetchObject( $result );
+                       if ( $row->lockstatus === 't' ) {
+                               return true;
+                       } else {
+                               sleep( 1 );
+                       }
+               }
+               wfDebug( __METHOD__." failed to acquire lock\n" );
+               return false;
+       }
+
+       /**
+        * See http://www.postgresql.org/docs/8.2/static/functions-admin.html#FUNCTIONS-ADVISORY-LOCKSFROM PG DOCS: http://www.postgresql.org/docs/8.2/static/functions-admin.html#FUNCTIONS-ADVISORY-LOCKS
+        * @param $lockName string
+        * @param $method string
+        * @return bool
+        */
+       public function unlock( $lockName, $method ) {
+               $key = $this->addQuotes( $this->bigintFromLockName( $lockName ) );
+               $result = $this->query( "SELECT pg_advisory_unlock($key) as lockstatus", $method );
+               $row = $this->fetchObject( $result );
+               return ( $row->lockstatus === 't' );
+       }
+
+       /**
+        * @param string $lockName
+        * @return string Integer
+        */
+       private function bigintFromLockName( $lockName ) {
+               return wfBaseConvert( substr( sha1( $lockName ), 0, 15 ), 16, 10 );
+       }
 } // end DatabasePostgres class
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 a3e1de3..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,10 +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.
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 d825d04..9c271ea 100644 (file)
@@ -315,7 +315,9 @@ class SwiftFileBackend extends FileBackendStore {
                }
 
                // (b) Get a SHA-1 hash of the object
+               wfSuppressWarnings();
                $sha1Hash = sha1_file( $params['src'] );
+               wfRestoreWarnings();
                if ( $sha1Hash === false ) { // source doesn't exist?
                        $status->fatal( 'backend-fail-copy', $params['src'], $params['dst'] );
                        return $status;
index 7b365c1..90f4ccd 100644 (file)
  */
 
 /**
- * Version of LockManager based on using DB table row locks.
+ * Version of LockManager based on using named/row DB 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.
  *
  * All lock requests for a resource, identified by a hash string, will map
  * to one bucket. Each bucket maps to one or several peer DBs, each on their
@@ -38,7 +36,7 @@
  * @ingroup LockManager
  * @since 1.19
  */
-class DBLockManager extends QuorumLockManager {
+abstract class DBLockManager extends QuorumLockManager {
        /** @var Array Map of DB names to server config */
        protected $dbServers; // (DB name => server config array)
        /** @var BagOStuff */
@@ -112,65 +110,6 @@ class DBLockManager extends QuorumLockManager {
                $this->session = wfRandomString( 31 );
        }
 
-       /**
-        * Get a connection to a lock DB and acquire locks on $paths.
-        * This does not use GET_LOCK() per http://bugs.mysql.com/bug.php?id=1118.
-        *
-        * @see QuorumLockManager::getLocksOnServer()
-        * @return Status
-        */
-       protected function getLocksOnServer( $lockSrv, array $paths, $type ) {
-               $status = Status::newGood();
-
-               if ( $type == self::LOCK_EX ) { // writer locks
-                       try {
-                               $keys = array_unique( array_map( array( $this, 'sha1Base36Absolute' ), $paths ) );
-                               # Build up values for INSERT clause
-                               $data = array();
-                               foreach ( $keys as $key ) {
-                                       $data[] = array( 'fle_key' => $key );
-                               }
-                               # Wait on any existing writers and block new ones if we get in
-                               $db = $this->getConnection( $lockSrv ); // checked in isServerUp()
-                               $db->insert( 'filelocks_exclusive', $data, __METHOD__ );
-                       } catch ( DBError $e ) {
-                               foreach ( $paths as $path ) {
-                                       $status->fatal( 'lockmanager-fail-acquirelock', $path );
-                               }
-                       }
-               }
-
-               return $status;
-       }
-
-       /**
-        * @see QuorumLockManager::freeLocksOnServer()
-        * @return Status
-        */
-       protected function freeLocksOnServer( $lockSrv, array $paths, $type ) {
-               return Status::newGood(); // not supported
-       }
-
-       /**
-        * @see QuorumLockManager::releaseAllLocks()
-        * @return Status
-        */
-       protected function releaseAllLocks() {
-               $status = Status::newGood();
-
-               foreach ( $this->conns as $lockDb => $db ) {
-                       if ( $db->trxLevel() ) { // in transaction
-                               try {
-                                       $db->rollback( __METHOD__ ); // finish transaction and kill any rows
-                               } catch ( DBError $e ) {
-                                       $status->fatal( 'lockmanager-fail-db-release', $lockDb );
-                               }
-                       }
-               }
-
-               return $status;
-       }
-
        /**
         * @see QuorumLockManager::isServerUp()
         * @return bool
@@ -276,14 +215,8 @@ class DBLockManager extends QuorumLockManager {
         * Make sure remaining locks get cleared for sanity
         */
        function __destruct() {
+               $this->releaseAllLocks();
                foreach ( $this->conns as $db ) {
-                       if ( $db->trxLevel() ) { // in transaction
-                               try {
-                                       $db->rollback( __METHOD__ ); // finish transaction and kill any rows
-                               } catch ( DBError $e ) {
-                                       // oh well
-                               }
-                       }
                        $db->close();
                }
        }
@@ -373,4 +306,117 @@ class MySqlLockManager extends DBLockManager {
 
                return $status;
        }
+
+       /**
+        * @see QuorumLockManager::freeLocksOnServer()
+        * @return Status
+        */
+       protected function freeLocksOnServer( $lockSrv, array $paths, $type ) {
+               return Status::newGood(); // not supported
+       }
+
+       /**
+        * @see QuorumLockManager::releaseAllLocks()
+        * @return Status
+        */
+       protected function releaseAllLocks() {
+               $status = Status::newGood();
+
+               foreach ( $this->conns as $lockDb => $db ) {
+                       if ( $db->trxLevel() ) { // in transaction
+                               try {
+                                       $db->rollback( __METHOD__ ); // finish transaction and kill any rows
+                               } catch ( DBError $e ) {
+                                       $status->fatal( 'lockmanager-fail-db-release', $lockDb );
+                               }
+                       }
+               }
+
+               return $status;
+       }
+}
+
+/**
+ * PostgreSQL version of DBLockManager that supports shared locks.
+ * All locks are non-blocking, which avoids deadlocks.
+ *
+ * @ingroup LockManager
+ */
+class PostgreSqlLockManager extends DBLockManager {
+       /** @var Array Mapping of lock types to the type actually used */
+       protected $lockTypeMap = array(
+               self::LOCK_SH => self::LOCK_SH,
+               self::LOCK_UW => self::LOCK_SH,
+               self::LOCK_EX => self::LOCK_EX
+       );
+
+       protected function getLocksOnServer( $lockSrv, array $paths, $type ) {
+               $status = Status::newGood();
+               if ( !count( $paths ) ) {
+                       return $status; // nothing to lock
+               }
+
+               $db = $this->getConnection( $lockSrv ); // checked in isServerUp()
+               $bigints = array_unique( array_map(
+                       function( $key ) { return wfBaseConvert( substr( $key, 0, 15 ), 16, 10 ); },
+                       array_map( array( $this, 'sha1Base16Absolute' ), $paths )
+               ) );
+
+               // Try to acquire all the locks...
+               $fields = array();
+               foreach ( $bigints as $bigint ) {
+                       $fields[] = ( $type == self::LOCK_SH )
+                               ? "pg_try_advisory_lock_shared({$db->addQuotes( $bigint )}) AS K$bigint"
+                               : "pg_try_advisory_lock({$db->addQuotes( $bigint )}) AS K$bigint";
+               }
+               $res = $db->query( 'SELECT ' . implode( ', ', $fields ), __METHOD__ );
+               $row = (array)$res->fetchObject();
+
+               if ( in_array( 'f', $row ) ) {
+                       // Release any acquired locks if some could not be acquired...
+                       $fields = array();
+                       foreach ( $row as $kbigint => $ok ) {
+                               if ( $ok === 't' ) { // locked
+                                       $bigint = substr( $kbigint, 1 ); // strip off the "K"
+                                       $fields[] = ( $type == self::LOCK_SH )
+                                               ? "pg_advisory_unlock_shared({$db->addQuotes( $bigint )})"
+                                               : "pg_advisory_unlock({$db->addQuotes( $bigint )})";
+                               }
+                       }
+                       if ( count( $fields ) ) {
+                               $db->query( 'SELECT ' . implode( ', ', $fields ), __METHOD__ );
+                       }
+                       foreach ( $paths as $path ) {
+                               $status->fatal( 'lockmanager-fail-acquirelock', $path );
+                       }
+               }
+
+               return $status;
+       }
+
+       /**
+        * @see QuorumLockManager::freeLocksOnServer()
+        * @return Status
+        */
+       protected function freeLocksOnServer( $lockSrv, array $paths, $type ) {
+               return Status::newGood(); // not supported
+       }
+
+       /**
+        * @see QuorumLockManager::releaseAllLocks()
+        * @return Status
+        */
+       protected function releaseAllLocks() {
+               $status = Status::newGood();
+
+               foreach ( $this->conns as $lockDb => $db ) {
+                       try {
+                               $db->query( "SELECT pg_advisory_unlock_all()", __METHOD__ );
+                       } catch ( DBError $e ) {
+                               $status->fatal( 'lockmanager-fail-db-release', $lockDb );
+                       }
+               }
+
+               return $status;
+       }
 }
index f988ff4..d222bab 100644 (file)
@@ -112,6 +112,18 @@ abstract class LockManager {
                return wfBaseConvert( sha1( "{$this->domain}:{$path}" ), 16, 36, 31 );
        }
 
+       /**
+        * Get the base 16 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 function sha1Base16Absolute( $path ) {
+               return sha1( "{$this->domain}:{$path}" );
+       }
+
        /**
         * Lock resources with the given keys and lock type
         *
index e1ecb96..98a21f7 100644 (file)
@@ -274,7 +274,7 @@ class ForeignAPIRepo extends FileRepo {
                } 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 */
index b02d92b..3f78619 100644 (file)
@@ -137,30 +137,12 @@ class ArchivedFile {
                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.
         *
index 0ddebc9..5acaf04 100644 (file)
@@ -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 );
@@ -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 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 2366495..7263392 100644 (file)
@@ -681,6 +681,7 @@ This message refers to a block of HTML being embedded into the installer page. I
 {{Identical|Memcached server}}',
        'config-extensions' => '{{Identical|Extension}}',
        'config-install-step-done' => '{{Identical|Done}}',
+       'config-install-step-failed' => '{{Identical|Failed}}',
        'config-install-database' => '*{{msg-mw|Config-install-database}}
 *{{msg-mw|Config-install-tables}}
 *{{msg-mw|Config-install-schema}}
@@ -4349,7 +4350,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' => 'Άλλο (προσδιορίστε)',
@@ -7130,7 +7131,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 כאן.
@@ -7211,7 +7212,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',
@@ -7351,7 +7352,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' => 'ויקי פרטי',
@@ -7360,13 +7361,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' => 'קריאייטיב קומונז–ייחוס–שיתוף זהה',
@@ -7451,7 +7452,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' => 'כולל הרחבות',
@@ -7516,7 +7517,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 (हिन्दी)
@@ -13957,7 +13959,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.
index 643459f..ff9e271 100644 (file)
@@ -537,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 07047f2..e126c23 100644 (file)
@@ -1157,7 +1157,7 @@ class WebInstaller_Install extends WebInstallerPage {
                        $this->startForm();
                        $this->addHTML( "<ul>" );
                        $results = $this->parent->performInstallation(
-                               array( $this, 'startStage'),
+                               array( $this, 'startStage' ),
                                array( $this, 'endStage' )
                        );
                        $this->addHTML( "</ul>" );
@@ -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();
                }
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 92beb2c..7ce654b 100644 (file)
@@ -324,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 9b3ffa7..6e42305 100644 (file)
@@ -28,6 +28,7 @@
  * @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
@@ -105,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 );
@@ -215,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' ) ) ) {
@@ -401,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
 
@@ -439,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 );
                        }
                }
 
@@ -516,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;
@@ -554,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 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;
        }
 
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 d34bf6e..47b2231 100644 (file)
@@ -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 );
index 5ff0434..eb8779f 100644 (file)
@@ -192,7 +192,7 @@ 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':
index 5300947..9735791 100644 (file)
@@ -259,7 +259,7 @@ class DjVuImage {
                # Text layer
                if ( isset( $wgDjvuTxt ) ) {
                        wfProfileIn( 'djvutxt' );
-                       $cmd = wfEscapeShellArg( $wgDjvuTxt ) . ' --detail=page ' . wfEscapeShellArg( $this->mFilename ) ;
+                       $cmd = wfEscapeShellArg( $wgDjvuTxt ) . ' --detail=page ' . wfEscapeShellArg( $this->mFilename );
                        wfDebug( __METHOD__ . ": $cmd\n" );
                        $retval = '';
                        $txt = wfShellExec( $cmd, $retval, array(), array( 'memory' => self::DJVUTXT_MEMORY_LIMIT ) );
@@ -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 63b2122..2dc2eae 100644 (file)
@@ -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...
@@ -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" );
                }
        }
 
index c34e67b..1671ab2 100644 (file)
@@ -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 ) {
index 7109f42..97aa28b 100644 (file)
@@ -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 );
index 3ae59ad..06cbc3b 100644 (file)
@@ -375,8 +375,8 @@ class IPTC {
                        $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)
+               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'
@@ -386,7 +386,7 @@ class IPTC {
                        // 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;
                }
 
index fb305db..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];
index e4833fc..0decb75 100644 (file)
@@ -276,10 +276,7 @@ class XMPReader {
                                                default:
                                                        //this should be impossible to get to
                                                        throw new MWException( "Invalid BOM" );
-                                                       break;
-
                                        }
-
                                } else {
                                        // standard specifically says, if no bom assume utf-8
                                        $this->charset = 'UTF-8';
@@ -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;
-
        }
 
        /**
@@ -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 59547e5..e2ae535 100644 (file)
@@ -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;
                        }
index eaa2304..adc3ef2 100644 (file)
@@ -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 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 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 bae1b75..5cc02d3 100644 (file)
@@ -324,28 +324,28 @@ class SqlBagOStuff extends BagOStuff {
         * @return bool
         */
        public function cas( $casToken, $key, $value, $exptime = 0 ) {
-               $db = $this->getDB();
-               $exptime = intval( $exptime );
-
-               if ( $exptime < 0 ) {
-                       $exptime = 0;
-               }
+               list( $serverIndex, $tableName ) = $this->getTableByKey( $key );
+               try {
+                       $db = $this->getDB( $serverIndex );
+                       $exptime = intval( $exptime );
 
-               if ( $exptime == 0 ) {
-                       $encExpiry = $this->getMaxDateTime();
-               } else {
-                       if ( $exptime < 3.16e8 ) { # ~10 years
-                               $exptime += time();
+                       if ( $exptime < 0 ) {
+                               $exptime = 0;
                        }
 
-                       $encExpiry = $db->timestamp( $exptime );
-               }
-               try {
+                       if ( $exptime == 0 ) {
+                               $encExpiry = $this->getMaxDateTime( $db );
+                       } else {
+                               if ( $exptime < 3.16e8 ) { # ~10 years
+                                       $exptime += time();
+                               }
+                               $encExpiry = $db->timestamp( $exptime );
+                       }
                        $db->begin( __METHOD__ );
                        // (bug 24425) use a replace if the db supports it instead of
                        // delete/insert to avoid clashes with conflicting keynames
                        $db->update(
-                               $this->getTableByKey( $key ),
+                               $tableName,
                                array(
                                        'keyname' => $key,
                                        'value' => $db->encodeBlob( $this->serialize( $value ) ),
@@ -354,7 +354,9 @@ class SqlBagOStuff extends BagOStuff {
                                array(
                                        'keyname' => $key,
                                        'value' => $db->encodeBlob( $this->serialize( $casToken ) )
-                               ), __METHOD__ );
+                               ),
+                               __METHOD__
+                       );
                        $db->commit( __METHOD__ );
                } catch ( DBQueryError $e ) {
                        $this->handleWriteError( $e );
index 5e93466..ff1e0af 100644 (file)
@@ -215,7 +215,7 @@ 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 ) ) {
                        # Fail gracefully
index 876e3b7..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() . '#%';
@@ -1810,7 +1805,7 @@ class Parser {
                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
@@ -1870,7 +1865,7 @@ class Parser {
                                }
                                $trail = "";
                        } else { # Invalid form; output directly
-                               $s .= $prefix . '[[' . $line ;
+                               $s .= $prefix . '[[' . $line;
                                wfProfileOut( __METHOD__ . "-e1" );
                                continue;
                        }
@@ -1881,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;
                        }
@@ -2337,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
@@ -2388,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 );
@@ -4109,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 );
@@ -5240,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
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 f6da6c7..b2cdc41 100644 (file)
@@ -134,7 +134,7 @@ class Parser_LinkHooks extends Parser {
                wfProfileIn( __METHOD__ );
 
                wfProfileIn( __METHOD__ . '-setup' );
-               static $tc = FALSE, $titleRegex; //$e1, $e1_img;
+               static $tc = false, $titleRegex; //$e1, $e1_img;
                if( !$tc ) {
                        # the % is needed to support urlencoded titles as well
                        $tc = Title::legalChars() . '#%';
index 2505528..468802d 100644 (file)
@@ -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 );
index a871205..c22da64 100644 (file)
@@ -643,19 +643,13 @@ class Preprocessor_Hash implements Preprocessor {
                                        $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() );
diff --git a/includes/parser/Preprocessor_HipHop.hphp b/includes/parser/Preprocessor_HipHop.hphp
deleted file mode 100644 (file)
index bd5e1a7..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 5340cb9..d64201c 100644 (file)
@@ -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
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 d21520c..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
index c462057..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__ );
        }
index fba2bf0..2b505b3 100644 (file)
@@ -85,11 +85,7 @@ class SpecialChangePassword extends UnlistedSpecialPage {
                                                'wpDomain'     => $this->mDomain,
                                                'wpLoginToken' => $token,
                                                'wpPassword'   => $request->getVal( 'wpNewPassword' ),
-                                               'returnto'     => $request->getVal( 'returnto' ),
-                                       );
-                                       if( $request->getCheck( 'wpRemember' ) ) {
-                                               $data['wpRemember'] = 1;
-                                       }
+                                       ) + $request->getValues( 'wpRemember', 'returnto', 'returntoquery' );
                                        $login = new LoginForm( new FauxRequest( $data, true ) );
                                        $login->setContext( $this->getContext() );
                                        $login->execute( null );
@@ -103,11 +99,13 @@ class SpecialChangePassword extends UnlistedSpecialPage {
        }
 
        function doReturnTo() {
-               $titleObj = Title::newFromText( $this->getRequest()->getVal( 'returnto' ) );
+               $request = $this->getRequest();
+               $titleObj = Title::newFromText( $request->getVal( 'returnto' ) );
                if ( !$titleObj instanceof Title ) {
                        $titleObj = Title::newMainPage();
                }
-               $this->getOutput()->redirect( $titleObj->getFullURL() );
+               $query = $request->getVal( 'returntoquery' );
+               $this->getOutput()->redirect( $titleObj->getFullURL( $query ) );
        }
 
        /**
@@ -150,6 +148,15 @@ class SpecialChangePassword extends UnlistedSpecialPage {
                                        array( 'wpRetype', 'retypenew', 'password', null ),
                                );
                $prettyFields = array_merge( $prettyFields, $extraFields );
+               $hiddenFields = array(
+                       'token' => $user->getEditToken(),
+                       'wpName' => $this->mUserName,
+                       'wpDomain' => $this->mDomain,
+               ) + $this->getRequest()->getValues( 'returnto', 'returntoquery' );
+               $hiddenFieldsStr = '';
+               foreach( $hiddenFields as $fieldname => $fieldvalue ) {
+                       $hiddenFieldsStr .= Html::hidden( $fieldname, $fieldvalue ) . "\n";
+               }
                $this->getOutput()->addHTML(
                        Xml::fieldset( $this->msg( 'resetpass_header' )->text() ) .
                        Xml::openElement( 'form',
@@ -157,10 +164,7 @@ class SpecialChangePassword extends UnlistedSpecialPage {
                                        'method' => 'post',
                                        'action' => $this->getTitle()->getLocalUrl(),
                                        'id' => 'mw-resetpass-form' ) ) . "\n" .
-                       Html::hidden( 'token', $user->getEditToken() ) . "\n" .
-                       Html::hidden( 'wpName', $this->mUserName ) . "\n" .
-                       Html::hidden( 'wpDomain', $this->mDomain ) . "\n" .
-                       Html::hidden( 'returnto', $this->getRequest()->getVal( 'returnto' ) ) . "\n" .
+                       $hiddenFieldsStr .
                        $this->msg( 'resetpass_text' )->parseAsBlock() . "\n" .
                        Xml::openElement( 'table', array( 'id' => 'mw-resetpass-table' ) ) . "\n" .
                        $this->pretty( $prettyFields ) . "\n" .
index af4d4fb..d156d20 100644 (file)
@@ -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 40971c7..7e1b44a 100644 (file)
@@ -77,6 +77,7 @@ class SpecialEditWatchlist extends UnlistedSpecialPage {
                }
 
                $this->checkPermissions();
+               $this->checkReadOnly();
 
                $this->outputHeader();
 
index 9eb555a..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
                                 */
@@ -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 ) {
index 06e3261..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)',
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 f486ea8..e1e18e4 100644 (file)
@@ -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 8180963..77f0ddb 100644 (file)
@@ -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()
@@ -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 ) {
index cf95994..afc41bf 100644 (file)
@@ -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' ) );
index e57871c..78383bd 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' );
                }
 
@@ -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();
@@ -1031,7 +1033,8 @@ class LoginForm extends SpecialPage {
                        }
                }
 
-               if ( $this->mUsername == '' ) {
+               // Pre-fill username (if not creating an account, bug 44775).
+               if ( $this->mUsername == '' && $this->mType != 'signup' ) {
                        if ( $user->isLoggedIn() ) {
                                $this->mUsername = $user->getName();
                        } else {
@@ -1076,6 +1079,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 4eb30ee..3a37f11 100644 (file)
@@ -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__ );
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 5538ac8..ffb3268 100644 (file)
@@ -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 9c15595..5079813 100644 (file)
@@ -77,19 +77,6 @@ class LanguageHy extends Language {
                return $word;
        }
 
-       /**
-        * @param $count int
-        * @param $forms array
-        *
-        * @return string
-        */
-       function convertPlural( $count, $forms ) {
-               if ( !count( $forms ) ) { return ''; }
-               $forms = $this->preConvertPlural( $forms, 2 );
-
-               return ( abs( $count ) <= 1 ) ? $forms[0] : $forms[1];
-       }
-
        /**
         * Armenian numeric format is "12 345,67" but "1234,56"
         *
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 a2992c8..d1a403d 100644 (file)
@@ -1,8 +1,8 @@
 <?xml version="1.0" encoding="UTF-8" ?>
 <!DOCTYPE supplementalData SYSTEM "../../common/dtd/ldmlSupplemental.dtd">
 <supplementalData>
-    <version number="$Revision: 7657 $"/>
-    <generation date="$Date: 2012-08-29 11:20:56 -0700 (Wed, 29 Aug 2012) $"/>
+    <version number="$Revision: 8007 $"/>
+    <generation date="$Date: 2013-01-03 07:17:41 +0530 (Thu, 03 Jan 2013) $"/>
     <plurals>
         <!-- if locale is known to have no plurals, there are no rules -->
         <pluralRules locales="az bm bo dz fa id ig ii hu ja jv ka kde kea km kn ko lo ms my sah ses sg th to tr vi wo yo zh"/> 
@@ -18,7 +18,7 @@
             <pluralRule count="two">n is 2</pluralRule>
             <pluralRule count="many">n is not 0 AND n mod 10 is 0</pluralRule>
         </pluralRules>
-        <pluralRules locales="asa ast af bem bez bg bn brx ca cgg chr ckb da de dv ee el en eo es et eu fi fo fur fy gl gsw gu ha haw is it jgo jmc kaj kcg kk kkj kl ks ksb ku ky lb lg mas mgo ml mn mr nah nb nd ne nl nn nnh no nr ny nyn om or os pa pap ps pt rof rm rwk saq seh sn so sq ss ssy st sv sw syr ta te teo tig tk tn ts ur vo wae ve vun xh xog zu">
+        <pluralRules locales="asa ast af bem bez bg bn brx ca cgg chr ckb da de dv ee el en eo es et eu fi fo fur fy gl gsw gu ha haw hy is it jgo jmc kaj kcg kk kkj kl ks ksb ku ky lb lg mas mgo ml mn mr nah nb nd ne nl nn nnh no nr ny nyn om or os pa pap ps pt rof rm rwk saq seh sn so sq ss ssy st sv sw syr ta te teo tig tk tn ts ur vo wae ve vun xh xog zu">
             <pluralRule count="one">n is 1</pluralRule>
         </pluralRules>
         <pluralRules locales="ak am bh fil tl guw hi ln mg nso ti wa">
index 4861900..3bbee94 100644 (file)
@@ -426,7 +426,7 @@ $1",
 '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 keuneulheueh',
+'newmessagesdifflinkplural' => '{{PLURAL:$1|neuubah}} keuneulheueh',
 'youhavenewmessagesmulti' => 'Droëneuh na padum boh peusan barô bak $1',
 'editsection' => 'andam',
 'editold' => 'andam',
@@ -489,6 +489,9 @@ 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.
@@ -501,9 +504,34 @@ Meunyo kön nyoë sababjih, Droëneuh kadang ka neuteumèë saboh bug lam softwa
 '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
index 9568465..3a743a7 100644 (file)
@@ -646,8 +646,8 @@ $messages = array(
 'searchbutton' => 'ابحث',
 'go' => 'اذهب',
 'searcharticle' => 'اذهب',
-'history' => 'تأريخ الصفحة',
-'history_short' => 'تأريخ',
+'history' => 'تاريخ الصفحة',
+'history_short' => 'تاريخ',
 'updatedmarker' => 'حُدِّثَت منذ زيارتي الأخيرة',
 'printableversion' => 'نسخة للطباعة',
 'permalink' => 'رابط دائم',
@@ -910,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' => 'اسم المستخدم الذي تم إدخاله مستعمل بالفعل.
@@ -2201,7 +2201,7 @@ $1',
 'shared-repo' => 'مستودع مشترك',
 'shared-repo-name-wikimediacommons' => 'ويكيميديا كومنز',
 'filepage.css' => '/* CSS المعروض هنا سيضمن في صفحات وصف الملفات، أيضا على الويكيات الأجنبية */',
-'upload-disallowed-here' => 'للأسف لا يمكنك تعديل هذه الصورة.',
+'upload-disallowed-here' => 'لا يمكنك تعديل هذه الصورة.',
 
 # File reversion
 'filerevert' => 'استرجع $1',
@@ -2278,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' => 'الصفحات التي ترتبط بصفحات توضيح',
@@ -2454,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' => 'أخف الإداريين',
@@ -2991,7 +2991,7 @@ $1',
 # Move page
 'move-page' => 'نقل $1',
 'move-page-legend' => 'نقل صفحة',
-'movepagetext' => "باستخدام  الاستمارة بالأسفل بإمكانك أن تغير اسم الصفحة، وأن تنقل تاريخها إلى لاسم الجديد.
+'movepagetext' => "باستخدام  الاستمارة بالأسفل بإمكانك أن تغير اسم الصفحة، وأن تنقل تاريخها إلى الاسم الجديد.
 العنوان القديم سيصبح تحويلة للعنوان الجديد.
 يمكنك أن تترك التحويلات التي تشير إلى العنوان الأصلي كما هي لتقوم البوتات بتحديثها تلقائياً.
 إذا اخترت أن تقوم بالتحديث يدوياً، فتأكد من عدم وجود تحويلات [[Special:DoubleRedirects|مزدوجة]] أو [[Special:BrokenRedirects|مكسورة]] وقم بتصحيحها.
@@ -3353,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|من غير  التحويلات}})',
@@ -3403,6 +3404,7 @@ $1',
 'markedaspatrollederrortext' => 'يجب عليك اختيار المراجعة التي تريد أن تشير أنها مراجعة',
 'markedaspatrollederror-noautopatrol' => 'لا يجوز لك تعليم تغييراتك الشخصية بعلامة المراجعة.',
 'markedaspatrollednotify' => 'هذا التغيير لـ $1  تم تعليمه كمراقب.',
+'markedaspatrollederrornotify' => 'لم ينجح وسم هذه النسخة بأنها مراجعة',
 
 # Patrol log
 'patrol-log-page' => 'سجل الخفر',
@@ -4254,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' => 'أدوات السبام',
 
@@ -4351,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',
@@ -4409,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 48901d5..0766055 100644 (file)
@@ -141,8 +141,10 @@ $messages = array(
 'tog-underline' => 'ܪܫܘܡ ܣܪܛܐ ܬܚܝܬ ܐܣܪܐ:',
 'tog-justify' => 'ܫܘܐ ܦܬܓܡ̈ܐ',
 'tog-hideminor' => 'ܛܫܝ ܫܘܚܠܦ̈ܐ ܙܥܘܪ̈ܐ ܒܫܘܚܠܦ̈ܐ ܚܕ̈ܬܐ',
+'tog-hidepatrolled' => 'ܛܫܝ ܫܘܚܠܦ̈ܐ ܟܪ̈ܝܟܐ ܒܫܘܚܠܦ̈ܐ ܚܕ̈ܬܐ',
+'tog-newpageshidepatrolled' => 'ܛܫܝ ܦܐܬܬ̈ܐ ܟܪ̈ܝܟܬܐ ܡܢ ܡܟܬܒܘܬܐ ܕܦܐܬܐ ܚܕܬܐ',
 'tog-extendwatchlist' => 'ܐܪܘܚ ܪ̈ܗܝܬܐ ܠܚܘܘܝܐ ܕܟܠܗܘܢ ܫܘܚܠܦ̈ܐ، ܠܐ ܚܕ̈ܬܐ ܒܠܚܘܕ',
-'tog-editondblclick' => 'ܫܚܠܦ ܦܐܬ̈ܐ ܬܪ ܢܩܪܐ ܙܘܓܢܝܐ (ܣܢܝܩ ܠ JavaScript)',
+'tog-editondblclick' => 'ܫܚܠܦ ܦܐܬ̈ܐ ܬܪ ܢܩܪܐ ܙܘܓܢܝܐ (ܣܢܝܩܬ ܠ JavaScript)',
 'tog-editsection' => 'ܡܫܟܚ ܫܘܚܠܦܐ ܕܦܘܣܩ̈ܐ ܒܐܘܪܚܐ ܕܐܝܨܘܪ̈ܐ  [ܫܚܠܦ]',
 'tog-rememberpassword' => 'ܕܟܘܪ ܥܠܠܬܝ ܥܠ ܡܦܐܬܢܐ ܗܢܐ (ܠܡܬܚܐ ܥܠܝܐ ܕ $1 {{PLURAL:$1|ܝܘܡܐ|ܝܘܡܬ̈ܐ}})',
 'tog-watchcreations' => 'ܐܘܣܦ ܦܐܬܬ̈ܐ ܕܒܪܐ ܐܢܐ ܘܠܠܦ̈ܐ ܕܐܣܩ ܐܢܐ ܠܪ̈ܗܝܬܝ',
@@ -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',
@@ -448,7 +450,7 @@ $1',
 'gotaccount' => "ܐܝܬ ܠܟ ܚܘܫܒܢܐ؟ '''$1'''.",
 'gotaccountlink' => 'ܥܘܠ',
 'userlogin-resetlink' => 'ܐܬܢܫܝܬ ܝܕ̈ܥܬܐ ܕܥܠܠܐ؟',
-'createaccountmail' => 'Ü\92Ü\9dÜ\95 Ü\92Ü\9dÜ Ü\95ܪÜ\90 Ü\90Ü Ü©Ü\9bܪÜ\98Ü¢Ü\9dÜ\90',
+'createaccountmail' => 'Ü\90ܦܠÜ\9a Ü¡Ü Ü¬Ü\90 Ü\95ܥܠܠÜ\90 Ü\99Ü\92ܢܢÜ\9dܬÜ\90 Ü\98Ü«Ü\95ܪ Ü Ü\97 Ü¥Ü  Ü\92Ü\9dÜ Ü\95ܪÜ\90 Ü\90Ü Ü©Ü\9bܪÜ\98Ü¢Ü\9dÜ\90 Ü¬Ü\98Ü\9aÜ¡Ü\90 Ü Ü¬Ü\9aܬ',
 'createaccountreason' => 'ܥܠܬܐ',
 'badretype' => 'ܡܠܬܐ ܕܥܠܠܐ ܟܬܒܬ ܐܢܬ ܠܐ ܐܘܝܢܬܐ.',
 'userexists' => 'ܫܡܐ ܕܡܦܠܚܢܐ ܕܐܥܠܬ ܫܩܝܠܐ ܐܝܬܘܗܝ.
@@ -747,9 +749,9 @@ $1',
 'prefs-files' => 'ܠܦܦ̈ܐ',
 'prefs-emailconfirm-label' => 'ܫܘܪܪܐ ܕܒܝܠܕܪܐ ܐܠܩܛܪܘܢܝܐ:',
 'youremail' => 'ܒܝܠܕܪܐ ܐܠܩܛܪܘܢܝܐ:',
-'username' => 'ܫܡܐ ܕܡܦܠܚܢܐ:',
-'uid' => 'ܗܝܝܘܬܐ ܕܡܦܠܚܢܐ:',
-'prefs-memberingroups' => 'ܗܕܡܐ ܕ{{PLURAL:$1|ܟܢܘܫܬܐ|ܟܢܘܫܬ̈ܐ}}:',
+'username' => '{{GENDER:$1|ܫܡܐ ܕܡܦܠܚܢܐ|ܫܡܐ ܕܡܦܠܚܢܬܐ}}:',
+'uid' => 'ܗܝܝܘܬܐ ܕ{{GENDER:$1|ܡܦܠܚܢܐ|ܡܦܠܚܢܬܐ}}:',
+'prefs-memberingroups' => '{{GENDER:$2|ܗܕܡܐ}} ܕ{{PLURAL:$1|ܟܢܘܫܬܐ|ܟܢܘܫܬ̈ܐ}}:',
 'prefs-registration' => 'ܙܒܢܐ ܕܣܘܓܠܐ:',
 'yourrealname' => 'ܫܡܐ ܫܪܝܪܐ:',
 'yourlanguage' => 'ܠܫܢܐ:',
@@ -1096,6 +1098,7 @@ $1',
 'movethispage' => 'ܫܢܝ ܦܐܬܐ ܗܕܐ',
 'notargettitle' => 'ܕܠܐ ܢܘܦܐ',
 'nopagetitle' => 'ܠܝܬ ܗܟܘܬ ܦܐܬܐ ܕܢܘܦܐ',
+'nopagetext' => 'ܦܐܬܐ ܕܢܘܦܐ ܕܬܬܚܡܬ ܠܝܬ ܠܗ ܐܝܬܘܬܐ.',
 'pager-newer-n' => '{{PLURAL:$1|1 1 ܚܕܬܐ|$1 ܚܕ̈ܬܐ}}',
 'pager-older-n' => '{{PLURAL:$1|1 ܥܬܝܩܐ|$1 ܥܬܝܩ̈ܐ}}',
 'suppress' => 'ܚܝܘܪܐ',
@@ -1110,6 +1113,8 @@ $1',
 'speciallogtitlelabel' => 'ܢܘܦܐ (ܟܘܢܝܐ ܐܘ ܡܦܠܚܢܐ):',
 'log' => 'ܣܓܠ̈ܐ',
 'all-logs-page' => 'ܟܠ ܣܓܠ̈ܐ ܓܘܢܝ̈ܐ',
+'alllogstext' => 'ܓܠܚܐ ܟܠܢܝܐ ܠܟܠ ܣܓܠ̈ܐ ܡܪ ܐܝܬܘܬܐ ܒ{{SITENAME}}.
+ܡܨܬ ܕܬܙܥܪ ܠܦܠܛܐ ܒܓܒܝܬܐ ܕܐܕܫܐ ܕܣܓܠܐ ܐܘ ܫܡܐ ܕܡܦܠܚܢܐ (ܪܓܫܬܢܐ ܠܐܕܫܐ ܕܐܬܘܬܐ) ܐܘ ܦܐܬܐ ܬܘܥܒܕܬܐ (ܐܦ ܪܓܫܬܢܐ ܠܐܕܫܐ ܕܐܬܘܬܐ).',
 'logempty' => 'ܠܝܬ ܡܠܘܐ̈ܐ ܠܐ̈ܝܡܐ ܒܣܓܠܐ ܗܢܐ.',
 'log-title-wildcard' => 'ܒܨܝ ܥܠ ܟܘܢܝ̈ܐ ܕܫܪܝܢ ܥܡ ܟܬܒܬܐ ܗܕܐ',
 'showhideselectedlogentries' => 'ܚܘܝ/ܛܫܝ ܣܓܠ̈ܐ ܕܥܠܠܐ ܓܒܝ̈ܐ',
@@ -1160,7 +1165,7 @@ $1',
 
 # Special:ActiveUsers
 'activeusers' => 'ܡܟܬܒܘܬܐ ܕܗܕ̈ܡܐ ܙܪ̄ܝܙܐ',
-'activeusers-count' => '$1 {{PLURAL:$1|Ü«Ü\98Ü\9aܠܦÜ\90 Ü\9aÜ\95ܬÜ\90|Ü«Ü\98Ü\9aܠܦÌ\88Ü\90 Ü\9aÜ\95Ì\88ܬܐ}} ܒ {{PLURAL:$3|ܝܘܡܐ ܐܚܪܝܐ|$3 ܝܘܡܬ̈ܐ ܐܚܪ̈ܝܐ}}',
+'activeusers-count' => '$1 {{PLURAL:$1|Ü¥Ü\92Ü\95Ü\90|Ü¥Ü\92Ü\95Ì\88ܐ}} ܒ {{PLURAL:$3|ܝܘܡܐ ܐܚܪܝܐ|$3 ܝܘܡܬ̈ܐ ܐܚܪ̈ܝܐ}}',
 'activeusers-from' => 'ܚܘܝ ܡܦܠܚܢ̈ܐ ܕܫܪܐ ܥܡ:',
 'activeusers-hidebots' => 'ܛܫܝ ܒܘܬ̈ܐ (bots)',
 'activeusers-hidesysops' => 'ܛܫܝ ܡܕܒܪ̈ܢܐ',
@@ -1202,7 +1207,7 @@ $1',
 'usermessage-editor' => 'ܡܫܕܪܢܐ ܕܛܟܣܐ',
 
 # Watchlist
-'watchlist' => 'ܪÌ\88Ü\97Ü\9dܬÜ\9d',
+'watchlist' => 'ܪÌ\88Ü\97Ü\9dܬÜ\90',
 'mywatchlist' => 'ܪ̈ܗܝܬܐ',
 'watchlistfor2' => 'ܕ $1 $2',
 'nowatchlist' => 'ܠܝܬ ܠܟ ܡܕܡ ܒܪ̈ܗܝܬܐ ܕܝܠܟ',
@@ -1210,8 +1215,8 @@ $1',
 'watchnologin' => 'ܠܝܬܝܟ ܥܠܝܠܐ',
 'watchnologintext' => 'ܐܠܨܐ ܕܬܗܘܐ [[Special:UserLogin|ܥܠܝܠܐ]] ܠܫܚܠܦܬܐ ܕܪ̈ܗܝܬܟ.',
 'addwatch' => 'ܐܘܣܦ ܥܠ ܪ̈ܗܝܬܝ',
-'addedwatchtext' => "ܦܐܬܐ ܕ\"[[:\$1]]\" ܐܬܬܘܣܦܬ ܒ[[Special:Watchlist|ܪ̈ܗܝܬܟ]].
\90Ü\9dÜ¢Ü\90 Ü«Ü\98Ü\9aܠܦÜ\90 Ü Ü¦Ü\90ܬÜ\90 Ü\97Ü\95Ü\90 Ü\92Ü\95ܥܬÜ\9dÜ\95 Ü¬Ü¬Ü\93Ü Ü\9a Ü¥Ü¡ Ü¦Ü\90ܬÜ\90 Ü\95Ü¡Ü¡Ü Ü Ü\90 Ü\95Ü\9dÜ Ü\97 Ü¬Ü¡Ü¢, Ü\98ܦÜ\90ܬÜ\90 Ü¬Ü\97Ü\98Ü\90 Ü\92ܣܪÜ\9bÜ\90 '''Ü\9aÜ Ü\9dÜ¡Ü\90''' Ü\92ܦÜ\90ܬÜ\90 Ü\95[[Special:RecentChanges|Ü«Ü\98Ü\9aܠܦÌ\88Ü\90 Ü\9aÜ\95Ì\88ܬÜ\90]] Ü Ü¦Ü«Ü\9bܬÜ\90 Ü\95Ü«Ü\9fÜ\9aܬÜ\97.",
+'addedwatchtext' => 'ܦܐܬܐ ܕ"[[:$1]]" ܐܬܬܘܣܦܬ ܠ[[Special:Watchlist|ܪ̈ܗܝܬܟ]].
\90Ü\9dÜ¢Ü\90 Ü«Ü\98Ü\9aܠܦÜ\90 Ü¥Ü  Ü¦Ü\90ܬÜ\90 Ü\97Ü\95Ü\90 Ü\92Ü\95ܥܬÜ\9dÜ\95 Ü¬Ü¬Ü\93Ü Ü\9a Ü¥Ü¡ Ü¦Ü\90ܬÜ\90 Ü\95Ü¡Ü¡Ü Ü Ü\90 Ü\95Ü\9dÜ Ü\97 Ü¬Ü¡Ü¢.',
 'removewatch' => 'ܫܩܘܠ ܡܢ ܪ̈ܗܝܬܝ',
 'removedwatchtext' => 'ܦܐܬܐ ܕ "[[:$1]]" ܐܫܬܩܠܬ ܡܢ [[Special:Watchlist|ܪ̈ܗܝܬܟ]].',
 'watch' => 'ܪܗܝ',
@@ -1274,10 +1279,11 @@ $1',
 'protect-legend' => 'ܫܪܪ ܢܘܛܪܐ',
 'protectcomment' => 'ܥܠܬܐ:',
 'protect-default' => 'ܦܣܣܐ ܠܟܠ ܡܦܠܚܢ̈ܐ',
-'protect-fallback' => 'Ü\92Ü¥Ü\9d "$1" Ü¦Ü£Ü£Ü\90',
-'protect-level-autoconfirmed' => 'Ü\9aܪÜ\98Ü¡ Ü¡Ü¦Ü Ü\9aÜ¢Ì\88Ü\90 Ü\9aÜ\95Ì\88ܬÜ\90 Ü\98Ü Ü\90 Ü¥Ü Ü\9dÜ Ì\88Ü\90',
-'protect-level-sysop' => 'ܡܕܒܪ̈ܢܐ ܒܠܚܘܕ',
+'protect-fallback' => 'ܦܣܣ Ü Ü¡Ü¦Ü Ü\9aÜ¢Ì\88Ü\90 Ü¥Ü¡ "$1" Ü¦Ü£Ü£Ü\90 Ü\92Ü Ü\9aÜ\98Ü\95',
+'protect-level-autoconfirmed' => 'ܦܣܣ Ü Ü¡Ü¦Ü Ü\9aÜ¢Ì\88Ü\90 Ü\9aܬÜ\9dܬÌ\88Ü\90 Ü\9dܬÜ\90Ü\9dܬ Ü\92Ü Ü\9aÜ\98Ü\95',
+'protect-level-sysop' => 'ܦܣܣ Ü Ü¡Ü\95Ü\92ܪÌ\88Ü¢Ü\90 Ü\92Ü Ü\9aÜ\98Ü\95',
 'protect-expiring' => 'ܬܦܪܘܩ ܒ $1 (UTC)',
+'protect-expiring-local' => 'ܬܦܪܘܩ ܒ $1',
 'protect-expiry-indefinite' => 'ܠܥܠܡ',
 'protect-othertime' => 'ܥܕܢܐ ܐܚܪܢܐ:',
 'protect-othertime-op' => 'ܥܕܢܐ ܐܚܪܢܐ',
@@ -1559,10 +1565,11 @@ Do you want to change the settings?',
 'pageinfo-protect-cascading-yes' => 'ܐܝܢ',
 
 # Patrolling
-'markaspatrolleddiff' => 'ܫܘܕܥ ܐܝܟ ܟܪܝܟܐ',
+'markaspatrolleddiff' => 'Ü«Ü\98Ü\95Ü¥ Ü\90Ü\9dÜ\9f Ü\9fܪÜ\9dÜ\9fܬÜ\90',
 'markaspatrolledtext' => 'ܫܘܕܥ ܦܐܬܐ ܗܕܐ ܐܝܟ ܟܪܝܟܬܐ',
-'markedaspatrolled' => 'ܫܘܕܥܬ ܐܝܟ ܟܪܝܟܐ',
+'markedaspatrolled' => 'Ü«Ü\98Ü\95ܥܬ Ü\90Ü\9dÜ\9f Ü\9fܪÜ\9dÜ\9fܬÜ\90',
 'markedaspatrollednotify' => 'ܫܘܚܠܦܐ ܗܢܐ ܥܠ $1 ܐܫܬܘܕܥ ܐܝܟ ܟܪܝܟܐ.',
+'markedaspatrollederrornotify' => 'ܠܐ ܐܬܢܨܚ ܫܘܘܕܥܐ ܐܝܟ ܟܪܝܟܬܐ',
 
 # Patrol log
 'patrol-log-page' => 'ܣܓܠܐ ܕܟܪܟܐ',
@@ -1674,6 +1681,8 @@ $1',
 'exif-gpsdirection-t' => 'ܨܘܒܐ ܬܪܝܨܐ',
 'exif-gpsdirection-m' => 'ܨܘܒܐ ܡܓܢܛܝܣܝܐ',
 
+'exif-dc-contributor' => 'ܫܘܬܦܢ̈ܐ',
+
 # 'all' in various places, this might be different for inflected languages
 'watchlistall2' => 'ܟܠ',
 'namespacesall' => 'ܟܠ',
@@ -1766,7 +1775,7 @@ $1',
 'specialpages-group-highuse' => 'ܦܐܬܬ̈ܐ ܕܡܬܚܫܚܢܘܬܐ ܥܠܝܬܐ',
 'specialpages-group-pages' => 'ܡܟܬܒܘܬ̈ܐ ܕܦܐܬܬ̈ܐ',
 'specialpages-group-pagetools' => 'ܡܐܢ̈ܐ ܕܦܐܬܐ',
-'specialpages-group-wiki' => 'Ü\93Ü Ü\9dܬÌ\88Ü\90 Ü\98Ü¡Ü\90Ü¢Ì\88Ü\90 Ü\95Ü\98Ü\9dÜ©Ü\9d',
+'specialpages-group-wiki' => 'Ü Ü\9dܬÌ\88Ü\90 Ü\98Ü¡Ü\90Ü¢Ì\88Ü\90',
 'specialpages-group-redirects' => 'ܨܘܝܒܐ ܕܦܐܬܐ ܕܝܠܢܝܬܐ',
 
 # Special:BlankPage
@@ -1774,7 +1783,10 @@ $1',
 
 # Special:Tags
 'tags' => 'ܚܬ̈ܡܐ ܕܫܘܚܠܦܐ ܬܪܝܨܐ',
+'tag-filter' => 'ܡܨܦܝܢܝܬܐ ܕ[[Special:Tags|ܪܘܫܡܐ]]:',
 'tag-filter-submit' => 'ܡܨܦܝܢܝܬܐ',
+'tags-title' => 'ܪ̈ܘܫܡܐ',
+'tags-tag' => 'ܫܡܐ ܕܪܘܫܡܐ',
 'tags-edit' => 'ܫܚܠܦ',
 'tags-hitcount' => '$1 {{PLURAL:$1|ܫܘܚܠܦܐ|ܫܘܚܠܦ̈ܐ}}',
 
@@ -1798,6 +1810,8 @@ $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' => '$1 ܫܘܕܥ ܬܢܝܬܐ $4 ܕܦܐܬܐ $3 ܟܪܝܟܬܐ',
+'logentry-patrol-patrol-auto' => '$1 ܝܬܐܝܬ ܫܘܕܥ ܬܢܝܬܐ $4 ܕܦܐܬܐ $3 ܟܪܝܟܬܐ',
 'logentry-newusers-newusers' => 'ܚܘܫܒܢܐ ܕܡܦܠܚܢܐ $1 ܐܬܒܪܐ',
 'logentry-newusers-create' => 'ܚܘܫܒܢܐ ܕܡܦܠܚܢܐ $1 ܐܬܒܪܐ',
 'logentry-newusers-create2' => 'ܚܘܫܒܢܐ ܕܡܦܠܚܢܐ $3 ܐܬܒܪܐ ܒܝܕ $1',
index ad0b1b0..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',
@@ -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 85f4ee5..e910798 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(
@@ -329,7 +331,7 @@ $1',
 'edithelp' => 'Даведка рэдактарскага акна',
 'edithelppage' => 'Help:Праўка',
 'helppage' => 'Help:Змест',
-'mainpage' => 'Ð\9fеÑ\80Ñ\88ая старонка',
+'mainpage' => 'Ð\93алоÑ\9eная старонка',
 'mainpage-description' => 'Першая старонка',
 'policy-url' => 'Project:Арганізацыйная палітыка',
 'portal' => 'Супольнасць',
index 4c8b054..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' => 'усе',
@@ -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|звычайная|звычайныя|звычайных}})',
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 932723a..36a1df5 100644 (file)
@@ -229,7 +229,7 @@ $messages = array(
 'tog-externaldiff' => "Utilitza per defecte un altre visualitzador de diferències (opció per a experts, requereix la configuració adient de l'ordinador, [//www.mediawiki.org/wiki/Manual:External_editors consulteu-ho al manual])",
 'tog-showjumplinks' => "Habilita els enllaços de dreceres d'accessibilitat",
 'tog-uselivepreview' => 'Utilitza la previsualització automàtica (cal JavaScript) (experimental)',
-'tog-forceeditsummary' => "Avisa'm en introduir un camp de resum en blanc",
+'tog-forceeditsummary' => "Avisa'm en deixar el resum de la modificació en blanc",
 'tog-watchlisthideown' => 'Amaga les meues edicions de la llista de seguiment',
 'tog-watchlisthidebots' => 'Amaga de la llista de seguiment les edicions fetes per usuaris bots',
 'tog-watchlisthideminor' => 'Amaga les edicions menors de la llista de seguiment',
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 45bbac7..b5a92a5 100644 (file)
@@ -1389,7 +1389,7 @@ Podrobnosti mohou být uvedeny v [{{fullurl:{{#Special:Log}}/delete|page={{FULLP
 'search-interwiki-default' => 'Výsledky z $1:',
 'search-interwiki-more' => '(více)',
 'search-relatedarticle' => 'Související',
-'mwsuggest-disable' => 'Vypnout ajaxové napovídání',
+'mwsuggest-disable' => 'Vypnout našeptávač při hledání',
 'searcheverything-enable' => 'Hledat ve všech jmenných prostorech',
 'searchrelated' => 'související',
 'searchall' => 'vše',
@@ -3148,6 +3148,7 @@ Uložte jej na svůj disk a nahrajte ho sem.',
 'pageinfo-robot-noindex' => 'Neindexovatelná',
 'pageinfo-views' => 'Počet zobrazení',
 'pageinfo-watchers' => 'Počet sledujících',
+'pageinfo-few-watchers' => 'Méně než $1 {{PLURAL:$1|sledující|sledující|sledujících}}',
 'pageinfo-redirects-name' => 'Přesměrování na tuto stránku',
 'pageinfo-subpages-name' => 'Podstránky této stránky',
 'pageinfo-subpages-value' => '$1 ($2 {{PLURAL:$2|přesměrování}}; $3 {{PLURAL:$3|nepřesměrování}})',
index ef94fe1..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. 
@@ -871,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',
@@ -1133,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',
@@ -1627,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.",
@@ -2136,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',
@@ -2555,7 +2563,7 @@ Os ydych yn dewis peidio â gwneud hyn, gwiriwch [[Special:DoubleRedirects|dudal
 [[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 tudalen a'r enw newydd ar gael yn barod, oni bai ei bod hi'n dudalen ailgyfeirio ac nad oes hanes golygu ganddi.
+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!'''
@@ -2872,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}})',
@@ -2941,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.',
@@ -3571,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.
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 53e87ee..bd132c3 100644 (file)
@@ -13,6 +13,7 @@
  * @author Church of emacs
  * @author DaSch
  * @author Das Schäfchen
+ * @author Dschwen
  * @author Duesentrieb
  * @author Filzstift
  * @author Geitost
@@ -1434,7 +1435,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 +3204,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',
@@ -3535,7 +3537,7 @@ Weitere werden standardmäßig nicht angezeigt.
 'exif-compression-4' => 'CCITT Gruppe 4 Faxcodierung',
 
 'exif-copyrighted-true' => 'Geschützt',
-'exif-copyrighted-false' => 'Gemeinfrei',
+'exif-copyrighted-false' => 'Copyright Flag nicht gesetzt',
 
 'exif-unknowndate' => 'Unbekanntes Datum',
 
index 3800fef..72d3adf 100644 (file)
@@ -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',
@@ -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..76cae46 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ś.'''
@@ -1161,7 +1162,7 @@ Drobnostki móžoš w [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}
 'search-interwiki-default' => '$1 wuslědki:',
 'search-interwiki-more' => '(wěcej)',
 'search-relatedarticle' => 'swójźbne',
-'mwsuggest-disable' => 'Naraźenja pśez AJAX znjemóžniś',
+'mwsuggest-disable' => 'Pytańske naraźenja znjemóžniś',
 'searcheverything-enable' => 'We wšych mjenjowych rumach pytaś',
 'searchrelated' => 'swójźbne',
 'searchall' => 'wše',
@@ -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;
@@ -2882,6 +2883,7 @@ W zespominanju dajo se pśicyna pódaś.',
 'pageinfo-robot-noindex' => 'Njeindeksěrujobny',
 'pageinfo-views' => 'Licba zwobraznjenjow',
 'pageinfo-watchers' => 'Licba  wobglědowarjow boka',
+'pageinfo-few-watchers' => 'Mjenjej ako $1 {{PLURAL:$1|wobglědowaŕ|wobglědowarja|wobglědowarje|wobglědowarjow}}',
 'pageinfo-redirects-name' => 'Dalejpósrědnjenja k toś tomu bokoju',
 'pageinfo-redirects-value' => '$1',
 'pageinfo-subpages-name' => 'Pódboki toś togo boka',
@@ -3651,7 +3653,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 +3750,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 +3809,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 8c8289e..a7dafad 100644 (file)
@@ -63,6 +63,10 @@ $specialPageAliases = array(
 $messages = array(
 # User preference toggles
 'tog-hideminor' => 'ކުދި އުނި އިތުރުތައް އެންމެފަހުގެ ބަދަލުތަކުގެ ލިސްޓުން ފޮރުއްވަވާ',
+'tog-watchlisthideown' => 'މަގޭ ނަޒަރުން މަގޭ ހިއްސާ ފޮރުއްވާ',
+'tog-watchlisthidebots' => 'މަގޭ ނަޒަރުން ބޮޓުންގެ ހިއްސާ ފޮރުއްވާ',
+'tog-watchlisthideminor' => 'މަގޭ ނަޒަރުން ކުދި އުނިއިތުރުތައް ފޮރުއްވާ',
+'tog-watchlisthideliu' => 'މަގޭ ނަޒަރުން ވަދެފައިވާ މެމްބަރުންގެ އުނިއުތުރުތައް ފޮރުއްވާ',
 'tog-ccmeonemails' => 'އަޅުގަނޑު އެހެން މެމްބަރުންނަށް ފޮނުވާ އީމެއިލްގެ ނަކަލެއް އަޅުގަނޑަށް ފޮނުވާ',
 'tog-showhiddencats' => 'ފޮރުވިފައިވާ ޤިސްމުތައް ދައްކަވާ',
 
@@ -255,6 +259,10 @@ $1',
 'youhavenewmessages' => 'ތިޔަބޭފުޅާއަށް $1 ($2)',
 'newmessageslink' => 'އައު މެސެޖުތައް',
 'newmessagesdifflink' => 'އެންމެ ފަހުގެ ބަދަލު',
+'youhavenewmessagesfromusers' => 'ތިބޭފުޅާއަށް {{PLURAL:$3|މެމްބަރެއް|$3 މެމްބަރުން}} $1 ފޮނުއްވާފައިވެއެވެ. ($2)',
+'youhavenewmessagesmanyusers' => 'ތިބޭފުޅާއަށް ގިނަ މެމްބަރުން $1 ފޮނުއްވާފައިވެއެވެ. ($2)',
+'newmessageslinkplural' => '{{PLURAL:$1|އާ މެސެޖެއް|މެސެޖުތައް}}',
+'newmessagesdifflinkplural' => 'ފަހު {{PLURAL:$1|ބަދަލު|ބަދަލުތައް}}',
 'editsection' => 'އުނިއިތުރު ގެންނަވާ',
 'editold' => 'އުނިއިތުރު ގެންނަވާ',
 'viewsourceold' => 'މަސްދަރު ބައްލަވާ',
@@ -399,8 +407,15 @@ $1',
 'accmailtitle' => 'ސިއްރުބަސް ފޮނުވިއްޖެ.',
 'accmailtext' => '"$1" އަށްޓަކައިވާ ސިއްރު ބަސް $2 އަށް ވަނީ ފޮނުވިފައި',
 'newarticle' => '(އައު)',
-'noarticletext' => 'މި ޞަފްޙާގައި އެއްވެސް ލިޔުމެއް ނުވެއެވެ. ތިޔަބޭފުޅާއަށް މި ނަން [[Special:Search/{{PAGENAME}}|އެހެން ޞަފްޙާތަކުން ހޯއްދެވިދާނެއެވެ]]. ނުވަތަ <span class="plainlinks">[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} މިއާ ގުޅޭ ލޮގްތައް ހޯއްދެވިދާނެއެވެ].
-[{{fullurl:{{FULLPAGENAME}}|action=edit}} ނުވަތަ މި ޞަފްޙާއަށް އުނިއިތުރު ގެނެވިދާނެއެވެ].</span>.',
+'newarticletext' => "<div style=\"border:1px solid black;\">
+<big>'''ވިކިޕީޑިއާގައި އަދި މިހާތަނަށް ތިނަމުންވާ މަޒުމޫނެއް އެކުލެވިފައިނުވެއެވެ.'''</big>
+* ތިޔަ ވަޑައިގެންނެވި ޞަފްޙާގައި އެއްވެސް ލިޔުމެއް އެކުލެވިފައި ނުވެއެވެ.
+*މި ޞަފްޙާއަށް ތިބޭފުޅާއަށް ވަޑައިގަނެވުނީ އޮޅުމަކުން ކަމަށް ވާނަމަ ކޮމްޕިޔުޓަރުގެ `ވެބް ބްރޯޒަރ` ގެ ''ފަހަތް'' ފިތައް އޮބާލައްވާށެވެ. އޭރުން އެންމެ ފަހުން ހުންނެވި ޞަފްޙާ އަށް ވަޑައިގަނެވޭނެއެވެ.
+* މަޒްމޫނެއް ފެއްޓެވުމަށް ތިރީގައި ވާ ފޮށީގައި ލިޔުއްވުމަށް ފަހު މަޒުމޫނުގެ ނަމޫނާ ބެއްލެވުމަށް ފަހު ކުށެއްވާނަމަ ރަނގަޅު ކުރައްވާފައި ފޮށީގެ ތިރީގައިވާ '''ޞަފްޙާ ރައްކާކުރައްވާ'''އަށް ފިއްތަވާ ލައްވަވާ.
+* އިތުރު އެހީ ބޭނުންފުޅު ނަމަ [[{{MediaWiki:Helppage}}|އެހީ ޞަފްހާއަށް]] ވަޑައިގަންނަވާށެވެ.
+</div>",
+'noarticletext' => 'މި ޞަފްޙާގައި އެއްވެސް ލިޔުމެއް ނުވެއެވެ. ތިޔަބޭފުޅާއަށް މި ނަން [[Special:Search/{{PAGENAME}}|އެހެން ޞަފްޙާއަކުން ހޯއްދެވިދާނެއެވެ]]. ނުވަތަ <span class="plainlinks">[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} މިއާ ގުޅޭ ލޮގްތައް ހޯއްދެވިދާނެއެވެ].
+[{{fullurl:{{FULLPAGENAME}}|action=edit}} ނުވަތަ މި ޞަފްޙާއަށް އުނިއިތުރު ގެނެވިދާނެއެވެ].</span>',
 'previewnote' => "'''މިއީ ހަމައެކަނި ނަމޫނާ އެކެވެ.'''
 އަދި ތިބޭފުޅާގެ ބަދަލުތައް ރައްކާނުކުރެވެއެވެ!",
 'editing' => '$1 އަށް އުނިއިތުރު ގެންނަނީ',
@@ -423,6 +438,7 @@ $1',
 ފޮހެލުމުގެ އަދި ނަން ބަދަލުކުރުމުގެ ލޮގް ތިރީގައިވަނީއެވެ.',
 
 # History pages
+'viewpagelogs' => 'މިޞަފްޙާގެ ލޮގުތައް ބައްލަވާ',
 'currentrev' => 'އެންމެފަހުން ގެނެވުނު ބަދަލު',
 'currentrev-asof' => 'އެންމެ ފަހުން ގެނެވުނު ބަދަލު $1',
 'revisionasof' => '$1ގެ ނުސްހާ',
@@ -666,7 +682,7 @@ Also see [[Special:WantedCategories|wanted categories]].',
 'blanknamespace' => '(މައި)',
 
 # Contributions
-'contributions' => 'މެންބަރު ގެ ހިއްސާ',
+'contributions' => '{{GENDER:$1|މެމްބަރުގެ}} ހިއްސާ',
 'mycontris' => 'މަގޭ ހިއްސާ',
 
 'sp-contributions-talk' => 'ވާހަކަ',
@@ -762,6 +778,7 @@ Also see [[Special:WantedCategories|wanted categories]].',
 'tooltip-ca-nstab-category' => 'ޤިސްމު ޞަފްޙާ ބައްލަވާ',
 'tooltip-save' => 'ބަދަލުތައް ރައްކާކުރައްވާ',
 'tooltip-preview' => 'ބަދަލުތައް ދައްކަވާ، ރައްކާކުރެއްވުމުގެ ކުރިން މި ބޭނުންކުރައްވާ!',
+'tooltip-watch' => 'މިޞަފްޙާއަށް ނަޒަރުބަހައްޓަވާ',
 'tooltip-rollback' => '"ކުރީގެ ނުސްހާ އަކަށް ބަދަލުކުރައްވާ" އިން މި ޞަފްޙާއަށް އެންމެ ފަހުން އުނިއިތުރު ގެންނެވި މެމްބަރުގެ އުނިއިތުރު(އުނިއިތުރުތައް) ފޮހެލެވޭނެއެވެ.',
 'tooltip-summary' => 'ކުރު ޚުލާސާއެއް ލިޔުއްވާ',
 
index 8da6463..62a5b27 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' => 'Αλλαγή κωδικού πρόσβασης',
@@ -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' => 'Επόμενες',
@@ -2235,7 +2237,7 @@ $1',
 'linksearch-ok' => 'Αναζήτηση',
 'linksearch-text' => 'Μπορούν να χρησιμοποιηθούν χαρακτήρες μπαλαντέρ όπως "*.wikipedia.org". 
 Χρειάζεται τουλάχιστον μια κατάληξη ανωτάτου επιπέδου, για παράδειγμα "*.org".<br />
-Υποστηριζόμενα πρωτόκολλα: <code>$1</code> (αν δεν οριστεί πρωτόκολλο η προεπιλογή είναι http://).',
+Υποστηριζόμενα {{PLURAL:$2|πρωτόκολλο|πρωτόκολλα}}: <code>$1</code> (αν δεν οριστεί πρωτόκολλο η προεπιλογή είναι http://).',
 'linksearch-line' => 'Η $1 συνδεδεμένη από την $2',
 'linksearch-error' => 'Λέξεις-μπαλαντέρ μπορεί να εμφανιστούν μόνο στην αρχή τού ονόματος ιστοτόπου (hostname).',
 
@@ -2460,6 +2462,8 @@ $UNWATCHURL
 'prot_1movedto2' => 'Η [[$1]] μετακινήθηκε στη θέση [[$2]]',
 'protect-badnamespace-title' => 'Μη-προστατευόμενη ομάδα σελίδων',
 'protect-badnamespace-text' => 'Οι  σελίδες σε αυτόν τον ονοματοχώρο δεν μπορούν να κλειδωθούν.',
+'protect-norestrictiontypes-text' => 'Αυτή η σελίδα δεν μπορούν να προστατευθούν δεδομένου ότι δεν υπάρχουν διαθέσιμοι τύποι κλειδώματος.',
+'protect-norestrictiontypes-title' => 'Μη-προστατευόμενη σελίδα',
 'protect-legend' => 'Επιβεβαίωση κλειδώματος',
 'protectcomment' => 'Αιτία:',
 'protectexpiry' => 'Λήξη',
@@ -2566,11 +2570,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 +2610,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 +2778,8 @@ $1',
 Αν επιλέξετε να μην ενημερωθούν αυτόματα, μην ξεχάσετε να ελέγξετε για [[Special:DoubleRedirects|διπλές]] ή [[Special:BrokenRedirects|κατεστραμμένες ανακατευθύνσεις]].
 Είναι δική σας ευθύνη να επιβεβαιώσετε ότι οι σύνδεσμοι εξακολουθούν να δείχνουν προς τη σωστή κατεύθυνση.
 
-Λάβετε υπόψιν σας ότι η σελίδα '''δεν''' θα μετακινηθεί αν υπάρχει ήδη μια άλλη σελίδα υπό το νέο τίτλο, εκτός αν η σελίδα αυτή είναι κενή ή ανακατεύθυνση και δεν έχει ιστορικό επεξεργασίας.
+Λάβετε υπόψιν σας ότι η σελίδα '''δεν''' θα μετακινηθεί αν υπάρχει ήδη μια άλλη σελίδα υπό το νέο τίτλο, εκτός αν η σελίδα αυτή είναι ανακατεύθυνση και δεν έχει ιστορικό επεξεργασίας.
+
 Αυτό σημαίνει ότι σε περίπτωση λάθους μπορείτε να μετονομάσετε ξανά μια σελίδα δίνοντας της την αρχική της ονομασία αλλά δεν μπορείτε να αντικαταστήσετε μια υπάρχουσα σελίδα.
 
 '''ΠΡΟΣΟΧΗ!'''
@@ -2838,8 +2843,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 +2925,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 +3137,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 +3222,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' => 'μόλις τώρα',
 
@@ -4026,6 +4034,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 c7ceb47..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',
@@ -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 0fb1a80..4e6b235 100644 (file)
@@ -362,7 +362,7 @@ $linkTrail = '/^([a-záéíóúñ]+)(.*)$/sDu';
 
 $messages = array(
 # User preference toggles
-'tog-underline' => 'Subrayar enlaces:',
+'tog-underline' => 'Subrayar los enlaces:',
 'tog-justify' => 'Justificar los párrafos',
 'tog-hideminor' => 'Ocultar las ediciones menores en los cambios recientes',
 'tog-hidepatrolled' => 'Ocultar las ediciones patrulladas en los cambios recientes',
@@ -410,14 +410,14 @@ $messages = array(
 
 'underline-always' => 'Siempre',
 'underline-never' => 'Nunca',
-'underline-default' => 'Aspecto (skin) o navegador predeterminado',
+'underline-default' => 'Aspecto (skin) o valor predeterminado del navegador',
 
 # Font style option in Special:Preferences
 'editfont-style' => 'Estilo de tipografía del área de edición:',
 'editfont-default' => 'Predeterminado del navegador',
 'editfont-monospace' => 'Tipografía monoespaciada',
-'editfont-sansserif' => 'Tipografía sans-serif',
-'editfont-serif' => 'Tipografía serif',
+'editfont-sansserif' => 'Tipo de letra de palo seco',
+'editfont-serif' => 'Tipo de letra con serifas',
 
 # Dates
 'sunday' => 'domingo',
@@ -630,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',
@@ -784,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',
@@ -796,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.
@@ -1406,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',
@@ -1503,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',
@@ -2005,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',
@@ -2338,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',
@@ -2534,9 +2534,9 @@ 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' => 'Permite sólo a usuarios con el permiso «$1»',
-'protect-level-autoconfirmed' => 'Permitir solo usuarios autoconfirmados',
-'protect-level-sysop' => 'Permitir solo administradores',
+'protect-fallback' => 'Solo permitir usuarios con el permiso «$1»',
+'protect-level-autoconfirmed' => 'Solo permitir usuarios autoconfirmados',
+'protect-level-sysop' => 'Solo permitir administradores',
 'protect-summary-cascade' => 'en cascada',
 'protect-expiring' => 'caduca el $1 (UTC)',
 'protect-expiring-local' => 'caduca el $1',
@@ -2824,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]].
@@ -3185,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',
index d3e5855..41654e5 100644 (file)
@@ -873,7 +873,7 @@ $2',
 'gotaccount' => 'حساب کاربری دارید؟ $1.',
 'gotaccountlink' => 'به سامانه وارد شوید',
 'userlogin-resetlink' => 'جزئیات ورود را فراموش کرده‌اید؟',
-'createaccountmail' => 'با Ø±Ø§Û\8cاÙ\86اÙ\85Ù\87',
+'createaccountmail' => 'استÙ\81ادÙ\87 Ø§Ø² Ø±Ù\85ز Ø¹Ø¨Ù\88ر Ù\85Ù\88Ù\82ت ØªØµØ§Ø¯Ù\81Û\8c Ù\88 Ø§Ø±Ø³Ø§Ù\84 Ø¢Ù\86 Ø¨Ù\87 Ø¢Ø¯Ø±Ø³ Ø§Û\8cÙ\85Û\8cÙ\84 Ù\85شخص Ø´Ø¯Ù\87 Ø¯Ø± Ø²Û\8cر',
 'createaccountreason' => 'دلیل:',
 'badretype' => 'گذرواژه‌هایی که وارد کرده‌اید یکسان نیستند.',
 'userexists' => 'نام کاربری‌ای که وارد کردید قبلاً استفاده شده‌است.
@@ -1491,7 +1491,7 @@ $1",
 'search-interwiki-default' => '$1 نتیجه:',
 'search-interwiki-more' => '(بیشتر)',
 'search-relatedarticle' => 'مرتبط',
-'mwsuggest-disable' => 'پیشنهادهای مبتنی بر AJAX را غیرفعال کن',
+'mwsuggest-disable' => 'پیشنهادهای مبتنی بر جستجو را غیرفعال کن',
 'searcheverything-enable' => 'جستجو در تمام فضاهای نام',
 'searchrelated' => 'مرتبط',
 'searchall' => 'همه',
@@ -2404,7 +2404,7 @@ https://www.mediawiki.org/wiki/Manual:Image_Authorization را ببینید.',
 # Special:ActiveUsers
 'activeusers' => 'فهرست کاربران فعال',
 'activeusers-intro' => 'در زیر فهرستی از کاربرانی را می‌بینید که در $1 {{PLURAL:$1|روز|روز}} گذشته فعالیتی داشته‌اند.',
-'activeusers-count' => '$1 {{PLURAL:$1|Ù\88Û\8cراÛ\8cØ´|Ù\88Û\8cراÛ\8cØ´}} در {{PLURAL:$3|روز|$3 روز}} اخیر',
+'activeusers-count' => '$1 {{PLURAL:$1|Ù\81عاÙ\84Û\8cت|Ù\81عاÙ\84Û\8cت}} در {{PLURAL:$3|روز|$3 روز}} اخیر',
 'activeusers-from' => 'نمایش کاربران با آغاز از:',
 'activeusers-hidebots' => 'نهفتن ربات‌ها',
 'activeusers-hidesysops' => 'نهفتن مدیران',
@@ -2467,7 +2467,7 @@ https://www.mediawiki.org/wiki/Manual:Image_Authorization را ببینید.',
 'usermessage-editor' => 'پیغام رسان سامانه',
 
 # Watchlist
-'watchlist' => 'فهرست پی‌گیری‌های من',
+'watchlist' => 'فهرست پی‌گیری',
 'mywatchlist' => 'فهرست پی‌گیری‌ها',
 'watchlistfor2' => 'برای $1 $2',
 'nowatchlist' => 'در فهرست پی‌گیری‌های شما هیچ موردی نیست.',
@@ -2946,7 +2946,7 @@ $1',
 '''شما''' مسئول اطمینان از این هستید که پیوندها هنوز به همان‌جایی که قرار است بروند.
 
 توجه کنید که اگر از قبل صفحه‌ای در عنوان جدید وجود داشته باشد صفحه منتقل '''نخواهد شد'''،
-مگر این که صفحه خالی یا تغییرمسیر باشد و تاریخچهٔ ویرایشی نداشته باشد.
+مگر این آخرین ویرایش تغییرمسیر باشد و در  تاریخچهٔ ویرایشی نداشته باشد.
 این یعنی اگر اشتباه کردید می‌توانید صفحه را به همان جایی که از آن منتقل شده بود برگردانید، و این که نمی‌توانید روی صفحه‌ها موجود بنویسید.
 
 '''هشدار!'''
@@ -3271,6 +3271,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|غیرتغییرمسیر|غیرتغییرمسیر}})',
@@ -4107,7 +4108,7 @@ $5
 'specialpages-group-highuse' => 'صفحه‌های پربازدید',
 'specialpages-group-pages' => 'فهرست‌های صفحه‌ها',
 'specialpages-group-pagetools' => 'ابزارهای صفحه‌ها',
-'specialpages-group-wiki' => 'اطÙ\84اعات Ù\88 Ø§Ø¨Ø²Ø§Ø±Ù\87اÛ\8c Ù\88Û\8cÚ©Û\8c',
+'specialpages-group-wiki' => 'دادÙ\87 Ù\88 Ø§Ø¨Ø²Ø§Ø±Ù\87ا',
 'specialpages-group-redirects' => 'صفحه‌های ویژهٔ تغییرمسیر دهنده',
 'specialpages-group-spam' => 'ابزارهای هرزنگاری',
 
@@ -4205,6 +4206,7 @@ $5
 '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 را تغییر داد',
@@ -4262,6 +4264,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 09a5ee6..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',
@@ -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,6 +3913,7 @@ 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ä',
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 50b0f59..0cfc7d4 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',
@@ -533,8 +533,8 @@ $messages = array(
 '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.
-Se vos plét, atende 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',
@@ -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,32 +650,32 @@ 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.
+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',
 'badtitletext' => 'Lo titro de la pâge demandâye est pas justo, vouedo ou ben o est un titro entèrlengoua ou entèrvouiqui mâl-liyê.
-Contint sûrament yon ou ben un mouél de caractèros que pôvont pas étre empleyês dedens los titros.',
+Contint de sûr yon ou ben un mouél de caractèros que pôvont pas étre empleyês dedens los titros.',
 'perfcached' => 'Cetes donâs sont en cacho et pôvont pas étre a jorn. Por lo més {{PLURAL:$1|un rèsultat est disponiblo|$1 rèsultats sont disponiblos}} dedens lo cacho.',
 'perfcachedts' => 'Cetes donâs sont en cacho et sont étâyes betâyes a jorn por lo dèrriér côp a $1. Por lo més {{PLURAL:$1|un rèsultat est disponiblo|$1 rèsultats sont disponiblos}} dedens lo cacho.',
 'querypage-no-updates' => 'Ora les mises a jorn por ceta pâge sont dèsactivâyes.
@@ -689,8 +689,8 @@ Demanda : $2',
 '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.
 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, 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.
@@ -705,7 +705,7 @@ $2',
 '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 »',
@@ -748,16 +748,16 @@ Oubliâd pas de changiér voutres [[Special:Preferences|prèferences dessus {{SI
 '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ê.
 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.
-Se vos plét, activâd-los et pués tornâd-vos 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.
 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.
@@ -800,8 +800,8 @@ Devant qu’un ôtro mèssâjo seye mandâ a ceti compto, vos devréd siuvre les
 '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.',
@@ -827,8 +827,8 @@ Se vos plét, atende devant que tornar èprovar.',
 
 # 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',
@@ -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
@@ -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.
-Se vos plét, entrebetâd 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 é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.
-Se vos plét, entrebetâd 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.
 Se vos plét, buchiéd et pués validâd 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.
+'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,9 +988,9 @@ 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, 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.''",
+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 que vint 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]
@@ -1060,7 +1060,7 @@ Na solucion de rechanjo est étâye trovâye por vos pèrmetre de changiér en t
 Se vos l’encartâd, tôs los changements fêts dês ceta vèrsion seront pèrdus.",
 'yourdiff' => 'Difèrences',
 '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 pués rebalyês a volontât, adonc mandâd-los pas ique.<br />
+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' => "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.
@@ -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',
@@ -1151,7 +1151,7 @@ Se vos plét, controlâd la comparèson ce-desot por vos assurar qu’o est fran
 '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,7 +1223,7 @@ 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',
@@ -1234,12 +1234,12 @@ fonccion, la vèrsion spècifiâye ègziste pas ou ben vos tâchiéd de cachiér
 '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.",
+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',
@@ -1273,7 +1273,7 @@ Vos y é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.
+'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
@@ -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, se vos plét tornâd 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.',
@@ -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,7 +1546,7 @@ 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 éd pas la pèrmission de changiér des drêts d’utilisator dessus d’ôtros vouiquis.',
@@ -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',
@@ -1740,15 +1740,15 @@ Les pâges de voutra [[Special:Watchlist|lista de siuvu]] sont en '''grâs'''.",
 'reuploaddesc' => 'Anular lo tèlèchargement et pués tornar u formulèro de tèlèchargement',
 '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.',
+'uploadnologintext' => 'Vos dête étre [[Special:UserLogin|branchiê(ye)]] por povêr tèlèchargiér des fichiérs.',
+'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
@@ -1788,11 +1788,11 @@ Se vos plét, renomâd-lo et pués tornâd-lo tèlèchargiér.',
 '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 est étâ anulâ per n’è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' => 'Na fôta encognua est arrevâ.',
-'tmp-create-error' => 'Empossiblo de fâre lo fichiér temporèro.',
+'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.',
@@ -1893,47 +1893,47 @@ Se lo problèmo continue, veriéd-vos vers un [[Special:ListUsers/sysop|administ
 '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 tramandar lo fichiér « $1 ».',
-'backend-fail-backup' => 'Empossiblo d’encartar 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-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' => 'Empossiblo de suprimar lo fichiér « $1 ».',
-'backend-fail-describe' => 'Empossiblo de changiér les mètadonâs du fichiér « $1 ».',
+'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' => 'Empossiblo de stocar lo fichiér « $1 » dedens « $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 grôs {{PLURAL:$2|qu’un octèt|que $2 octèts}}.',
+'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 dedens « $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 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 » ; il 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 donâs de vèrroly dedens la sèlye $1.',
-'lockmanager-fail-db-release' => 'Empossiblo de relâchiér los vèrrolys sur la bâsa de donâ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' => 'Na fôta est arrevâye pendent l’uvèrtura du fichiér por los contrôlos ZIP.',
@@ -1945,69 +1945,69 @@ Pôt pas étre controlâ coment fôt por la sècuritât.',
 
 # Special:UploadStash
 '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 cors 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-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 cela accion at pas reussia, pôt-étre perce que voutres enformacions de branchement ont èxpirâs. Tornâd èprovar.',
+'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,87 +2167,87 @@ 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}}.
-Vos pouede rètrendre la vua en chouèséssent un tipo de jornal, un nom d’usanciér (sensiblo a la câssa) ou ben una pâge afèctâ (sensibla a la câssa avouéc).',
-'logempty' => 'Nion èlèment d’ense at étâ trovâ dens lo jornal.',
-'log-title-wildcard' => 'Chèrchiér permié los titros que començont per ceti tèxto',
-'showhideselectedlogentries' => 'Fâre vêre / cachiér les entrâs de jornal chouèsies',
+'alllogstext' => 'Vua combinâye de tôs los jornals disponiblos dessus {{SITENAME}}.
+Vos pouede rètrendre la vua en chouèséssent un tipo de jornal, lo nom d’utilisator (sensiblo a la câssa) la pâge regardâye (sensibla a la câssa avouéc).',
+'logempty' => 'Niona piéce que corrèspond dedens lo jornal.',
+'log-title-wildcard' => 'Chèrchiér entre-mié los titros que començont per cél tèxto',
+'showhideselectedlogentries' => 'Montrar / cachiér les entrâs de jornal chouèsies',
 
 # Special:AllPages
 'allpages' => 'Totes les pâges',
@@ -2251,32 +2257,34 @@ Vos pouede rètrendre la vua en chouèséssent un tipo de jornal, un nom d’usa
 'allpagesfrom' => 'Fâre vêre les pâges dês :',
 'allpagesto' => 'Fâre vêre les pâges tant qu’a :',
 'allarticles' => 'Totes les pâges',
-'allinnamespace' => 'Totes les pâges (dens l’èspâço de noms « $1 »)',
+'allinnamespace' => 'Totes les pâges (dedens l’èspâço de noms « $1 »)',
 'allnotinnamespace' => 'Totes les pâges (en defôr de l’èspâço de noms « $1 »)',
 'allpagesprev' => 'Devant',
 'allpagesnext' => 'Aprés',
 'allpagessubmit' => 'Listar',
 'allpagesprefix' => 'Fâre vêre les pâges que començont per lo prèfixo :',
-'allpagesbadtitle' => 'Lo titro de pâge balyê est fôx ou ben il at un prèfixo entèrlengoua ou entèrvouiqui resèrvâ.
-Contint sûrement yon ou ben un mouél de caractèros que pôvont pas étre utilisâs dens los titros.',
+'allpagesbadtitle' => 'Lo titro de la pâge balyêe est pas justo ou ben il at un prèfixo entèrlengoua ou entèrvouiqui resèrvâ.
+Contint de sûr yon ou ben un mouél de caractèros que pôvont pas étre empleyês dedens los titros.',
 'allpages-bad-ns' => '{{SITENAME}} at gins d’èspâço de noms « $1 ».',
 'allpages-hide-redirects' => 'Cachiér les redirèccions',
 
 # SpecialCachedPage
-'cachedspecial-refresh-now' => 'Vêre lo ples novél.',
+'cachedspecial-viewing-cached-ttl' => 'Vos vêde na vèrsion betâye en cacho de cela pâge, que pôt étre vielye por lo més $1.',
+'cachedspecial-viewing-cached-ts' => 'Vos vêde na vèrsion betâye en cacho de cela pâge, que porrêt pas étre tot a fêt a jorn.',
+'cachedspecial-refresh-now' => 'Vêre la ples novèla.',
 
 # Special:Categories
 'categories' => 'Catègories',
-'categoriespagetext' => '{{PLURAL:$1|Ceta catègorie contint|Cetes catègories contegnont}} des pâges ou ben des fichiérs mèdia.
-Les [[Special:UnusedCategories|catègories inutilisâs]] sont pas montrâs ique.
-Vêde asse-ben les [[Special:WantedCategories|catègories les ples demandâs]].',
+'categoriespagetext' => '{{PLURAL:$1|Ceta catègorie contint|Cetes catègories contegnont}} des pâges des fichiérs mèdia.
+Les [[Special:UnusedCategories|catègories pas empleyêes]] sont pas montrâyes ique.
+Vêde asse-ben les [[Special:WantedCategories|catègories demandâyes]].',
 'categoriesfrom' => 'Fâre vêre les catègories dês :',
-'special-categories-sort-count' => 'tri per nombro d’èlèments',
+'special-categories-sort-count' => 'tri per nombro de piéces',
 'special-categories-sort-abc' => 'tri alfabètico',
 
 # Special:DeletedContributions
-'deletedcontributions' => 'Contribucions suprimâs',
-'deletedcontributions-title' => 'Contribucions suprimâs',
+'deletedcontributions' => 'Contribucions suprimâyes',
+'deletedcontributions-title' => 'Contribucions suprimâyes',
 'sp-deletedcontributions-contribs' => 'contribucions',
 
 # Special:LinkSearch
@@ -2284,133 +2292,133 @@ Vêde asse-ben les [[Special:WantedCategories|catègories les ples demandâs]].'
 'linksearch-pat' => 'Modèlo de rechèrche :',
 'linksearch-ns' => 'Èspâço de noms :',
 'linksearch-ok' => 'Rechèrchiér',
-'linksearch-text' => 'Des caractèros j·oquères coment « *.wikipedia.org » pôvont étre utilisâs.
-Ils ont fôta d’u muens un domêno de nivél supèrior, per ègzemplo « *.org ».<br />
-Protocolos recognus : <code>$1</code> (apondéd gins de cetos dedens voutra rechèrche).',
+'linksearch-text' => 'Des caractèros j·oquères coment « *.wikipedia.org » pôvont étre empleyês.
+Ils ont fôta de por lo muens un domêno de nivél de dessus, per ègzemplo « *.org ».<br />
+{{PLURAL:$2|Protocolo recognu|Protocolos recognus}} : <code>$1</code> (http:// per dèfôt se nion protocolo est spècifiâ).',
 'linksearch-line' => '$1 est liyê dês $2',
-'linksearch-error' => 'Los caractèros j·oquères pôvont étre utilisâs ren qu’u comencement du nom de domêno de l’hôto.',
+'linksearch-error' => 'Los caractèros j·oquères pôvont étre empleyês ren qu’u comencement du nom de domêno de l’hôto.',
 
 # Special:ListUsers
 'listusersfrom' => 'Fâre vêre los utilisators dês :',
-'listusers-submit' => 'Montrar',
-'listusers-noresult' => 'Gins d’usanciér trovâ.',
-'listusers-blocked' => '(blocâ)',
+'listusers-submit' => 'Listar',
+'listusers-noresult' => 'Nion utilisator trovâ.',
+'listusers-blocked' => '(blocâ{{GENDER:$1||ye|(ye)}})',
 
 # Special:ActiveUsers
-'activeusers' => 'Lista ux usanciérs actifs',
-'activeusers-intro' => 'O est una lista ux usanciérs qu’ont ègzèrciê una activitât quinta que seye pendent {{PLURAL:$1|lo jorn passâ|los $1 jorns passâs}}.',
-'activeusers-count' => '$1 {{PLURAL:$1|novél changement|novéls changements}} dens {{PLURAL:$3|lo jorn passâ|los $3 jorns passâs}}',
+'activeusers' => 'Lista des utilisators actifs',
+'activeusers-intro' => 'O est na lista des utilisators qu’ont ègzèrciê n’activitât la quinta que seye pendent {{PLURAL:$1|lo jorn passâ|los $1 jorns passâs}}.',
+'activeusers-count' => '$1 accion{{PLURAL:$1||s}} pendent {{PLURAL:$3|lo jorn passâ|los $3 jorns passâs}}',
 'activeusers-from' => 'Fâre vêre los utilisators dês :',
-'activeusers-hidebots' => 'Cachiér los bots',
+'activeusers-hidebots' => 'Cachiér los robots',
 'activeusers-hidesysops' => 'Cachiér los administrators',
-'activeusers-noresult' => 'Gins d’usanciér trovâ.',
+'activeusers-noresult' => 'Nion utilisator trovâ.',
 
 # Special:ListGroupRights
-'listgrouprights' => 'Drêts a les tropes d’usanciérs',
-'listgrouprights-summary' => 'Ceta pâge contint una lista a les tropes dèfenies sur ceti vouiqui et pués los drêts d’accès que lor sont associyês.
-Y pôt avêr [[{{MediaWiki:Listgrouprights-helppage}}|més d’enformacions]] sur los drêts particuliérs.',
+'listgrouprights' => 'Drêts de les tropes d’utilisators',
+'listgrouprights-summary' => 'Vê-que na lista de les tropes d’utilisators dèfenies sur ceti vouiqui et pués los sins drêts d’accès.
+Y pôt avêr [[{{MediaWiki:Listgrouprights-helppage}}|més d’enformacions]] sur los drêts endividuèls.',
 'listgrouprights-key' => '* <span class="listgrouprights-granted">Drêt balyê</span>
-* <span class="listgrouprights-revoked">Drêt rèvocâ</span>',
+* <span class="listgrouprights-revoked">Drêt cassâ</span>',
 'listgrouprights-group' => 'Tropa',
-'listgrouprights-rights' => 'Drêts associyês',
-'listgrouprights-helppage' => 'Help:Drêts a les tropes',
-'listgrouprights-members' => '(lista ux membros)',
-'listgrouprights-addgroup' => 'Apondre des membros a {{PLURAL:$2|la tropa|les tropes}} : $1',
-'listgrouprights-removegroup' => 'Enlevar des membros de {{PLURAL:$2|la tropa|les tropes}} : $1',
-'listgrouprights-addgroup-all' => 'Apondre des membros a totes les tropes',
-'listgrouprights-removegroup-all' => 'Enlevar des membros de totes les tropes',
+'listgrouprights-rights' => 'Drêts',
+'listgrouprights-helppage' => 'Help:Drêts de les tropes',
+'listgrouprights-members' => '(lista des membros)',
+'listgrouprights-addgroup' => 'Apondre a {{PLURAL:$2|la tropa|les tropes}} : $1',
+'listgrouprights-removegroup' => 'Enlevar de {{PLURAL:$2|la tropa|les tropes}} : $1',
+'listgrouprights-addgroup-all' => 'Apondre a totes les tropes',
+'listgrouprights-removegroup-all' => 'Enlevar de totes les tropes',
 'listgrouprights-addgroup-self' => 'Sè pôt apondre {{PLURAL:$2|la tropa|les tropes}} a son prôpro compto : $1',
 'listgrouprights-removegroup-self' => 'Sè pôt enlevar {{PLURAL:$2|la tropa|les tropes}} de son prôpro compto : $1',
 'listgrouprights-addgroup-self-all' => 'Sè pôt apondre totes les tropes a son prôpro compto',
 'listgrouprights-removegroup-self-all' => 'Sè pôt enlevar totes les tropes de son prôpro compto',
 
 # E-mail user
-'mailnologin' => 'Gins d’adrèce d’èxpèdior',
-'mailnologintext' => 'Vos dête étre [[Special:UserLogin|branchiê]] et avêr endicâ una adrèce èlèctronica valida dens voutres [[Special:Preferences|prèferences]] por povêr mandar des mèssâjos a d’ôtros usanciérs.',
+'mailnologin' => 'Nion’adrèce d’èxpèdior',
+'mailnologintext' => 'Vos dête étre [[Special:UserLogin|branchiê]] et avêr spècifiâ n’adrèce èlèctronica justa dens voutres [[Special:Preferences|prèferences]] por povêr mandar des mèssâjos a d’ôtros utilisators.',
 'emailuser' => 'Lui mandar un mèssâjo',
 'emailuser-title-target' => 'Mandar un mèssâjo a cet’utilisat{{GENDER:$1|or|rice}}',
 'emailuser-title-notarget' => 'Mandar un mèssâjo a l’utilisator',
 'emailpage' => 'Mandar un mèssâjo a l’utilisator',
 'emailpagetext' => 'Vos pouede empleyér lo formulèro ce-desot por mandar un mèssâjo a cet’utilisat{{GENDER:$1|or|rice}}.
-L’adrèce èlèctronica que vos éd buchiêye dens voutres [[Special:Preferences|prèferences]] aparètrat dedens lo champ « Èxpèdior » de voutron mèssâjo ; d’ense, lo dèstinatèro vos porrat rèpondre tot drêt.',
-'usermailererror' => 'Èrror dens lo sujèt du mèssâjo :',
-'defemailsubject' => 'Mèssâjo de {{SITENAME}} de l’usanciér « $1 »',
-'usermaildisabled' => 'L’èxpèdicion de mèssâjos entre-mié usanciérs est dèsactivâ',
-'usermaildisabledtext' => 'Vos pouede pas mandar des mèssâjos a d’ôtros usanciérs sur ceti vouiqui',
-'noemailtitle' => 'Dèstinatèro sen adrèce èlèctronica',
-'noemailtext' => 'Ceti usanciér at pas spècefiâ una adrèce èlèctronica valida.',
-'nowikiemailtitle' => 'Gins de mèssageria èlèctronica ôtorisâ',
-'nowikiemailtext' => 'Ceti usanciér at chouèsi de pas recêvre de mèssâjo de la pârt d’ôtros usanciérs.',
-'emailnotarget' => 'Nom d’usanciér u dèstinatèro pas ègzistent ou ben envalido.',
-'emailtarget' => 'Buchiéd lo nom d’usanciér u dèstinatèro',
+L’adrèce èlèctronica que vos éd buchiêe dens voutres [[Special:Preferences|prèferences]] aparêtrat dedens lo champ « Èxpèdior » de voutron mèssâjo ; d’ense, lo dèstinatèro vos porrat rèpondre tot drêt.',
+'usermailererror' => 'Fôta dens la chousa du mèssâjo :',
+'defemailsubject' => 'Mèssâjo de {{SITENAME}} de l’utilisator « $1 »',
+'usermaildisabled' => 'L’èxpèdicion de mèssâjos entre utilisators est dèsactivâye',
+'usermaildisabledtext' => 'Vos pouede pas mandar de mèssâjos a d’ôtros utilisators sur ceti vouiqui',
+'noemailtitle' => 'Nion’adrèce èlèctronica',
+'noemailtext' => 'Cet’utilisator at pas spècifiâ n’adrèce èlèctronica justa.',
+'nowikiemailtitle' => 'Niona mèssageria èlèctronica ôtorisâye',
+'nowikiemailtext' => 'Cél utilisator at chouèsi de pas recêvre de mèssâjos de la pârt d’ôtros utilisators.',
+'emailnotarget' => 'Nom d’utilisator du dèstinatèro pas ègzistent pas justo.',
+'emailtarget' => 'Buchiéd lo nom d’utilisator du dèstinatèro',
 'emailusername' => 'Nom d’utilisator :',
-'emailusernamesubmit' => 'Sometre',
-'email-legend' => 'Mandar un mèssâjo a un ôtro usanciér de {{SITENAME}}',
+'emailusernamesubmit' => 'Mandar',
+'email-legend' => 'Mandar un mèssâjo a un ôtr’utilisator de {{SITENAME}}',
 'emailfrom' => 'De :',
-'emailto' => 'Dèstinatèro :',
-'emailsubject' => 'Sujèt :',
+'emailto' => 'A :',
+'emailsubject' => 'Chousa :',
 'emailmessage' => 'Mèssâjo :',
 'emailsend' => 'Mandar',
-'emailccme' => 'Mè mandar per mèssageria èlèctronica una copia de mon mèssâjo.',
+'emailccme' => 'Mè mandar per mèssageria èlèctronica na copia de mon mèssâjo.',
 'emailccsubject' => 'Copia de voutron mèssâjo a $1 : $2',
 'emailsent' => 'Mèssâjo mandâ',
-'emailsenttext' => 'Voutron mèssâjo at étâ mandâ per mèssageria èlèctronica.',
-'emailuserfooter' => 'Ceti mèssâjo at étâ mandâ per « $1 » a « $2 » per la fonccion « Lui mandar un mèssâjo » de {{SITENAME}}.',
+'emailsenttext' => 'Voutron mèssâjo est étâ mandâ per mèssageria èlèctronica.',
+'emailuserfooter' => 'Ceti mèssâjo est étâ mandâ per « $1 » a « $2 » per la fonccion « Lui mandar un mèssâjo » de {{SITENAME}}.',
 
 # User Messenger
-'usermessage-summary' => 'At lèssiê un mèssâjo sistèmo.',
+'usermessage-summary' => 'Il at lèssiê un mèssâjo sistèmo.',
 'usermessage-editor' => 'Mèssagiér du sistèmo',
 'usermessage-template' => 'MediaWiki:MèssâjoUtilisator',
 
 # Watchlist
-'watchlist' => 'Lista de survelyence',
-'mywatchlist' => 'Lista de survelyence',
+'watchlist' => 'Lista de siuvu',
+'mywatchlist' => 'Lista de siuvu',
 'watchlistfor2' => 'Por $1 $2',
-'nowatchlist' => 'Voutra lista de survelyence contint gins d’èlèment.',
-'watchlistanontext' => 'Vos volyéd $1 por vêre ou ben changiér les piéces de voutra lista de survelyence.',
+'nowatchlist' => 'Vos éd gins de piéce dedens voutra lista de siuvu.',
+'watchlistanontext' => 'Se vos plét, vos vos dête $1 por povêr vêre ou ben changiér les piéces de voutra lista de siuvu.',
 'watchnologin' => 'Pas branchiê',
-'watchnologintext' => 'Vos dête étre [[Special:UserLogin|branchiê]] por changiér voutra lista de survelyence.',
-'addwatch' => 'Apondre a la lista de survelyence',
-'addedwatchtext' => 'La pâge « [[:$1]] » est étâye apondua a voutra [[Special:Watchlist|lista de survelyence]].
+'watchnologintext' => 'Vos dête étre [[Special:UserLogin|branchiê(ye)]] por povêr changiér voutra lista de siuvu.',
+'addwatch' => 'Apondre a la lista de siuvu',
+'addedwatchtext' => 'La pâge « [[:$1]] » est étâye apondua a voutra [[Special:Watchlist|lista de siuvu]].
 Los changements que vegnont de ceta pâge et de la sina pâge de discussion y seront listâs.',
-'removewatch' => 'Enlevar de la lista de survelyence',
-'removedwatchtext' => 'La pâge « [[:$1]] » at étâ enlevâ de voutra [[Special:Watchlist|lista de survelyence]].',
+'removewatch' => 'Enlevar de la lista de siuvu',
+'removedwatchtext' => 'La pâge « [[:$1]] » est étâye enlevâye de voutra [[Special:Watchlist|lista de siuvu]].',
 'watch' => 'Siuvre',
 'watchthispage' => 'Siuvre ceta pâge',
 'unwatch' => 'Pas més siuvre',
 'unwatchthispage' => 'Pas més siuvre',
-'notanarticle' => 'Pas una pâge de contegnu',
-'notvisiblerev' => 'La vèrsion at étâ suprimâ',
-'watchnochange' => 'Nion des èlèments que vos siude at étâ changiê pendent lo temps montrâ.',
-'watchlist-details' => 'Voutra lista de survelyence contint $1 pâge{{PLURAL:$1||s}}, sen comptar les pâges de discussion.',
-'wlheader-enotif' => '* La notificacion per mèssageria èlèctronica est activâ.',
-'wlheader-showupdated' => "* Les pâges qu’ont étâ changiês dês voutra dèrriére visita sont montrâs en '''grâs'''.",
+'notanarticle' => 'O est pas na pâge de contegnu',
+'notvisiblerev' => 'La dèrriére vèrsion per un ôtr’utilisator est étâye suprimâye',
+'watchnochange' => 'Pas yona de les piéces que vos siude est étâye changiêe pendent lo temps fêt vêre.',
+'watchlist-details' => 'Y at $1 pâge{{PLURAL:$1||s}} dedens voutra lista de siuvu, sen comptar les pâges de discussion.',
+'wlheader-enotif' => '* La notificacion per mèssageria èlèctronica est activâye.',
+'wlheader-showupdated' => "* Les pâges que sont étâyes changiêes dês voutra dèrriére visita sont montrâyes en '''grâs'''.",
 'watchmethod-recent' => 'contrôlo des novéls changements por y trovar des pâges siuvues',
 'watchmethod-list' => 'contrôlo de les pâges siuvues por y trovar des novéls changements',
-'watchlistcontains' => 'Voutra lista de survelyence contint $1 pâge{{PLURAL:$1||s}}.',
-'iteminvalidname' => 'Problèmo avouéc l’èlèment « $1 » : lo nom est envalido.',
-'wlnote' => "Vê-que {{PLURAL:$1|lo dèrriér changement fêt|los '''$1''' dèrriérs changements fêts}} pendent {{PLURAL:$2|l’hora passâ|les '''$2''' hores passâs}}, dês $3, $4.",
+'watchlistcontains' => 'Voutra lista de siuvu contint $1 pâge{{PLURAL:$1||s}}.',
+'iteminvalidname' => 'Problèmo avouéc la piéce « $1 », nom pas justo...',
+'wlnote' => "Vê-que {{PLURAL:$1|lo dèrriér changement fêt|los '''$1''' dèrriérs changements fêts}} pendent {{PLURAL:$2|l’hora passâye|les '''$2''' hores passâyes}}, dês $3 a $4.",
 'wlshowlast' => 'Montrar les $1 hores passâyes, los $2 jorns passâs ou ben $3',
-'watchlist-options' => 'Chouèx de la lista de survelyence',
+'watchlist-options' => 'Chouèx de la lista de siuvu',
 
 # Displayed when you click the "watch" button and it is in the process of watching
-'watching' => 'Survelyence...',
-'unwatching' => 'Fin de la survelyence...',
-'watcherrortext' => 'Una èrror est arrevâ pendent lo changement des paramètres de voutra lista de survelyence por « $1 ».',
+'watching' => 'Siuvu...',
+'unwatching' => 'Fin du siuvu...',
+'watcherrortext' => 'Na fôta est arrevâye pendent lo changement de la configuracion de voutra lista de siuvu por « $1 ».',
 
 'enotif_mailer' => 'Sistèmo de notificacion per mèssageria èlèctronica de {{SITENAME}}',
-'enotif_reset' => 'Marcar totes les pâges coment visitâs',
-'enotif_impersonal_salutation' => 'Usanciér de {{SITENAME}}',
+'enotif_reset' => 'Marcar totes les pâges coment visitâyes',
+'enotif_impersonal_salutation' => 'Utilisator de {{SITENAME}}',
 'enotif_subject_deleted' => 'La pâge $1 dessus {{SITENAME}} est étâye suprimâye per {{GENDER:$2|$2}}',
 'enotif_subject_created' => 'La pâge $1 dessus {{SITENAME}} est étâye fêta per {{GENDER:$2|$2}}',
-'enotif_subject_moved' => 'La pâge $1 dessus {{SITENAME}} est étâye renomâye per {{GENDER:$2|$2}}',
+'enotif_subject_moved' => 'La pâge $1 dessus {{SITENAME}} est étâye dèplaciêe per {{GENDER:$2|$2}}',
 'enotif_subject_restored' => 'La pâge $1 dessus {{SITENAME}} est étâye refêta per {{GENDER:$2|$2}}',
-'enotif_subject_changed' => 'La pâge $1 dessus {{SITENAME}} est étâye changiêye per {{GENDER:$2|$2}}',
+'enotif_subject_changed' => 'La pâge $1 dessus {{SITENAME}} est étâye changiêe per {{GENDER:$2|$2}}',
 'enotif_body_intro_deleted' => 'La pâge $1 dessus {{SITENAME}} est étâye suprimâye lo $PAGEEDITDATE per {{GENDER:$2|$2}}, vêde $3.',
 'enotif_body_intro_created' => 'La pâge $1 dessus {{SITENAME}} est étâye fêta lo $PAGEEDITDATE per {{GENDER:$2|$2}}, vêde $3 por la vèrsion d’ora.',
-'enotif_body_intro_moved' => 'La pâge $1 dessus {{SITENAME}} est étâye renomâye lo $PAGEEDITDATE per {{GENDER:$2|$2}}, vêde $3 por la vèrsion d’ora.',
+'enotif_body_intro_moved' => 'La pâge $1 dessus {{SITENAME}} est étâye dèplaciêe lo $PAGEEDITDATE per {{GENDER:$2|$2}}, vêde $3 por la vèrsion d’ora.',
 'enotif_body_intro_restored' => 'La pâge $1 dessus {{SITENAME}} est étâye refêta lo $PAGEEDITDATE per {{GENDER:$2|$2}}, vêde $3 por la vèrsion d’ora.',
-'enotif_body_intro_changed' => 'La pâge $1 dessus {{SITENAME}} est étâye changiêye lo $PAGEEDITDATE per {{GENDER:$2|$2}}, vêde $3 por la vèrsion d’ora.',
+'enotif_body_intro_changed' => 'La pâge $1 dessus {{SITENAME}} est étâye changiêe lo $PAGEEDITDATE per {{GENDER:$2|$2}}, vêde $3 por la vèrsion d’ora.',
 'enotif_lastvisited' => 'Vêde $1 por tôs los changements dês voutra dèrriére visita.',
 'enotif_lastdiff' => 'Vêde $1 por vêre cél changement.',
 'enotif_anon_editor' => 'utilisator anonimo $1',
index 59adbfd..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.',
@@ -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 1cc7e16..4205100 100644 (file)
@@ -947,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 →',
@@ -1105,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:',
@@ -1161,7 +1161,7 @@ Podrobnosće móžeš w [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}
 'search-interwiki-default' => '$1 wuslědki:',
 'search-interwiki-more' => '(dalše)',
 'search-relatedarticle' => 'Přiwuzne',
-'mwsuggest-disable' => 'Namjety AJAX znjemóžnić',
+'mwsuggest-disable' => 'Pytanske namjety znjemóžnić',
 'searcheverything-enable' => 'We wšěch mjenowych rumach pytać',
 'searchrelated' => 'přiwuzny',
 'searchall' => 'wšě',
@@ -2566,7 +2566,7 @@ Hlej [[Special:BlockList|lisćinu blokowanjow]], zo by zablokowanjow pruwował.'
 '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.  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 '''nje''' 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ć.
 
 '''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ć.
@@ -2879,6 +2879,7 @@ W poslednim padźe móžeš tež wotkaz wužiwać, na př. „[[{{#Special:Expor
 'pageinfo-robot-noindex' => 'Njeindeksujomny',
 'pageinfo-views' => 'Ličba zwobraznjenjow',
 'pageinfo-watchers' => 'Ličba wobkedźbowarjow strony',
+'pageinfo-few-watchers' => 'Mjenje hač $1 {{PLURAL:$1|wobkedźbowar|wobkedźbowarjej|wobkedźbowarje|wobkedźbowarjow}}',
 'pageinfo-redirects-name' => 'Dalesposrědkowanja k tutej stronje',
 'pageinfo-redirects-value' => '$1',
 'pageinfo-subpages-name' => 'Podstrony tuteje strony',
index 1ad51bf..c07fa9a 100644 (file)
@@ -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 e2284cc..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',
@@ -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',
 
@@ -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.',
 
@@ -2234,6 +2237,11 @@ Le modificationes futur in iste pagina e in le pagina de discussion associate es
 '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',
index f2157b1..73cafbb 100644 (file)
@@ -447,12 +447,12 @@ $messages = array(
 'dec' => 'Des',
 
 # Categories related messages
-'pagecategories' => '{{PLURAL:$1|Kategori}}',
+'pagecategories' => '{{PLURAL:$1|Kategori|Kategori}}',
 'category_header' => 'Halaman dalam kategori "$1"',
 'subcategories' => 'Subkategori',
 'category-media-header' => 'Media dalam kategori "$1"',
 'category-empty' => "''Saat ini, tidak terdapat halaman ataupun media dalam kategori ini.''",
-'hidden-categories' => '{{PLURAL:$1|Kategori tersembunyi}}',
+'hidden-categories' => '{{PLURAL:$1|Kategori tersembunyi|Kategori tersembunyi}}',
 'hidden-category-category' => 'Kategori tersembunyi',
 'category-subcat-count' => '{{PLURAL:$2|Kategori ini hanya memiliki satu subkategori berikut.|Kategori ini memiliki {{PLURAL:$1|subkategori|$1 subkategori}} berikut, dari total $2.}}',
 'category-subcat-count-limited' => 'Kategori ini memiliki {{PLURAL:$1|subkategori|$1 subkategori}} berikut.',
@@ -1142,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',
@@ -1341,8 +1341,8 @@ Rinciannya dapat ditemukan di [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGE
 'notextmatches' => 'Tidak ada teks halaman yang cocok',
 'prevn' => '{{PLURAL:$1|$1}} sebelumnya',
 'nextn' => '{{PLURAL:$1|$1}} selanjutnya',
-'prevn-title' => '$1 {{PLURAL:$1|hasil}} sebelumnya',
-'nextn-title' => '$1 {{PLURAL:$1|hasil}} selanjutnya',
+'prevn-title' => '$1 {{PLURAL:$1|hasil|hasil}} sebelumnya',
+'nextn-title' => '$1 {{PLURAL:$1|hasil|hasil}} selanjutnya',
 'shown-title' => 'Tampilkan $1 {{PLURAL:$1|hasil|hasil}} per halaman',
 'viewprevnext' => 'Lihat ($1 {{int:pipe-separator}} $2) ($3)',
 'searchmenu-legend' => 'Opsi pencarian',
@@ -1360,7 +1360,7 @@ Rinciannya dapat ditemukan di [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGE
 'searchprofile-images-tooltip' => 'Pencarian berkas',
 'searchprofile-everything-tooltip' => 'Pencarian di seluruh situs (termasuk halaman pembicaraan)',
 'searchprofile-advanced-tooltip' => 'Pencarian di ruang nama tertentu',
-'search-result-size' => '$1 ({{PLURAL:$2|$2 kata}})',
+'search-result-size' => '$1 ({{PLURAL:$2|1 kata|$2 kata}})',
 'search-result-category-size' => '{{PLURAL:$1|1 anggota|$1 anggota}} ({{PLURAL:$2|1 subkategori|$2 subkategori}}, {{PLURAL:$3|1 berkas|$3 berkas}})',
 'search-result-score' => 'Relevansi: $1%',
 'search-redirect' => '(pengalihan $1)',
@@ -1370,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',
@@ -1403,7 +1403,7 @@ Perlu diingat bahwa indeks Google untuk konten {{SITENAME}} mungkin belum mencak
 
 # Preferences page
 'preferences' => 'Preferensi',
-'mypreferences' => 'Pengaturan',
+'mypreferences' => 'Preferensi',
 'prefs-edits' => 'Jumlah suntingan:',
 'prefsnologin' => 'Belum masuk log',
 'prefsnologintext' => 'Anda harus <span class="plainlinks">[{{fullurl:{{#Special:UserLogin}}|returnto=$1}} masuk log]</span> untuk mengeset preferensi Anda.',
@@ -2134,7 +2134,7 @@ Nama yang telah <del>dicoret</del> berarti telah dibetulkan.',
 'fewestrevisions' => 'Halaman dengan perubahan tersedikit',
 
 # Miscellaneous special pages
-'nbytes' => '$1 {{PLURAL:$1|bita}}',
+'nbytes' => '$1 {{PLURAL:$1|bita|bita}}',
 'ncategories' => '$1 {{PLURAL:$1|kategori|kategori}}',
 'ninterwikis' => '$1 {{PLURAL:$1|interwiki|interwiki}}',
 'nlinks' => '$1 {{PLURAL:$1|pranala|pranala}}',
@@ -2199,7 +2199,7 @@ Harap perhatikan bahwa situs web lain mungkin memiliki pranala ke suatu berkas d
 'nopagetitle' => 'Halaman tujuan tidak ditemukan',
 'nopagetext' => 'Halaman yang Anda tuju tidak ditemukan.',
 'pager-newer-n' => '{{PLURAL:$1|1 lebih baru|$1 lebih baru}}',
-'pager-older-n' => '{{PLURAL:$1|$1 lebih lama}}',
+'pager-older-n' => '{{PLURAL:$1|1 lebih lama|$1 lebih lama}}',
 'suppress' => 'Pengawas',
 'querypage-disabled' => 'Halaman istimewa ini dinonaktifkan demi alasan kinerja.',
 
@@ -2279,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',
@@ -3268,7 +3268,7 @@ Jika dijalankan, sistem Anda akan berisiko terserang.",
 # 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 m',
+'minutes-abbrev' => '$1 mnt',
 'hours-abbrev' => '$1 j',
 'days-abbrev' => '$1 h',
 'seconds' => '{{PLURAL:$1|$1 detik|$1 detik}}',
index 732549b..53305af 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.',
@@ -3027,11 +3074,14 @@ Vinsamlegast reyndu aftur.',
 'sp-newimages-showfrom' => 'Leita af nýjum skráum frá $2, $1',
 
 # Video information, used by Language::formatTimePeriod() to format lengths in the above messages
-'seconds' => '{{PLURAL:$1|ein sekúnda|$1 sekúndur}}',
-'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}}',
+'seconds' => '{{PLURAL:$1|einni sekúndu|$1 sekúndum}}',
+'minutes' => '{{PLURAL:$1|einni mínútu|$1 mínútum}}',
+'hours' => '{{PLURAL:$1|einum klukkutíma|$1 klukkutímum}}',
+'days' => '{{PLURAL:$1|einum degi|$1 dögum}}',
+'months' => '{{PLURAL:$1|$1 mánuði|$1 mánuðum}}',
+'years' => '{{PLURAL:$1|$1 ári|$1 árum}}',
 '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..4c2cf75 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',
@@ -3150,7 +3151,7 @@ $1',
 'seconds' => '{{PLURAL:$1|un secondo|$1 secondi}}',
 'minutes' => '{{PLURAL:$1|un minuto|$1 minuti}}',
 'hours' => "{{PLURAL:$1|un'ora|$1 ore}}",
-'days' => '{{PLURAL:$1|un giorno|$1 giorni}}',
+'days' => '{{PLURAL:$1|$1 giorno|$1 giorni}}',
 'months' => '{{PLURAL:$1|$1 mese|$1 mesi}}',
 'years' => '{{PLURAL:$1|$1 anno|$1 anni}}',
 'ago' => '$1 fa',
index cafb07c..eb11072 100644 (file)
@@ -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 8859f3a..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' => 'შეტყობინება:',
@@ -2344,6 +2345,7 @@ $UNWATCHURL
 'prot_1movedto2' => '[[$1]] გადატანილია გვერდზე [[$2]]',
 'protect-badnamespace-title' => 'დაუცველი სახელთა სივრცე',
 'protect-badnamespace-text' => 'ამ სახელთა სივრცის გვერდების დაცვა შეუძლებელია.',
+'protect-norestrictiontypes-text' => 'ამ გვერდის დაცვა შეუძლებელია, რადგან მისთვის არ არსებობს შესაბამისი დაცვის ტიპი.',
 'protect-norestrictiontypes-title' => 'დაუცველი გვერდი',
 'protect-legend' => 'დაცვის დადასტურება',
 'protectcomment' => 'მიზეზი:',
@@ -2663,7 +2665,7 @@ $1',
 შეამოწმეთ [[Special:DoubleRedirects|ორმაგი]] ან [[Special:BrokenRedirects|გამწყდარი გადამისამართებები]]. 
 თქვენ ხართ პასუხისმგებელი, რომ ბმულები მკითხველს დანიშნულებისამებრ მიიყვანს.
 
\83\92á\83\90á\83\98á\83\97á\83\95á\83\90á\83\9aá\83\98á\83¡á\83¬á\83\98á\83\9cá\83\94á\83\97, á\83 á\83\9dá\83\9b á\83\92á\83\95á\83\94á\83 á\83\93á\83\98 á\83\90á\83  á\83\92á\83\90á\83\93á\83\90á\83\95á\83\90, á\83\97á\83£ á\83\90á\83®á\83\90á\83\9aá\83\98 á\83¡á\83\90á\83\97á\83\90á\83£á\83 á\83\98á\83\97 á\83¡á\83¢á\83\90á\83¢á\83\98á\83\90 á\83£á\83\99á\83\95á\83\94 á\83\90á\83 á\83¡á\83\94á\83\91á\83\9dá\83\91á\83¡, á\83\92á\83\90á\83 á\83\93á\83\90 á\83\98á\83\9b á\83¨á\83\94á\83\9bá\83\97á\83®á\83\95á\83\94á\83\95á\83\98á\83¡á\83\90, á\83\97á\83£ á\83\98á\83¡ ცარიელია ან გადამისამართებაა და არ აქვს გვერდის რედაქტირების ისტორია. 
\83\92á\83\90á\83\98á\83\97á\83\95á\83\90á\83\9aá\83\98á\83¡á\83¬á\83\98á\83\9cá\83\94á\83\97, á\83 á\83\9dá\83\9b á\83\92á\83\95á\83\94á\83 á\83\93á\83\98 á\83\90á\83  á\83\92á\83\90á\83\93á\83\90á\83\95á\83\90, á\83\97á\83£ á\83\90á\83®á\83\90á\83\9aá\83\98 á\83¡á\83\90á\83\97á\83\90á\83£á\83 á\83\98á\83\97 á\83¡á\83¢á\83\90á\83¢á\83\98á\83\90 á\83£á\83\99á\83\95á\83\94 á\83\90á\83 á\83¡á\83\94á\83\91á\83\9dá\83\91á\83¡, á\83\92á\83\90á\83 á\83\93á\83\90 á\83\98á\83\9b á\83¨á\83\94á\83\9bá\83\97á\83®á\83\95á\83\94á\83\95á\83\98á\83¡á\83\90, á\83 á\83\9dá\83\93á\83\94á\83¡á\83\90á\83ª á\83\9bá\83¡á\83\92á\83\90á\83\95á\83¡á\83\98 á\83\92á\83\95á\83\94á\83 á\83\93á\83\98 ცარიელია ან გადამისამართებაა და არ აქვს გვერდის რედაქტირების ისტორია. 
 ეს ნიშნავს, რომ თქვენ შეგიძლიათ დაუბრუნოთ ძველი სახელი გვერდს, თუ შეცდომა დაუშვით, მაგრამ არ შეგიძლიათ ზემოთ გადააწეროთ არსებულ გვერდს.
 
 '''ფრთხილად!'''
@@ -2840,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“ ქვეგვერდები დაუშვებელია.',
@@ -2992,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' => 'ამ გვერდის ქვეგვერდები',
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 29771eb..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]]',
@@ -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 cb3f61f..bc23d07 100644 (file)
@@ -201,6 +201,7 @@ $messages = array(
 'newwindow' => '(джангы терезеде ачылады)',
 'cancel' => 'Ызына алыу',
 'moredotdotdot' => 'Баргъаны…',
+'morenotlisted' => 'Энди джукъ джокъду...',
 'mypage' => 'Бет',
 'mytalk' => 'Сюзюу',
 'anontalk' => 'Бу IP-адресге сюзюу бет',
@@ -500,7 +501,7 @@ $2',
 'gotaccount' => 'Тергеу джазыуугъуз (аккаунтугъуз) энди бармыды? $1.',
 'gotaccountlink' => 'Кириу',
 'userlogin-resetlink' => 'Кирир ючюн билгилеригизни унутхан этгенмисиз?',
-'createaccountmail' => 'e-mail бла',
+'createaccountmail' => 'Эсде болмагъанлай генерация этилген болджаллы паролну хайырландыр эм тюбюрекде берилген электрон почта адресге ий:',
 'createaccountreason' => 'Чурум:',
 'badretype' => 'Джазгъан паролларыгъыз бир-бирине келишмейдиле.',
 'userexists' => 'Джазылгъан ат хайырландырылады.
@@ -1879,6 +1880,9 @@ URL-ни тюз , сайтны ачыкъ болгъанына ишексиз б
 'allpages-bad-ns' => '{{SITENAME}} сайтда «$1» ат алам джокъду.',
 'allpages-hide-redirects' => 'Башха бетлеге джиберген бетлени (редиректлени) джашыр',
 
+# SpecialCachedPage
+'cachedspecial-refresh-now' => 'Ахыр версиягъа къарау.',
+
 # Special:Categories
 'categories' => 'Категорияла',
 'categoriespagetext' => 'Ызындан келген {{PLURAL:$1|категория|категорияла}} бет неда медия-файл тутадыла.
@@ -1944,6 +1948,8 @@ URL-ни тюз , сайтны ачыкъ болгъанына ишексиз б
 'mailnologin' => 'Джиберирге адрес джокъду',
 'mailnologintext' => 'Башха къошулуучулагъа эл. почта джиберелир ючюн [[Special:UserLogin|системагъа кирирге]] керексиз эм [[Special:Preferences|джарашдырыуланы]] бетинде джараулу эл. почта адрес болургъа керекди.',
 'emailuser' => 'Къошулуучугъа письмо',
+'emailuser-title-target' => '{{GENDER:$1|Къошулуучугъа}} электрон джазма джазыу',
+'emailuser-title-notarget' => 'Электрон джазма джазыу',
 'emailpage' => 'Къошулуучугъа письмо джибер',
 'emailpagetext' => 'Бу къошулуучуну почтасына письмо джиберир ючюн бу форманы толтурургъа боллукъсуз.
 Ызына адрес болуб, сиз [[Special:Preferences|джарашдырыуларыгъызда]] джазгъан адрес белгиленникди, ол себебден сизни письмогъузну аллыкъ сизге тюз джууаб берирге мадарлы боллукъду.',
@@ -2109,6 +2115,7 @@ $2 тюрлендирген алгъаракъ версиясына къайты
 'unprotectedarticle' => '«[[$1]]» бетден джакълыкъ алыннганды',
 'movedarticleprotection' => 'Къоруулауну джарашдырыулары "[[$2]]" бетден "[[$1]]" бетге кёчюрюлгенди',
 'protect-title' => '"$1" ючюн къоруулау дараджаны сайлагъыз',
+'protect-title-notallowed' => '«$1» джакълау дараджагъа къара',
 'prot_1movedto2' => '[[$1]] бетни джангы аты: [[$2]]',
 'protect-legend' => 'Къоруулауну къабыл эт',
 'protectcomment' => 'Чурум:',
@@ -2129,6 +2136,7 @@ $2 тюрлендирген алгъаракъ версиясына къайты
 'protect-level-sysop' => 'Къуру администраторла',
 'protect-summary-cascade' => 'каскадлы',
 'protect-expiring' => 'бошалады $1 (UTC)',
+'protect-expiring-local' => '$1 бошалады',
 'protect-expiry-indefinite' => 'болджалсыз',
 'protect-cascade' => 'Бу бетге кирген бетлени джакъла (каскадлы джакълау)',
 'protect-cantedit' => 'Сиз бу бетни джакълау дараджасын тюрлендиреллик тюйюлсюз, бу бетни тюрлендирирге хакъыгъыз болмагъаны ючюн.',
@@ -2263,6 +2271,7 @@ $1',
 
 # Block/unblock
 'block' => 'Къошулуучуну блокла',
+'unblock' => 'Къошулуучуну блок этилиуюн алыу',
 'blockip' => 'Бу къошулуучуну блок эт',
 'blockip-title' => 'Къошулуучуну блокга салыу',
 'blockip-legend' => 'Къошулуучуну блокга салыу',
@@ -2694,6 +2703,8 @@ MediaWiki локализациясына юлюш къошаргъа излей
 'pageinfo-views' => 'Къарауланы саны',
 'pageinfo-watchers' => 'Бетни кёзде тутханланы саны',
 'pageinfo-redirects-name' => 'Бу бетге редиректле',
+'pageinfo-firstuser' => 'Бетле къураучу',
+'pageinfo-lastuser' => 'Ахыр редактор',
 'pageinfo-edits' => 'Бютеу тюрлендириулени саны',
 'pageinfo-authors' => 'Тюрлю-тюрлю авторланы саны',
 'pageinfo-toolboxlink' => 'Бетни юсюнден',
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 a579d53..ed2890d 100644 (file)
@@ -917,7 +917,7 @@ Dir kënnt den Text kopéieren an an een Textfichier drasetzen an deen ofspäich
 
 Den Administrateur den d'Datebank gespaart huet, huet dës Erklärung ginn: $1",
 'protectedpagewarning' => "'''OPGEPASST: Dës Säit gouf gespaart a kann nëmme vun engem Administrateur geännert ginn.''' Déi lescht Zeil aus de Logbicher fannt Dir zu Ärer Informatioun hei ënnendrënner.",
-'semiprotectedpagewarning' => "'''Bemierkung:''' Dës Säit gouf esou gespaart, datt nëmme ugemellte Benotzer s'ännere kënnen. Déi lescht Zeil aus de Logbicher fannt Dir zu Ärer Informatioun hei ënnendrënner.",
+'semiprotectedpagewarning' => "'''Bemierkung:''' Dës Säit gouf esou gespaart, datt nëmme ugemellt Benotzer s'ännere kënnen. Déi lescht Zeil aus de Logbicher fannt Dir zu Ärer Informatioun hei ënnendrënner.",
 'cascadeprotectedwarning' => "'''Passt op:''' Dës Säit gouf gespaart a kann nëmme vu Benotzer mat Administreursrechter geännert ginn. Si ass an dës {{PLURAL:$1|Säit|Säiten}} agebonnen, déi duerch Cascadespäroptioun gespaart {{PLURAL:$1|ass|sinn}}:'''",
 'titleprotectedwarning' => "'''OPGEPASST: Dës Säit gouf gespaart sou datt [[Special:ListGroupRights|spezifesch Rechter]] gebraucht gi fir se uleeën ze kënnen.''' Déi lescht Zeil aus de Logbicher fannt Dir zu Ärer Informatioun hei ënnendrënner.",
 'templatesused' => '{{PLURAL:$1|Schabloun|Schablounen}} déi op dëser Säit am Gebrauch sinn:',
@@ -1206,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',
@@ -1522,7 +1522,7 @@ Si muss manner wéi $1 {{PLURAL:$1|Zeechen|Zeechen}} hunn.',
 'rclistfrom' => 'Nei Ännerunge vu(n) $1 u weisen',
 'rcshowhideminor' => 'Kleng Ännerunge $1',
 'rcshowhidebots' => 'Botte $1',
-'rcshowhideliu' => 'Ugemellte Benotzer $1',
+'rcshowhideliu' => 'Ugemellt Benotzer $1',
 'rcshowhideanons' => 'Anonym Benotzer $1',
 'rcshowhidepatr' => 'iwwerwaacht Ännerunge $1',
 'rcshowhidemine' => 'Meng Ännerunge $1',
@@ -2198,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
 
@@ -2209,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
 
@@ -2352,7 +2351,7 @@ Hei sinn déi aktuell Astellunge fir d'Säit '''$1''':",
 
 # Restriction levels
 'restriction-level-sysop' => 'ganz gespaart',
-'restriction-level-autoconfirmed' => 'hallef-gespaart (nëmmen ugemellte Benotzer déi net nei sinn)',
+'restriction-level-autoconfirmed' => 'hallef gespaart (nëmmen ugemellt Benotzer déi net nei sinn)',
 'restriction-level-all' => 'alleguerten',
 
 # Undelete
@@ -2511,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',
@@ -2610,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.
@@ -2938,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 d596c8b..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' => 'Малумат',
@@ -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 7ac299a..0af7144 100644 (file)
@@ -7,6 +7,7 @@
  * @ingroup Language
  * @file
  *
+ * @author Amire80
  * @author Ashishanchinhar
  * @author Dhirendra.maithili
  * @author Ggajendra
@@ -160,7 +161,7 @@ $messages = array(
 'cancel' => 'समाप्त',
 'moredotdotdot' => 'आर...',
 'mypage' => 'हमर पन्ना',
-'mytalk' => 'हमर à¤µà¤¾à¤°à¥\8dतà¥\8dता',
+'mytalk' => 'वार्त्ता',
 'anontalk' => 'ऐ अनिकेत पता लेल विमर्श',
 'navigation' => 'संचार',
 'and' => '&#32;आर',
@@ -1048,7 +1049,7 @@ $3 द्वारा देल कारण अछि ''$2''",
 
 # Preferences page
 'preferences' => 'विकल्प',
-'mypreferences' => 'हमर à¤\96ासमà¤\96ास',
+'mypreferences' => 'खासमखास',
 'prefs-edits' => 'सम्पादनक संख्या',
 'prefsnologin' => 'सम्प्रवेशित नै',
 'prefsnologintext' => 'अहाँ <span class="plainlinks">[{{fullurl:{{#Special:UserLogin}}|returnto=$1}} logged in]</span> प्रयोक्ता विकल्प निर्धारण लेल प्रयोग करू।',
@@ -1924,8 +1925,8 @@ $1',
 'usermessage-template' => 'मीडियाविकी:प्रयोक्ता संदेश',
 
 # Watchlist
-'watchlist' => 'हमर à¤¸à¤¾à¤\95ाà¤\82à¤\95à¥\8dषसà¥\82à¤\9aà¥\80',
-'mywatchlist' => 'हमर à¤¸à¤¾à¤\95ाà¤\82à¤\95à¥\8dष-सà¥\82à¤\9aà¥\80',
+'watchlist' => 'साकांक्षसूची',
+'mywatchlist' => 'साकांक्ष-सूची',
 'watchlistfor2' => '$1 $2 लेल',
 'nowatchlist' => 'अहाँक साकांक्ष-सूचीमे कोनो बौस्तु नै अछि।',
 'watchlistanontext' => 'कृपा कऽ $1 अहाँक साकांक्ष-सूचीकेँ देखबा वा सम्पादित करबा लेल।',
@@ -2182,7 +2183,7 @@ $1',
 # Contributions
 'contributions' => 'प्रयोक्ताक योगदान सभ',
 'contributions-title' => '$1 लेल प्रयोक्ताक अवदान',
-'mycontris' => 'हमर à¤¯à¥\8bà¤\97दान',
+'mycontris' => 'योगदान',
 'contribsub2' => '$1 ($2) लेल',
 'nocontribs' => 'कोनो परिवर्तन ऐ सँ मेल नै खाइए।',
 'uctop' => '(शिखर)',
@@ -2223,7 +2224,7 @@ $1',
 'whatlinkshere-hideredirs' => '$1 घुरबैए',
 'whatlinkshere-hidetrans' => '$1 परागत',
 'whatlinkshere-hidelinks' => '$1 सम्बन्ध सभ',
-'whatlinkshere-hideimages' => '$1 à¤\9aितà¥\8dरà¤\95 लागि सभ',
+'whatlinkshere-hideimages' => '$1 à¤«à¤¾à¤\87ल लागि सभ',
 'whatlinkshere-filters' => 'चलनी सभ',
 
 # Block/unblock
index cdddf43..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',
index 665e870..561b020 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-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',
@@ -134,20 +134,20 @@ $messages = array(
 '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 laman ataupun media dalam kategori ko.''",
-'hidden-categories' => '{{PLURAL:$1|Kategori tapandam|Kategori tapandam}}',
+'hidden-categories' => '{{PLURAL:$1|Kategori tapandam}}',
 'hidden-category-category' => 'Kategori tasambunyi',
 'category-subcat-count' => '{{PLURAL:$2|Kategori ko punyo {{PLURAL:$1|$1 subkategori}}, dari total $2.}}',
-'category-subcat-count-limited' => 'Kategori iko mamiliki {{PLURAL:$1|subkategori|$1 subkategori}} barikuik.',
+'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|ciek laman|$1 laman}} barikuik.',
+'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|laman|$1 laman}} barikuik.',
-'listingcontinuesabbrev' => 'lanjuik',
+'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 gamba rusak',
@@ -160,7 +160,7 @@ $messages = array(
 'morenotlisted' => 'Salabiahnyo...',
 'mypage' => 'Laman',
 'mytalk' => 'Maota',
-'anontalk' => 'Ota IP iko',
+'anontalk' => 'Diskusi IP ko',
 'navigation' => 'Pinteh',
 'and' => '&#32;jo',
 
@@ -184,7 +184,7 @@ $messages = array(
 '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',
@@ -204,7 +204,7 @@ $messages = array(
 'history_short' => 'Riwayaik',
 'updatedmarker' => 'diubah sajak kunjuangan tarakhir ambo',
 'printableversion' => 'Versi cetak',
-'permalink' => 'Pranala permanen',
+'permalink' => 'Pautan parmanen',
 'print' => 'Cetak',
 'view' => 'Tampilkan',
 'edit' => 'Suntiang',
@@ -222,7 +222,7 @@ $messages = array(
 'unprotectthispage' => 'Tuka palindungan laman ko',
 'newpage' => 'Laman baru',
 'talkpage' => 'Musyawarahkan laman ko',
-'talkpagelinktext' => 'Maota',
+'talkpagelinktext' => 'maota',
 'specialpage' => 'Laman istimewa',
 'personaltools' => 'Pakakeh pribadi',
 'postcomment' => 'Bagian baru',
@@ -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',
@@ -278,7 +278,7 @@ $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|ciek dari kelompok}}: $1.',
+'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 ko. Caliak [[Special:Version|versi laman]]',
@@ -288,9 +288,9 @@ $1',
 'youhavenewmessages' => 'Awak punyo $1 ($2).',
 'newmessageslink' => 'pasan baru',
 'newmessagesdifflink' => 'parubahan tarakhia',
-'youhavenewmessagesfromusers' => 'Sanak mandapek $1 dari {{PLURAL:$3|another user|$3 users}} ($2)',
+'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' => 'Sanak mandapek pasan baru pado $1',
 'editsection' => 'suntiang',
@@ -306,7 +306,7 @@ $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' => 'Sindikasi umpan indak tasadio',
@@ -332,7 +332,7 @@ $1',
 
 # Main script and global functions
 'nosuchaction' => 'Indak ado tindakan tasabuik',
-'nosuchactiontext' => 'Tindakan nan diminta oleh URL tasabuik indak valid. Sanak mungkin salah mangetikkan URL, atau mangikuti suatu pranala nan ndak batua. Hal iko juo mungkin mangindikasikan suatu bug pado parangkaik lunak nan digunokan oleh {{SITENAME}}.',
+'nosuchactiontext' => 'Tindakan nan diminta dek URL tasabuik indak valid. Sanak mungkin salah mangetikkan URL, atau mangikuiki suatu pautan nan indak batua. Hal iko mungkin juo manunjuakan adonyo suatu bug pado parangkaik lunak nan dipagunoan dek {{SITENAME}}.',
 'nosuchspecialpage' => 'Indak ado laman istimewa tarsabuik',
 'nospecialpagetext' => '<strong>Sanak maminta laman istimewa nan indak sah.</strong>
 
@@ -358,7 +358,7 @@ Basis data manghasilkan kasalahan "$3: $4".',
 'readonlytext' => 'Basis data sadang dikunci tahadok masuakan baru. Panguruih nan malakukan panguncian mamberikan panjalehan sabagai berikut: <p>$1',
 '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.
+Hal ko biasonyo disababkan dek pautan usang ka pabaikkan tadahulu laman nan alah dihapuih.
 
 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.',
@@ -380,7 +380,7 @@ Silakan laporkan hal iko ka [[Special:ListUsers/sysop|pangurus]], sarato 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',
@@ -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''",
@@ -598,16 +598,16 @@ Sandi samantaro: $2',
 'bold_tip' => 'Teks taba',
 'italic_sample' => 'Teks miriang',
 'italic_tip' => 'Teks miriang',
-'link_sample' => 'Judul pranala',
-'link_tip' => 'Pranala internal',
-'extlink_sample' => 'http://www.hanyo-contoh.com judul pranala',
-'extlink_tip' => 'Pranala lua (ingek awalannyo http://)',
+'link_sample' => 'Judua pautan',
+'link_tip' => 'Pautan dalam',
+'extlink_sample' => 'http://www.anyo-contoh.com judua pautan',
+'extlink_tip' => 'Pautan lua (ingek awalannyo http://)',
 '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',
+'media_tip' => 'Pautan berkas',
 'sig_tip' => 'Tandotangan sanak jo waktu',
 'hr_tip' => 'Garih mandata',
 
@@ -686,8 +686,8 @@ Sanak dapek [[Special:Search/{{PAGENAME}}|malakukan pancarian untuak judul laman
 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].',
+Hal iko biasonyo disababkan dek pautan sijarah nan alah kadaluarsa ka laman nan alah diapuih.
+Rinciannyo dapek dicaliak di [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} log pangapuihan].',
 'userpage-userdoesnotexist' => 'Akun pangguno "<nowiki>$1</nowiki>" indak tadafta.',
 'userpage-userdoesnotexist-view' => 'Pangguno "$1" indak tadafta.',
 'blocked-notice-logextract' => 'Pangguno ko tangah diblokir.
@@ -784,13 +784,13 @@ 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]]',
@@ -804,7 +804,7 @@ Alah ado.',
 # Parser/template warnings
 '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.",
@@ -824,11 +824,11 @@ Uraian-uraian tu alah diabaikan.',
 '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',
@@ -857,7 +857,7 @@ Contoh: '''({{int:cur}})''' = bedo jo versi tarakhia, '''({{int:last}})''' = bed
 'history-show-deleted' => 'Hanyo nan dihapuih',
 'histfirst' => 'Nan lamo',
 'histlast' => 'Nan baru',
-'historysize' => '({{PLURAL:$1|bita|$1  bita}})',
+'historysize' => '({{PLURAL:$1|$1  bita}})',
 'historyempty' => '(kosong)',
 
 # Revision feed
@@ -937,7 +937,7 @@ Rinciannyo mungkin ado di [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAME
 '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-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)',
@@ -948,9 +948,9 @@ Rinciannyo mungkin ado di [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAME
 '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',
@@ -964,16 +964,54 @@ Cubo awali permintaan awak tu jo ''all:'' untuak mancari sado kandungan (tamasua
 'powersearch-togglenone' => 'Dak ado',
 
 # Preferences page
-'preferences' => 'Preferensi',
+'preferences' => 'Pangaturan',
 'mypreferences' => 'Pangaturan',
-'prefs-beta' => 'Fitur Beta',
-'prefs-datetime' => 'Tanggal dan waktu',
-'prefs-labs' => 'Fitur uji',
+'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',
@@ -987,27 +1025,85 @@ Cubo awali permintaan awak tu jo ''all:'' untuak mancari sado kandungan (tamasua
 'allowemail' => 'Izinkan pangguno lain mangirim surel',
 'prefs-searchoptions' => 'Cari',
 'prefs-namespaces' => 'Ruang namo',
-'defaultns' => 'Ataupun cari dalam ruang-ruang namo ko:',
+'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 kulit:',
+'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:',
+'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',
 
@@ -1015,7 +1111,12 @@ Alamaik surel tu indakkan tau dek urang nan manghubungi sanak tu.',
 '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}}',
@@ -1066,6 +1167,12 @@ Laman pado [[Special:Watchlist|pantauan Sanak]] ditandoi jo '''cetak taba'''.",
 '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',
@@ -1075,9 +1182,12 @@ Laman pado [[Special:Watchlist|pantauan Sanak]] ditandoi jo '''cetak taba'''.",
 '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-filesize' => 'Ukuran berkas',
 'filehist-comment' => 'Komen',
+'filehist-missing' => 'Berkas indak ado',
 'imagelinks' => 'Panggunoan berkas',
 'linkstoimage' => 'Barikuik ko {{PLURAL:$1|$1 laman nan takaik}} jo berkas:',
 'nolinkstoimage' => 'Indak ado laman nan batauik ka berkas ko.',
@@ -1126,7 +1236,7 @@ Katarangan dari [$2 laman kataranagn berkas] ditampilkan di bawah.',
 'categories' => 'Kategori',
 
 # Special:LinkSearch
-'linksearch' => 'Pranala lua',
+'linksearch' => 'Pancarian pautan lua',
 'linksearch-line' => '$1 tapauik dari $2',
 
 # Special:ListGroupRights
@@ -1208,7 +1318,7 @@ Awak dapek maubah tingkek perlindungannyo, walaupun indak pangaruah pado perlind
 # Contributions
 'contributions' => 'Jariah {{GENDER:$1|pangguno}}',
 'contributions-title' => 'Jariah pangguno untuak $1',
-'mycontris' => 'Jariah denai',
+'mycontris' => 'Jariah',
 'contribsub2' => 'Untuak $1 ($2)',
 'uctop' => '(ateh)',
 'month' => 'Dari bulan (dan sabalunnyo):',
@@ -1219,14 +1329,14 @@ Awak dapek maubah tingkek perlindungannyo, walaupun indak pangaruah pado perlind
 'sp-contributions-deleted' => 'kontribusi pangguno nan lah batiadoan',
 'sp-contributions-uploads' => 'muek',
 'sp-contributions-logs' => 'log',
-'sp-contributions-talk' => 'diskusi',
+'sp-contributions-talk' => 'maota',
 'sp-contributions-search' => 'Cari jariah',
 'sp-contributions-username' => 'Alamat IP atau namo pangguno:',
 'sp-contributions-toponly' => 'Hanyo manampilan suntiangan nan tarakhia',
 'sp-contributions-submit' => 'Cari',
 
 # What links here
-'whatlinkshere' => 'Pranala baliak',
+'whatlinkshere' => 'Pautan baliak',
 'whatlinkshere-title' => 'Laman yang bakaik ka "$1"',
 'whatlinkshere-page' => 'Laman:',
 'linkshere' => "Laman-laman ko bakaik ka '''[[:$1]]''':",
@@ -1236,10 +1346,10 @@ Awak dapek maubah tingkek perlindungannyo, walaupun indak pangaruah pado perlind
 'isimage' => 'tautan berkas',
 'whatlinkshere-prev' => '{{PLURAL:$1|sabalunnyo|sabalunnyo $1}}',
 'whatlinkshere-next' => '{{PLURAL:$1|salanjuiknyo|salanjuiknyo $1}}',
-'whatlinkshere-links' => '← pranala',
+'whatlinkshere-links' => '← pautan',
 'whatlinkshere-hideredirs' => '$1 pengalihan',
 'whatlinkshere-hidetrans' => '$1 transklusi',
-'whatlinkshere-hidelinks' => '$1 pranala',
+'whatlinkshere-hidelinks' => '$1 pautan',
 'whatlinkshere-hideimages' => '$1 pahubuang berkas',
 'whatlinkshere-filters' => 'Panapiah',
 
@@ -1257,17 +1367,21 @@ Awak dapek maubah tingkek perlindungannyo, walaupun indak pangaruah pado perlind
 '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.
+'movepagetext' => "Formulir di bawah ko digunoan untuak maubah namo suatu laman dan mamindahan sadonyo data riwayaik ka namo baru. 
+Judua lamo tu ka manjadi laman paraliahan manuju judua nan baru. 
+Awak dapek mampabarui paraliahan-paraliahan nan manuju ka judua lamo sacaro otomatis.
+Kok indak dipabarui sacaro otomatis, pastikan lah dipareso laman ko dari [[Special:DoubleRedirects|paraliahan ganda]] atau [[Special:BrokenRedirects|paralihan rusak]]. Awak batanggung-jawak untuak mamastian bahaso pautan tu taruih manyambuang ka laman nan saaruihnyo.
 
-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.
+Ingeklah bahaso laman ko '''indak''' ka bapindah apobilo lah ado laman nan manggunoan judua nan baru, kacuali bilo laman tu kosong atau marupoan laman paraliahan dan indak punyo riwayaik suntiangan. Aratinyo awak dapek maubah baliak namo laman ka namo samulo apobilo ado kasalahan, dan bahaso awak indak dapek manimpo laman nan 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:'''
+'''Paringatan!''' 
+Iko dapek maakibaikan parubahan nan indak dipakiroan pado laman nan populer; jadi pastikan awak paham akibaik tindakan ko sabalun malanjuikannyo.",
+'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',
@@ -1295,8 +1409,10 @@ Dalam kasus tu, apobilo diinginkan, awak dapek mamindahkan atau manggabuangkan l
 
 # Tooltip help for the actions
 'tooltip-pt-userpage' => 'Laman pangguno sanak',
-'tooltip-pt-mytalk' => 'Laman ota sanak',
-'tooltip-pt-preferences' => 'Preferensi denai',
+'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 disaranan untuak masuak log; walaupun indak wajib',
@@ -1332,9 +1448,10 @@ Sanak hanyo buliah mancaliak sumbernyo sajo',
 'tooltip-t-upload' => 'Muek berkas',
 'tooltip-t-specialpages' => 'Dafta dari sado laman istimewa',
 'tooltip-t-print' => 'Versi cetak dari laman ko',
-'tooltip-t-permalink' => 'Pranala permanen untuak revisi laman ko',
+'tooltip-t-permalink' => 'Pautan parmanen untuak revisi laman ko',
 'tooltip-ca-nstab-main' => 'Caliak isi laman',
 'tooltip-ca-nstab-user' => 'Caliak laman pangguno',
+'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',
@@ -1357,6 +1474,25 @@ Sanak hanyo buliah mancaliak 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',
@@ -1373,11 +1509,33 @@ Sanak hanyo buliah mancaliak sumbernyo sajo',
 '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-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',
@@ -1385,13 +1543,18 @@ Sanak hanyo buliah mancaliak sumbernyo sajo',
 '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:
+'bad_image_list' => 'Formatnyo adolah sabagai barikuik:
 
-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.',
+Anyo dafta babutia (barih nan dimulai jo tando *) nan dianggap.
+Pautan patamo pado barih musiti pautan ka berkas buruak.
+Satiok pautan salanjuiknyo pado barih nan samo dianggap pangacualian, yaitu laman-laman dima berkas ko bisa tacaliak.',
 
 /*
 Short names for language variants used for language conversion links.
@@ -1429,8 +1592,8 @@ Variants for Chinese language
 '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
@@ -1445,6 +1608,31 @@ 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)',
@@ -1459,15 +1647,25 @@ Nan lainnyo akan tasuruak sacaro default.
 '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 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',
@@ -1483,7 +1681,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..e16c6ac 100644 (file)
@@ -341,7 +341,7 @@ $messages = array(
 'tog-hidepatrolled' => 'റോന്തുചുറ്റിയ തിരുത്തുകൾ പുതിയമാറ്റങ്ങളിൽ പ്രദർശിപ്പിക്കാതിരിക്കുക',
 'tog-newpageshidepatrolled' => 'റോന്തുചുറ്റിയ താളുകൾ പുതിയതാളുകളുടെ പട്ടികയിൽ പ്രദർശിപ്പിക്കാതിരിക്കുക',
 'tog-extendwatchlist' => 'ഏറ്റവും പുതിയവ മാത്രമല്ല, എല്ലാ മാറ്റങ്ങളും ദൃശ്യമാകുന്ന വിധത്തിൽ ശ്രദ്ധിക്കുന്ന താളുകളുടെ പട്ടിക വികസിപ്പിക്കുക.',
-'tog-usenewrc' => 'സമീപകാല മാറ്റങ്ങൾ താളിലും ശ്രദ്ധിക്കുന്നവയുടെ പട്ടികയിലും മാറ്റങ്ങൾ താളിനനുസരിച്ച് ഗണമായി പ്രദർശിപ്പിക്കുക (ജാവാസ്ക്രിപ്റ്റ് ആവശ്യമാണ്)',
+'tog-usenewrc' => 'സമീപകാല മാറ്റങ്ങൾ, ശ്രദ്ധിക്കുന്നവയുടെ പട്ടിക എന്നീ താളുകളിലെ വിവരങ്ങൾ താളുകൾക്കനുസരിച്ചുള്ള കൂട്ടങ്ങളായി ഒതുക്കി പ്രദർശിപ്പിക്കുക (ജാവാസ്ക്രിപ്റ്റ് ആവശ്യമാണ്)',
 'tog-numberheadings' => 'ഉപവിഭാഗങ്ങൾക്ക് ക്രമസംഖ്യ കൊടുക്കുക',
 'tog-showtoolbar' => 'തിരുത്തൽ റ്റൂൾബാർ  പ്രദർശിപ്പിക്കുക (ജാവാസ്ക്രിപ്റ്റ്)',
 'tog-editondblclick' => 'താളുകളിൽ ഇരട്ട ക്ലിക്ക് ചെയ്യുമ്പോൾ തിരുത്താനനുവദിക്കുക (ജാവാസ്ക്രിപ്റ്റ്)',
@@ -1350,7 +1350,7 @@ $1",
 'search-interwiki-default' => '$1 ഫലങ്ങൾ:',
 'search-interwiki-more' => '(കൂടുതൽ)',
 'search-relatedarticle' => 'ബന്ധപ്പെട്ടവ',
-'mwsuggest-disable' => 'à´\85à´\9cà´¾à´\95àµ\8dà´¸àµ\8d à´¨à´¿àµ¼à´¦àµ\8dà´¦àµ\87à´¶à´\99àµ\8dà´\99ൾ à´µàµ\87à´£àµ\8dà´\9f',
+'mwsuggest-disable' => 'തിരà´\9aàµ\8dà´\9aിലിനàµ\81 à´¨à´¿àµ¼à´¦àµ\8dà´¦àµ\87à´¶à´\99àµ\8dà´\99ൾ à´¨àµ½à´\95àµ\81à´¨àµ\8dനതàµ\8d à´ªàµ\8dരവർതàµ\8dതനരഹിതമാà´\95àµ\8dà´\95àµ\81à´\95',
 'searcheverything-enable' => 'എല്ലാ നാമമേഖലകളും തിരയുക',
 'searchrelated' => 'ബന്ധപ്പെട്ടവ',
 'searchall' => 'എല്ലാം',
@@ -3118,6 +3118,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}})',
@@ -3132,6 +3133,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' => 'വിവരം',
index cc1a869..84b1507 100644 (file)
@@ -2653,12 +2653,13 @@ sahkan bahawa anda betul-betul mahu melakukan tindakan ini.',
 'move-page' => 'Pindahkan $1',
 'move-page-legend' => 'Pindahkan laman',
 'movepagetext' => "Menggunakan borang di bawah akan menukar nama halaman dan memindahkan segala sejarahnya kepada nama baru itu.
+
 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.
 
-Sila ingat bahasa halaman '''tidak''' akan dipindahkan jika tajuk barunya sudah diambil oleh halaman yang sedia ada, melainkan ia merupakan lencongan tanpa sebarang sejarah suntingan.
+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!'''
@@ -2983,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)',
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 48d2e38..34beed5 100644 (file)
@@ -198,25 +198,25 @@ $messages = array(
 'thu' => 'پنجشنبه',
 'fri' => 'جـومه',
 'sat' => 'شمبه',
-'january' => 'جـانـویـه',
+'january' => 'ژانویه',
 'february' => 'فوریه',
-'march' => 'مـارچ',
+'march' => 'مارس',
 'april' => 'آوریل',
 'may_long' => 'مه',
 'june' => 'ژوئن',
-'july' => 'جـولای',
+'july' => 'ژوئیه',
 'august' => 'ئـوگـه‌سـت',
 'september' => 'سـه‌پـتـه‌مـبـر',
 'october' => 'اکتبر',
 'november' => 'نـووه‌مـبـر',
 'december' => 'دسامبر',
-'january-gen' => 'جـانـویـه',
+'january-gen' => 'ژانویه',
 'february-gen' => 'فوریه',
 'march-gen' => 'مـارس',
 'april-gen' => 'آوریـل',
 'may-gen' => 'مه',
 'june-gen' => 'جـون',
-'july-gen' => 'جـولای',
+'july-gen' => 'ژوئیه',
 'august-gen' => 'ئوگـه‌سـت',
 'september-gen' => 'سـه‌پـتـه‌مـبـر',
 'october-gen' => 'اکتبر',
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 7c9cbe6..2cea497 100644 (file)
@@ -2339,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',
@@ -2458,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”',
@@ -2719,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',
@@ -2980,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
index 058870e..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.',
 
index 276eabf..93cca94 100644 (file)
@@ -12,6 +12,7 @@
  * @author Capmo
  * @author Crazymadlover
  * @author Daemorris
+ * @author Dicionarista
  * @author Francisco Leandro
  * @author Giro720
  * @author GoEThe
@@ -311,7 +312,7 @@ $magicWords = array(
 
 $messages = array(
 # User preference toggles
-'tog-underline' => 'Sublinhar links:',
+'tog-underline' => 'Sublinhar ligação:',
 'tog-justify' => 'Justificar parágrafos',
 'tog-hideminor' => 'Esconder edições menores nas mudanças recentes',
 'tog-hidepatrolled' => 'Esconder edições patrulhadas nas mudanças recentes',
@@ -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.',
@@ -745,7 +746,7 @@ Não se esqueça de personalizar as suas [[Special:Preferences|preferências]].'
 'gotaccount' => "Já possui uma conta? '''$1'''.",
 'gotaccountlink' => 'Autentique-se',
 'userlogin-resetlink' => 'Esqueceu-se do seu nome de utilizador ou da palavra-chave?',
-'createaccountmail' => 'por correio electrónico',
+'createaccountmail' => 'Usar uma palavra passe aleatória e temporária e enviar para o endereço de e-mail especificado abaixo',
 'createaccountreason' => 'Motivo:',
 'badretype' => 'As palavras-chave que introduziu não são iguais.',
 'userexists' => 'O nome de utilizador introduzido já existe.
@@ -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',
@@ -1406,7 +1407,7 @@ Note, no entanto, que a indexação da {{SITENAME}} neste motor de busca pode es
 'prefs-datetime' => 'Data e hora',
 'prefs-labs' => 'Funcionalidades dos laboratórios',
 'prefs-user-pages' => 'Páginas de utilizador',
-'prefs-personal' => 'Perfil de utilizador',
+'prefs-personal' => 'Dados do utilizador',
 'prefs-rc' => 'Mudanças recentes',
 'prefs-watchlist' => 'Páginas vigiadas',
 'prefs-watchlist-days' => 'Dias a mostrar nas mudanças às páginas vigiadas:',
@@ -1688,7 +1689,7 @@ Esta informação será pública.',
 'rcshowhidemine' => '$1 as minhas edições',
 'rclinks' => 'Mostrar as últimas $1 mudanças nos últimos $2 dias<br />$3',
 'diff' => 'dif',
-'hist' => 'hist',
+'hist' => 'his',
 'hide' => 'Esconder',
 'show' => 'Mostrar',
 'minoreditletter' => 'm',
@@ -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:',
@@ -2135,7 +2136,7 @@ Agora redirecciona para [[$2]].',
 'nbytes' => '$1 {{PLURAL:$1|byte|bytes}}',
 'ncategories' => '$1 {{PLURAL:$1|categoria|categorias}}',
 'ninterwikis' => '$1 {{PLURAL:$1|interwiki|interwikis}}',
-'nlinks' => '$1 {{PLURAL:$1|link|links}}',
+'nlinks' => '$1 {{PLURAL:$1|ligação|ligações}}',
 'nmembers' => '$1 {{PLURAL:$1|membro|membros}}',
 'nrevisions' => '$1 {{PLURAL:$1|edição|edições}}',
 'nviews' => '$1 {{PLURAL:$1|visita|visitas}}',
@@ -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,9 +2498,9 @@ 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-level-autoconfirmed' => 'Bloquear utilizadores novos e não registados',
-'protect-level-sysop' => 'Apenas administradores',
+'protect-fallback' => 'Permitir apenas utilizadores com o privilégio de "$1"',
+'protect-level-autoconfirmed' => 'Permitir apenas utilizadores auto-confirmados',
+'protect-level-sysop' => 'Permitir apenas administradores',
 'protect-summary-cascade' => 'em cascata',
 'protect-expiring' => 'expira a $1 (UTC)',
 'protect-expiring-local' => 'expira a $1',
@@ -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',
@@ -2884,7 +2885,7 @@ O último registo é apresentado abaixo para referência:",
 Escolha outro nome, por favor.',
 
 # Export
-'export' => 'Exportação de páginas',
+'export' => 'Exportar páginas',
 'exporttext' => 'Pode exportar o texto e o histórico de edições de uma página em particular para um ficheiro XML. Poderá então importar esse conteúdo noutra wiki que utilize o programa MediaWiki, através da [[Special:Import|página de importações]].
 
 Para exportar páginas, introduza os títulos na caixa de texto abaixo (um título por linha) e seleccione se deseja todas as versões, com as linhas de histórico de edições, ou apenas a edição actual e informações sobre a mais recente das edições.
@@ -3993,9 +3994,9 @@ Imagens serão apresentadas pelo browser na resolução máxima; ficheiros de ou
 'revdelete-content-hid' => 'conteúdo oculto',
 'revdelete-summary-hid' => 'sumário de edição oculto',
 'revdelete-uname-hid' => 'utilizador oculto',
-'revdelete-content-unhid' => 'conteúdo não oculto',
-'revdelete-summary-unhid' => 'sumário de edição não oculto',
-'revdelete-uname-unhid' => 'utilizador não oculto',
+'revdelete-content-unhid' => 'conteúdo desocultado',
+'revdelete-summary-unhid' => 'sumário de edição desocultado',
+'revdelete-uname-unhid' => 'utilizador desocultado',
 'revdelete-restricted' => 'restrições a administradores aplicadas',
 'revdelete-unrestricted' => 'restrições a administradores removidas',
 'logentry-move-move' => '$1 moveu a página $3 para $4',
index 7846686..4af987f 100644 (file)
@@ -19,6 +19,7 @@
  * @author Crazymadlover
  * @author Daemorris
  * @author Danielsouzat
+ * @author Dicionarista
  * @author Diego Queiroz
  * @author Eduardo.mps
  * @author Emufarmers
@@ -315,7 +316,7 @@ $magicWords = array(
 
 $messages = array(
 # User preference toggles
-'tog-underline' => 'Sublinhar links:',
+'tog-underline' => 'Sublinhar linques:',
 'tog-justify' => 'Justificar parágrafos',
 'tog-hideminor' => 'Ocultar edições menores nas mudanças recentes',
 'tog-hidepatrolled' => 'Ocultar edições patrulhadas nas mudanças recentes',
@@ -591,7 +592,7 @@ Veja a [[Special:Version|página sobre a versão do sistema]].',
 'editlink' => 'editar',
 'viewsourcelink' => 'ver código-fonte',
 'editsectionhint' => 'Editar seção: $1',
-'toc' => 'Conteúdo',
+'toc' => 'Índice',
 'showtoc' => 'exibir',
 'hidetoc' => 'ocultar',
 'collapsible-collapse' => 'Ocultar',
@@ -1096,7 +1097,7 @@ Ela já existia.',
 'defaultmessagetext' => 'Texto da mensagem padrão',
 'content-failed-to-parse' => 'Falha ao analisar o conteúdo $2 para o modelo $1: $3',
 'invalid-content-data' => 'Dados de conteúdo inválidos',
-'content-not-allowed-here' => 'O conteúdo de tipo "$1" não é permitido na página [[$2]]',
+'content-not-allowed-here' => 'Conteúdo do tipo "$1" não é permitido na página [[$2]]',
 
 # Content models
 'content-model-wikitext' => 'wikitexto',
@@ -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',
@@ -1404,7 +1405,7 @@ Note que os índices do sistema de busca externo poderão conter referências de
 'prefs-datetime' => 'Data e hora',
 'prefs-labs' => 'Características de laboratório',
 'prefs-user-pages' => 'Páginas de usuário',
-'prefs-personal' => 'Perfil de usuário',
+'prefs-personal' => 'Dados do usuário',
 'prefs-rc' => 'Mudanças recentes',
 'prefs-watchlist' => 'Lista de páginas vigiadas',
 'prefs-watchlist-days' => 'Dias a mostrar na lista de páginas vigiadas:',
@@ -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,20 +1673,20 @@ 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''').",
 'rclistfrom' => 'Mostrar as novas alterações a partir das $1',
 'rcshowhideminor' => '$1 edições menores',
-'rcshowhidebots' => '$1 bots',
+'rcshowhidebots' => '$1 robôs',
 'rcshowhideliu' => '$1 usuários registrados',
 'rcshowhideanons' => '$1 usuários anônimos',
 'rcshowhidepatr' => '$1 edições patrulhadas',
 'rcshowhidemine' => '$1 minhas edições',
 'rclinks' => 'Exibir as $1 alterações recentes feitas nos últimos $2 dias<br />$3',
 'diff' => 'dif',
-'hist' => 'hist',
+'hist' => 'his',
 'hide' => 'Ocultar',
 'show' => 'Exibir',
 'minoreditletter' => 'm',
@@ -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:',
@@ -2137,7 +2138,7 @@ Entradas <del>riscadas</del> foram resolvidas.',
 'nbytes' => '$1 {{PLURAL:$1|byte|bytes}}',
 'ncategories' => '$1 {{PLURAL:$1|categoria|categorias}}',
 'ninterwikis' => '$1 {{PLURAL:$1|interwiki|Interwikis}}',
-'nlinks' => '$1 {{PLURAL:$1|link|links}}',
+'nlinks' => '$1 {{PLURAL:$1|linque|linques}}',
 'nmembers' => '$1 {{PLURAL:$1|membro|membros}}',
 'nrevisions' => '$1 {{PLURAL:$1|revisão|revisões}}',
 'nviews' => '$1 {{PLURAL:$1|visita|visitas}}',
@@ -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.',
@@ -2748,7 +2749,7 @@ Consulte a [[Special:BlockList|lista de bloqueios]] para obter a lista de bloque
 'block-log-flags-anononly' => 'apenas usuários anônimos',
 'block-log-flags-nocreate' => 'criação de contas desabilitada',
 'block-log-flags-noautoblock' => 'bloqueio automático desabilitado',
-'block-log-flags-noemail' => 'impedido de enviar e-mail',
+'block-log-flags-noemail' => 'e-mail bloqueado',
 'block-log-flags-nousertalk' => 'impossibilitado de editar a própria página de discussão',
 'block-log-flags-angry-autoblock' => 'autobloqueio melhorado ativado',
 'block-log-flags-hiddenname' => 'nome de usuário oculto',
@@ -3139,7 +3140,7 @@ Tal bloqueio foi provavelmente causado por uma ligação para um ''website'' ext
 'pageinfo-watchers' => 'Número de vigilantes da 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',
@@ -3995,9 +3996,9 @@ As imagens serão exibidas em sua resolução máxima, outros tipos de arquivos
 'revdelete-content-hid' => 'conteúdo oculto',
 'revdelete-summary-hid' => 'sumário de edição oculto',
 'revdelete-uname-hid' => 'nome de usuário oculto',
-'revdelete-content-unhid' => 'conteúdo não oculto',
-'revdelete-summary-unhid' => 'sumário de edição não oculto',
-'revdelete-uname-unhid' => 'nome de usuário não oculto',
+'revdelete-content-unhid' => 'conteúdo desocultado',
+'revdelete-summary-unhid' => 'sumário de edição desocultado',
+'revdelete-uname-unhid' => 'nome de usuário desocultado',
 'revdelete-restricted' => 'restrições a administradores aplicadas',
 'revdelete-unrestricted' => 'restrições a administradores removidas',
 'logentry-move-move' => '$1 moveu a página $3 para $4',
index 5e40fbb..b5a72a0 100644 (file)
@@ -1067,7 +1067,8 @@ This message is displayed when someone tried to login and the CSRF failed (most
 
 Defaults to '''nocookieslogin''' ({{int:nocookieslogin}})",
 'noname' => 'Error message.',
-'loginsuccesstitle' => 'The title of the page saying that you are logged in. The content of the page is the message "[[MediaWiki:Loginsuccess/{{SUBPAGENAME}}]]".',
+'loginsuccesstitle' => 'The title of the page saying that you are logged in. The content of the page is the message {{msg-mw|Loginsuccess}}.
+{{Identical|Login successful}}',
 'loginsuccess' => 'The content of the page saying that you are logged in. The title of the page is "[[MediaWiki:Loginsuccesstitle/{{SUBPAGENAME}}|{{int:loginsuccesstitle}}]]". $1 is the name of the logged in user.
 
 <nowiki>{{</nowiki>[[Gender|GENDER]]<nowiki>}}</nowiki> is supported.',
@@ -3660,7 +3661,8 @@ $1 is the name of the shared repository. On wikimedia sites, $1 is {{msg-mw|shar
 'shared-repo' => 'This message can be used as parameter $1 in the following messages:
 * {{msg-mw|shared-repo-from}}
 * {{msg-mw|sharedupload}}, {{msg-mw|sharedupload-desc-here}}, {{msg-mw|sharedupload-desc-there}}',
-'shared-repo-name-wikimediacommons' => '{{optional}}',
+'shared-repo-name-wikimediacommons' => '{{optional}}
+{{Identical|Wikimedia Commons}}',
 'filepage.css' => '{{Optional}}',
 'upload-disallowed-here' => 'This message appears on an image page in place of the normal reupload link if they cannot upload - e.g. if the image page is upload protected and they do not have the right priviledge.',
 
@@ -3770,7 +3772,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]].
 
@@ -4757,7 +4760,8 @@ See also:
 See also:
 * {{msg-mw|Mycontris}}
 * {{msg-mw|Accesskey-pt-mycontris}}
-* {{msg-mw|Tooltip-pt-mycontris}}',
+* {{msg-mw|Tooltip-pt-mycontris}}
+{{Identical|Contribution}}',
 'contribsub2' => 'Contributions for "user" (links)
 {{Identical|For $1}}',
 'nocontribs' => 'Optional parameter: $1 is the user name',
@@ -4895,8 +4899,7 @@ Special pages use {{msg-mw|Nextn}} instead (still as an argument to {{msg-mw|Vie
 
 Example line:
 * [[Main Page]] ([[Special:WhatLinksHere/Main Page|{{int:whatlinkshere-links}}]])
-
-{{Identical|Links}}',
+{{Identical|Link}}',
 'whatlinkshere-hideredirs' => 'Filter option in [[Special:WhatLinksHere]]. Parameters:
 * $1 is the {{msg-mw|hide}} or {{msg-mw|show}}',
 'whatlinkshere-hidetrans' => 'First filter option in [[Special:WhatLinksHere]]. Parameters:
@@ -6523,6 +6526,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]]).",
@@ -7639,6 +7643,7 @@ See also:
 'exif-subjectdistancerange-0' => '{{Related|Exif-subjectdistancerange}}
 {{Identical|Unknown}}',
 'exif-subjectdistancerange-1' => 'Macro view is close-up photography. See [http://en.wikipedia.org/wiki/Macro_photography Wikipedia].
+{{Identical|Macro}}
 {{Related|Exif-subjectdistancerange}}',
 'exif-subjectdistancerange-2' => '{{Related|Exif-subjectdistancerange}}',
 'exif-subjectdistancerange-3' => '{{Related|Exif-subjectdistancerange}}',
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 3bec703..80d4285 100644 (file)
@@ -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',
index 3c96260..48d8dbe 100644 (file)
@@ -839,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' => 'Введённое имя участника уже используется.
@@ -2360,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' => 'Скрыть администраторов',
@@ -4104,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' => 'Инструменты против спама',
 
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 f96c25a..ce5cac7 100644 (file)
@@ -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}})',
index bee87f8..60a5d8d 100644 (file)
@@ -1355,7 +1355,7 @@ Detaljer kan hittas i [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}
 'search-interwiki-default' => 'Resultat i $1:',
 'search-interwiki-more' => '(mer)',
 'search-relatedarticle' => 'Relaterad',
-'mwsuggest-disable' => 'Avaktivera AJAX-förslag',
+'mwsuggest-disable' => 'Inaktivera sökförslag',
 'searcheverything-enable' => 'Sök i alla namnrymder',
 'searchrelated' => 'relaterad',
 'searchall' => 'alla',
@@ -3142,6 +3142,7 @@ Detta orsakades troligen av en länk till en svartlistad webbplats.',
 'pageinfo-robot-noindex' => 'Inte indexerbar',
 'pageinfo-views' => 'Antal visningar',
 'pageinfo-watchers' => 'Antal användare som bevakar sidan',
+'pageinfo-few-watchers' => 'Färre än $1 {{PLURAL:$1|bevakare}}',
 'pageinfo-redirects-name' => 'Omdirigeringar till denna sida',
 'pageinfo-subpages-name' => 'Undersidor till denna sida',
 'pageinfo-subpages-value' => '$1 ($2 {{PLURAL:$2|omdirigering|omdirigeringar}}; $3 {{PLURAL:$3|icke-omdirigering|icke-omdirigeringar}})',
index 2761d58..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',
index 8c1750e..67c8e48 100644 (file)
@@ -348,7 +348,7 @@ $messages = array(
 'faqpage' => 'Project:คำถามถามบ่อย',
 
 # Vector skin
-'vector-action-addsection' => 'à¹\80à¸\9eิà¹\88มสà¹\88วà¸\99ใหม่',
+'vector-action-addsection' => 'à¹\80à¸\9eิà¹\88มหัวà¸\82à¹\89อใหม่',
 'vector-action-delete' => 'ลบ',
 'vector-action-move' => 'เปลี่ยนชื่อ',
 'vector-action-protect' => 'ป้องกัน',
@@ -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' => 'ขณะนี้การปรับปรุงหน้านี้ถูกระงับ ข้อมูลในที่นี่จะไม่รีเฟรชเป็นปัจจุบัน',
@@ -586,7 +587,7 @@ $1',
 'customjsprotected' => 'คุณไม่มีสิทธิแก้ไขหน้าจาวาสคริปต์นี้ เนื่องจากหน้านี้มีการตั้งค่าส่วนบุคคลของผู้ใช้อื่น',
 'ns-specialprotected' => 'หน้าพิเศษไม่สามารถแก้ไขได้',
 'titleprotected' => "ชื่อเรื่องนี้ถูกป้องกันมิให้สร้างโดย [[User:$1|$1]] 
-เหตุผลที่ให้ไว้ คือ ''$2''",
+เหตุผลที่ให้ไว้คือ ''$2''",
 'invalidtitle-knownnamespace' => 'ชื่อที่มีเนมสเปซ "$2" กับข้อความ "$3" ไม่ถูกต้อง',
 'invalidtitle-unknownnamespace' => 'ชื่อที่ไม่ทราบเนมสเปซหมายเลข $1 กับข้อความ "$2" ไม่ถูกต้อง',
 'exception-nologin' => 'ไม่ได้ล็อกอิน',
@@ -648,8 +649,8 @@ $1',
 '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|การตั้งค่าผู้ใช้]]',
@@ -932,6 +934,7 @@ $1 เป็นผู้ดำเนินการบล็อก
 'defaultmessagetext' => 'ข้อความสารโดยปริยาย',
 
 # Content models
+'content-model-wikitext' => 'ข้อความวิกิ',
 'content-model-text' => 'ข้อความธรรมดา',
 'content-model-javascript' => 'จาวาสคริปต์',
 'content-model-css' => 'CSS',
@@ -1511,7 +1514,7 @@ $1",
 'rc_categories' => 'จำกัดเฉพาะหมวดหมู่ (แยกด้วย "|")',
 'rc_categories_any' => 'ใด ๆ',
 'rc-change-size-new' => '$1 ไบต์หลังปรับปรุง',
-'newsectionsummary' => '/* $1 */ à¸ªà¹\88วà¸\99ใหม่',
+'newsectionsummary' => '/* $1 */ à¸«à¸±à¸§à¸\82à¹\89อใหม่',
 'rc-enhanced-expand' => 'แสดงรายละเอียด (ต้องใช้จาวาสคริปต์)',
 'rc-enhanced-hide' => 'ซ่อนรายละเอียด',
 'rc-old-title' => 'เดิมถูกสร้างในชื่อ "$1"',
@@ -2405,7 +2408,7 @@ $1',
 'ipbotherreason' => 'เหตุผลอื่น',
 'ipbhidename' => 'ซ่อนผู้ใช้จากปูมการบล็อก และรายการผู้ที่ถูกบล็อก',
 'ipbwatchuser' => 'เฝ้าดูหน้าผู้ใช้และหน้าคุยกับผู้ใช้ของผู้ใช้รายนี้',
-'ipb-disableusertalk' => 'กันไม่ให้ผู้ใช้นี้แก้ไขหน้าคุยกับผู้ใช้ของตัวเองขณะถูกบล็อก',
+'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à¸\82อà¸\87à¸\95ัวà¹\80อà¸\87à¸\82à¸\93ะà¸\96ูà¸\81à¸\9aลà¹\87อà¸\81',
 'ipb-change-block' => 'บล็อกผู้ใช้อีกครั้งด้วยการตั้งค่าเหล่านี้',
 'ipb-confirm' => 'ยืนยันการบล็อก',
 'badipaddress' => 'เลขที่อยู่ไอพีไม่ถูกต้อง',
index b36da18..d07b794 100644 (file)
@@ -1840,7 +1840,7 @@ Goldanylýan protokollar: <code>$1</code>',
 'usermessage-editor' => 'Ulgam habarçysy',
 
 # Watchlist
-'watchlist' => 'Gözegçilik sanawym',
+'watchlist' => 'Gözegçilik sanawy',
 'mywatchlist' => 'Gözegçilik sanawy',
 'watchlistfor2' => '$1 üçin  $2',
 'nowatchlist' => 'Gözegçilik sanawyňyzda hiçhili sahypa ýok.',
@@ -2090,7 +2090,7 @@ $1',
 'blanknamespace' => '(Baş)',
 
 # Contributions
-'contributions' => 'Ulanyjynyň goşantlary',
+'contributions' => '{{GENDER:$1|Ulanyjy}} goşantlary',
 'contributions-title' => '$1 üçin ulanyjy goşantlary',
 'mycontris' => 'Goşantlar',
 'contribsub2' => '$1 ($2)',
index ab954fe..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.
@@ -1059,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.
@@ -2206,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.',
 
@@ -2219,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',
@@ -2251,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ışı',
@@ -2290,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',
@@ -2453,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',
@@ -2933,6 +2929,7 @@ 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
@@ -3073,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',
@@ -3123,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.',
@@ -3155,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',
 
@@ -3311,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',
@@ -3346,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',
@@ -3819,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 ce69a2b..152b92d 100644 (file)
@@ -9,6 +9,7 @@
  *
  * @author Alfredie
  * @author Arlin
+ * @author Calak
  * @author Kaganer
  * @author Reedy
  * @author Sahran
index 06ac565..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',
@@ -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 44e1dc8..e8deacd 100644 (file)
@@ -1330,7 +1330,7 @@ Xem chi tiết trong [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}}
 'search-interwiki-default' => '$1 kết quả:',
 'search-interwiki-more' => '(thêm)',
 'search-relatedarticle' => 'Liên quan',
-'mwsuggest-disable' => 'Tắt gợi ý bằng AJAX',
+'mwsuggest-disable' => 'Tắt gợi ý tìm kiếm',
 'searcheverything-enable' => 'Tìm trong tất cả không gian tên',
 'searchrelated' => 'có liên quan',
 'searchall' => 'tất cả',
@@ -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 .',
@@ -2761,7 +2761,7 @@ Bạn có thể cập nhật tự động các trang đổi hướng đến tên
 Nếu bạn chọn không cập nhật, hãy nhớ kiểm tra [[Special:DoubleRedirects|đổi hướng kép]] hoặc [[Special:BrokenRedirects|đổi hướng đến trang không tồn tại]].
 Bạn phải chịu trách nhiệm đảm bảo các liên kết đó tiếp tục trỏ đến nơi chúng cần đến.
 
-Chú ý rằng trang sẽ '''không''' bị di chuyển nếu đã có một trang tại tên mới, trừ khi  là trang đổi hướng và không có lịch sử sửa đổi trước đây.
+Chú ý rằng trang sẽ '''không''' bị di chuyển nếu đã có một trang tại tên mới, trừ khi trang tại tên mới là trang đổi hướng và không có lịch sử sửa đổi trước đây.
 Điều này có nghĩa là bạn có thể đổi tên trang lại như cũ nếu bạn có nhầm lẫn, và bạn không thể ghi đè lên một trang đã có sẵn.
 
 '''CẢNH BÁO!'''
@@ -3111,6 +3111,7 @@ Lưu nó vào máy tính của bạn rồi tải nó lên đây.',
 'pageinfo-robot-noindex' => 'Không thể ghi chỉ mục',
 'pageinfo-views' => 'Số lần xem',
 'pageinfo-watchers' => 'Số người theo dõi trang',
+'pageinfo-few-watchers' => 'Không tới $1 người theo dõi',
 'pageinfo-redirects-name' => 'Số trang đổi hướng đến trang này',
 'pageinfo-redirects-value' => '$1',
 'pageinfo-subpages-name' => 'Số trang con của trang này',
index 7917e29..fcc9b8b 100644 (file)
@@ -357,6 +357,9 @@ $messages = array(
 'youhavenewmessages' => 'Su pad ola binons $1 ($2).',
 'newmessageslink' => 'nuns nulik',
 'newmessagesdifflink' => 'votükam lätik',
+'youhavenewmessagesfromusers' => 'Labol $1 de {{PLURAL:$3|geban votik|gebans $3}} ($2).',
+'youhavenewmessagesmanyusers' => 'Labol $1 de gebans mödik ($2).',
+'newmessageslinkplural' => '{{PLURAL:$1|nuni nulik|nunis nulik}}',
 'youhavenewmessagesmulti' => 'Labol nunis nulik su $1',
 'editsection' => 'redakön',
 'editold' => 'redakön',
index 5a7da39..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' => 'ענדערן קאנטע פאסווארט',
@@ -1001,6 +1002,7 @@ $2
 'node-count-exceeded-category' => 'בלעטער וואו קנופצאל איז צו פיל',
 'node-count-exceeded-warning' => 'קנופנצאל אויפן בלאט צו הויך',
 'expansion-depth-exceeded-category' => "בלעטער וואו מ'האט אריבערגעשטיגן די פארברייטערונג טיף",
+'expansion-depth-exceeded-warning' => 'בלאט גייט אריבער דער פארברייטערונג טיף',
 'converter-manual-rule-error' => 'געטראפן א גרײַז אין האנטלעכן שפראך־קאנווערטירן כלל',
 
 # "Undo" feature
@@ -1230,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' => 'אלץ',
@@ -1731,6 +1733,7 @@ $1",
 'lockmanager-fail-deletelock' => 'נישט מעגלעך אויסמעקן שלאס טעקע פאר "$1".',
 
 # ZipDirectoryReader
+'zip-file-open-error' => 'געטראפן א גרײַז ביים עפענען די טעקע פאר ZIP־קאנטראלירונג.',
 'zip-wrong-format' => 'ספעציפירטע טעקע איז נישט קיין ZIP טעקע.',
 
 # Special:UploadStash
@@ -2277,6 +2280,7 @@ $UNWATCHURL
 'prot_1movedto2' => '[[$1]] אריבערגעפירט צו [[$2]]',
 'protect-badnamespace-title' => 'אומשיצבארער נאמענטייל',
 'protect-badnamespace-text' => 'בלעטער אין דעם נאמענטייל קען מען נישט שיצן.',
+'protect-norestrictiontypes-title' => 'נישט־שיצבארער בלאט',
 'protect-legend' => 'באַשטעטיגן שיץ',
 'protectcomment' => 'אורזאַך:',
 'protectexpiry' => 'גייט אויס:',
@@ -2585,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 בלאט צום נייעם קעפל.
 
 איר קענט דערהיינטיגן ווייטערפֿירונגען צום אלטן נאמען אויטאמאטיש.
 
@@ -3226,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° מיטן זייגער',
index c426b82..97ac129 100644 (file)
@@ -1617,7 +1617,7 @@ $1",
 'nchanges' => '$1次更改',
 'recentchanges' => '最近更改',
 'recentchanges-legend' => '最近更改选项',
-'recentchanges-summary' => '跟踪这个wiki上的最新更改。',
+'recentchanges-summary' => '在此页面上跟踪维基的更改。',
 'recentchanges-feed-description' => '跟踪订阅本wiki的最近更改。',
 'recentchanges-label-newpage' => '这次编辑建立了一个新页面',
 'recentchanges-label-minor' => '这是一个小编辑',
@@ -2190,7 +2190,7 @@ $1',
 
 # Special:ListGroupRights
 'listgrouprights' => '用户组权限',
-'listgrouprights-summary' => '以下面是一个在这个wiki中定义出来的用户权限列表,以及它们的访问权。
+'listgrouprights-summary' => '以下面是一个在这个维基中所定义出来的用户权限列表,以及它们的访问权。
 更多有关个别权限的细节可以在[[{{MediaWiki:Listgrouprights-helppage}}|这里]]找到。',
 'listgrouprights-key' => '* <span class="listgrouprights-granted">被授予的权限</span>
 * <span class="listgrouprights-revoked">被取消的权限</span>',
@@ -3039,6 +3039,7 @@ $1被封禁的理由是:“$2”',
 'pageinfo-robot-noindex' => '不可索引',
 'pageinfo-views' => '查看次数',
 'pageinfo-watchers' => '页面监视者人数',
+'pageinfo-few-watchers' => '少于$1名监视者',
 'pageinfo-redirects-name' => '重定向到本页',
 'pageinfo-subpages-name' => '本页的子页面',
 'pageinfo-subpages-value' => '$1 ($2个重定向;$3个非重定向)',
index b4ad181..b550cab 100644 (file)
@@ -670,7 +670,7 @@ $2',
 不要忘記設置[[Special:Preferences|{{SITENAME}}的個人參數]]。',
 'yourname' => '用戶名:',
 'yourpassword' => '您的密碼:',
-'yourpasswordagain' => '再次輸入密:',
+'yourpasswordagain' => '再次輸入密:',
 'remembermypassword' => '在這個瀏覽器上記住我的登入資訊(可維持 $1 {{PLURAL:$1|天|天}})',
 'securelogin-stick-https' => '登入後繼續以HTTPS連接',
 'yourdomainname' => '您的網域:',
@@ -1264,7 +1264,7 @@ $1",
 'search-interwiki-default' => '$1項結果:',
 'search-interwiki-more' => '(更多)',
 'search-relatedarticle' => '相關',
-'mwsuggest-disable' => '停用AJAX建議',
+'mwsuggest-disable' => '停用搜尋建議',
 'searcheverything-enable' => '在所有名字空間中搜尋',
 'searchrelated' => '相關',
 'searchall' => '所有',
@@ -2674,10 +2674,8 @@ $1被封禁的理由是“$2”',
 如果您選擇不去做的話,請檢查[[Special:DoubleRedirects|雙重]]或[[Special:BrokenRedirects|損壞重定向]]連結。
 您應當負責確定所有連結依然會連到指定的頁面。
 
-注意如果新頁面已經有內容的話,頁面將'''不會'''被移動,
-除非新頁面是重定向頁,而且沒有修訂歷史。
-這意味著您再必要時可以在移動到新頁面後再移回老的頁面,
-同時您也無法覆蓋現有頁面。
+注意如果新頁面已經有內容的話,頁面將'''不會'''被移動,除非新頁面是重定向頁,而且沒有修訂歷史。
+這意味著您再必要時可以在移動到新頁面後再移回老的頁面,同時您也無法覆蓋現有頁面。
 
 '''警告!'''
 對一個經常被訪問的頁面而言這可能是一個重大與唐突的更改;
@@ -3025,6 +3023,7 @@ $1被封禁的理由是“$2”',
 'pageinfo-robot-noindex' => '不可索引',
 'pageinfo-views' => '觀看次數',
 'pageinfo-watchers' => '頁面監視者數目',
+'pageinfo-few-watchers' => '少於$1名監視者',
 'pageinfo-redirects-name' => '重定向到此頁',
 'pageinfo-subpages-name' => '此頁面的子頁面',
 'pageinfo-subpages-value' => '$1 ($2 {{PLURAL:$2|重定向|重定向}}; $3 {{PLURAL:$3|非重定向|非重定向}})',
index 6bb0666..590cad2 100644 (file)
@@ -32,7 +32,7 @@
  * @ingroup Maintenance
  */
 class SevenZipStream {
-       var $stream;
+       protected $stream;
 
        private function stripPath( $path ) {
                $prefix = 'mediawiki.compress.7z://';
index 2a8b8e5..b2bbf9b 100644 (file)
@@ -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;
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 9fa7c8e..10c5cd0 100644 (file)
 require_once( __DIR__ . '/Benchmarker.php' );
 
 function bfNormalizeTitleStrTr( $str ) {
-    return strtr( $str, '_', ' ' );
+       return strtr( $str, '_', ' ' );
 }
 
 function bfNormalizeTitleStrReplace( $str ) {
-    return str_replace( '_', ' ', $str );
+       return str_replace( '_', ' ', $str );
 }
 
 /**
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 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 429e3b3..5e505eb 100644 (file)
@@ -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 032d6f9..fc38938 100644 (file)
@@ -48,6 +48,9 @@ class nextJobDB extends Maintenance {
                        $types = JobQueueGroup::singleton()->getDefaultQueueTypes();
                }
 
+               // Handle any required periodic queue maintenance
+               $this->executeReadyPeriodicTasks();
+
                $memcKey = 'jobqueue:dbs:v3';
                $pendingDbInfo = $wgMemc->get( $memcKey );
 
@@ -156,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 58fe880..b72c417 100644 (file)
@@ -32,22 +32,27 @@ 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->addOption( 'all', 'Purge all pages', false, false );
+               $this->addOption( 'delay', 'Number of seconds to delay between each purge', false, true );
+               $this->addOption( 'verbose', 'Show more output', false, false, 'v' );
                $this->setBatchSize( 100 );
        }
 
        public function execute() {
-               if( $this->hasOption( 'namespace' ) ) {
-                       $this->purgeNamespace();
+               if ( $this->hasOption( 'all' ) ) {
+                       $this->purgeNamespace( false );
+               } elseif ( $this->hasOption( 'namespace' ) ) {
+                       $this->purgeNamespace( intval( $this->getOption( 'namespace') ) );
                } else {
-                       $this->purgeList();
+                       $this->doPurge();
                }
                $this->output( "Done!\n" );
        }
 
        /** Purge URL coming from stdin */
-       private function purgeList() {
+       private function doPurge() {
                $stdin = $this->getStdin();
                $urls = array();
 
@@ -69,56 +74,41 @@ class PurgeList extends Maintenance {
                                }
                        }
                }
+               $this->output( "Purging " . count( $urls ). " urls\n" );
                $this->sendPurgeRequest( $urls );
        }
 
-       /** Purge a namespace given by --namespace */
-       private function purgeNamespace() {
+       /** Purge a namespace or all pages */
+       private function purgeNamespace( $namespace = false ) {
                $dbr = wfGetDB( DB_SLAVE );
-               $ns = $dbr->addQuotes( $this->getOption( 'namespace') );
-
-               $result = $dbr->select(
-                       array( 'page' ),
-                       array( 'page_namespace', 'page_title' ),
-                       array( "page_namespace = $ns" ),
-                       __METHOD__,
-                       array( 'ORDER BY' => 'page_id' )
-               );
-
-               $start   = 0;
-               $end = $result->numRows();
-               $this->output( "Will purge $end pages from namespace $ns\n" );
-
-               # Do remaining chunk
-               $end += $this->mBatchSize - 1;
-               $blockStart = $start;
-               $blockEnd = $start + $this->mBatchSize - 1;
-
-               while( $blockEnd <= $end ) {
-                       # Select pages we will purge:
-                       $result = $dbr->select(
-                               array( 'page' ),
-                               array( 'page_namespace', 'page_title' ),
-                               array( "page_namespace = $ns" ),
+               $startId = 0;
+               if ( $namespace === false ) {
+                       $conds = array();
+               } else {
+                       $conds = array( 'page_namespace' => $namespace );
+               }
+               while ( true ) {
+                       $res = $dbr->select( 'page', 
+                               array( 'page_id', 'page_namespace', 'page_title' ),
+                               $conds + array( 'page_id > ' . $dbr->addQuotes( $startId ) ),
                                __METHOD__,
-                               array( # conditions
-                                       'ORDER BY' => 'page_id',
-                                       'LIMIT'    => $this->mBatchSize,
-                                       'OFFSET'   => $blockStart,
+                               array(
+                                       'LIMIT' => $this->mBatchSize,
+                                       'ORDER BY' => 'page_id'
+
                                )
                        );
-                       # Initialize/reset URLs to be purged
+                       if ( !$res->numRows() ) {
+                               break;
+                       }
                        $urls = array();
-                       foreach( $result as $row ) {
+                       foreach ( $res as $row ) {
                                $title = Title::makeTitle( $row->page_namespace, $row->page_title );
                                $url = $title->getInternalUrl();
                                $urls[] = $url;
+                               $startId = $row->page_id;
                        }
-
                        $this->sendPurgeRequest( $urls );
-
-                       $blockStart += $this->mBatchSize;
-                       $blockEnd   += $this->mBatchSize;
                }
        }
 
@@ -127,9 +117,23 @@ class PurgeList extends Maintenance {
         * @param $urls array List of URLS to purge from squids
         */
        private function sendPurgeRequest( $urls ) {
-               $this->output( "Purging " . count( $urls ). " urls\n" );
-               $u = new SquidUpdate( $urls );
-               $u->doUpdate();
+               if ( $this->hasOption( 'delay' ) ) {
+                       $delay = floatval( $this->getOption( 'delay' ) );
+                       foreach ( $urls as $url ) {
+                               if ( $this->hasOption( 'verbose' ) ) {
+                                       $this->output( $url . "\n" );
+                               }
+                               $u = new SquidUpdate( array( $url ) );
+                               $u->doUpdate();
+                               usleep( $delay * 1e6 );
+                       }
+               } else {
+                       if ( $this->hasOption( 'verbose' ) ) {
+                               $this->output( implode( "\n", $urls ) . "\n"  );
+                       }
+                       $u = new SquidUpdate( $urls );
+                       $u->doUpdate();
+               }
        }
 
 }
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 0cf0217..f64b5e8 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 )
@@ -84,10 +90,16 @@ class RunJobs extends Maintenance {
                                // Perform the job (logging success/failure and runtime)...
                                $t = microtime( true );
                                $this->runJobsLog( $job->toString() . " STARTING" );
+
                                $status = $job->run();
+                               if ( !is_bool( $status ) ) {
+                                       wfWarn( $job->getType() . " job failed to return a boolean." );
+                                       $status = true; // sanity
+                               }
                                if ( $status ) {
                                        $group->ack( $job ); // done
                                }
+
                                $t = microtime( true ) - $t;
                                $timeMs = intval( $t * 1000 );
                                if ( !$status ) {
index 657c056..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
index 72e6775..9b0b576 100644 (file)
@@ -105,6 +105,7 @@ class MwSql extends Maintenance {
        public function sqlPrintResult( $res, $db ) {
                if ( !$res ) {
                        // Do nothing
+                       return;
                } elseif ( is_object( $res ) && $res->numRows() ) {
                        foreach ( $res as $row ) {
                                $this->output( print_r( $row, true ) );
index 31bae8e..be45a11 100644 (file)
 
 /**
  * Look for duplicate user table entries and optionally prune them.
+ *
+ * This is still used by our MysqlUpdater at:
+ * includes/installer/MysqlUpdater.php
+ *
  * @ingroup Maintenance
  */
 class UserDupes {
-       var $db;
-       var $reassigned;
-       var $trimmed;
-       var $failed;
+       private $db;
+       private $reassigned;
+       private $trimmed;
+       private $failed;
        private $outputCallback;
 
        function __construct( &$database, $outputCallback ) {
index 655be43..df83928 100644 (file)
@@ -31,6 +31,7 @@ require_once( __DIR__ . '/Maintenance.php' );
  */
 class WaitForSlave extends Maintenance {
        public function __construct() {
+               parent::__construct();
                $this->addArg( 'maxlag', 'How long to wait for the slaves, default 10 seconds', false );
        }
        public function execute() {
index 95f028a..cb8b1be 100644 (file)
@@ -22,7 +22,7 @@
 
 require_once( __DIR__ . '/includes/WebStart.php' );
 
-if( $wgRequest->getVal( 'ctype' ) == 'application/xml' ) {
+if ( $wgRequest->getVal( 'ctype' ) == 'application/xml' ) {
        // Makes testing tweaks about a billion times easier
        $ctype = 'application/xml';
 } else {
@@ -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();
 
@@ -78,7 +78,7 @@ $urls[] = array(
        'method' => 'get',
        'template' => $searchPage->getCanonicalURL( 'search={searchTerms}' ) );
 
-if( $wgEnableAPI ) {
+if ( $wgEnableAPI ) {
        // JSON interface for search suggestions.
        // Supported in Firefox 2 and later.
        $urls[] = array(
@@ -91,7 +91,7 @@ if( $wgEnableAPI ) {
 // general way than overriding the whole search engine...
 wfRunHooks( 'OpenSearchUrls', array( &$urls ) );
 
-foreach( $urls as $attribs ) {
+foreach ( $urls as $attribs ) {
        print Xml::element( 'Url', $attribs );
 }
 
index cbbf2ab..4117d97 100644 (file)
@@ -34,113 +34,111 @@ if ( isset( $_SERVER['MW_COMPILED'] ) ) {
        require ( __DIR__ . '/includes/WebStart.php' );
 }
 
-
 header( 'Content-Type: text/html; charset=utf-8' );
 
 ?>
 <!DOCTYPE html>
 <html>
 <head>
-<meta charset="UTF-8">
-<title>Profiling data</title>
-<style>
-       /* noc.wikimedia.org/base.css */
-
-       * {
-               margin: 0;
-               padding: 0;
-       }
-
-       body {
-               padding: 0.5em 1em;
-               background: #fff;
-               font: 14px/1.6 sans-serif;
-               color: #333;
-       }
+       <meta charset="UTF-8">
+       <title>Profiling data</title>
+       <style>
+               /* noc.wikimedia.org/base.css */
+
+               * {
+                       margin: 0;
+                       padding: 0;
+               }
 
-       p, ul, ol, table {
-               margin: 0.5em 0;
-       }
+               body {
+                       padding: 0.5em 1em;
+                       background: #fff;
+                       font: 14px/1.6 sans-serif;
+                       color: #333;
+               }
 
-       a {
-               color: #0645AD;
-               text-decoration: none;
-       }
+               p, ul, ol, table {
+                       margin: 0.5em 0;
+               }
 
-       a:hover {
-               text-decoration: underline;
-       }
+               a {
+                       color: #0645AD;
+                       text-decoration: none;
+               }
 
-       /*!
-        * Bootstrap v2.1.1
-        *
-        * Copyright 2012 Twitter, Inc
-        * Licensed under the Apache License v2.0
-        * http://www.apache.org/licenses/LICENSE-2.0
-        *
-        * Designed and built with all the love in the world @twitter by @mdo and @fat.
-        */
-
-       table {
-               max-width: 100%;
-               background-color: transparent;
-               border-collapse: collapse;
-               border-spacing: 0;
-       }
+               a:hover {
+                       text-decoration: underline;
+               }
 
-       .table {
-               width: 100%;
-               margin-bottom: 20px;
-       }
+               /*!
+                * Bootstrap v2.1.1
+                *
+                * Copyright 2012 Twitter, Inc
+                * Licensed under the Apache License v2.0
+                * http://www.apache.org/licenses/LICENSE-2.0
+                *
+                * Designed and built with all the love in the world @twitter by @mdo and @fat.
+                */
+
+               table {
+                       max-width: 100%;
+                       background-color: transparent;
+                       border-collapse: collapse;
+                       border-spacing: 0;
+               }
 
-       .table th,
-       .table td {
-               padding: 0.1em;
-               text-align: left;
-               vertical-align: top;
-               border-top: 1px solid #ddd;
-       }
+               .table {
+                       width: 100%;
+                       margin-bottom: 20px;
+               }
 
-       .table th {
-               font-weight: bold;
-       }
+               .table th,
+               .table td {
+                       padding: 0.1em;
+                       text-align: left;
+                       vertical-align: top;
+                       border-top: 1px solid #ddd;
+               }
 
-       .table thead th {
-               vertical-align: bottom;
-       }
+               .table th {
+                       font-weight: bold;
+               }
 
-       .table thead:first-child tr:first-child th,
-       .table thead:first-child tr:first-child td {
-               border-top: 0;
-       }
+               .table thead th {
+                       vertical-align: bottom;
+               }
 
-       .table tbody + tbody {
-               border-top: 2px solid #ddd;
-       }
+               .table thead:first-child tr:first-child th,
+               .table thead:first-child tr:first-child td {
+                       border-top: 0;
+               }
 
-       .table-condensed th,
-       .table-condensed td {
-               padding: 4px 5px;
-       }
+               .table tbody + tbody {
+                       border-top: 2px solid #ddd;
+               }
 
-       .table-striped tbody tr:nth-child(odd) td,
-       .table-striped tbody tr:nth-child(odd) th {
-               background-color: #f9f9f9;
-       }
+               .table-condensed th,
+               .table-condensed td {
+                       padding: 4px 5px;
+               }
 
-       .table-hover tbody tr:hover td,
-       .table-hover tbody tr:hover th {
-               background-color: #f5f5f5;
-       }
+               .table-striped tbody tr:nth-child(odd) td,
+               .table-striped tbody tr:nth-child(odd) th {
+                       background-color: #f9f9f9;
+               }
 
-       hr {
-               margin: 20px 0;
-               border: 0;
-               border-top: 1px solid #eee;
-               border-bottom: 1px solid #fff;
-       }
+               .table-hover tbody tr:hover td,
+               .table-hover tbody tr:hover th {
+                       background-color: #f5f5f5;
+               }
 
-</style>
+               hr {
+                       margin: 20px 0;
+                       border: 0;
+                       border-top: 1px solid #eee;
+                       border-bottom: 1px solid #fff;
+               }
+       </style>
 </head>
 <body>
 <?php
@@ -153,7 +151,7 @@ if ( !$wgEnableProfileInfo ) {
 
 $dbr = wfGetDB( DB_SLAVE );
 
-if( !$dbr->tableExists( 'profiling' ) ) {
+if ( !$dbr->tableExists( 'profiling' ) ) {
        echo '<p>No <code>profiling</code> table exists, so we can\'t show you anything.</p>'
                . '<p>If you want to log profiling data, enable <code>$wgProfileToDatabase</code>'
                . ' in your LocalSettings.php and run <code>maintenance/update.php</code> to'
@@ -163,9 +161,11 @@ if( !$dbr->tableExists( 'profiling' ) ) {
 }
 
 $expand = array();
-if ( isset( $_REQUEST['expand'] ) )
-       foreach( explode( ',', $_REQUEST['expand'] ) as $f )
+if ( isset( $_REQUEST['expand'] ) ) {
+       foreach ( explode( ',', $_REQUEST['expand'] ) as $f ) {
                $expand[$f] = true;
+       }
+}
 
 class profile_point {
        var $name;
@@ -212,19 +212,21 @@ class profile_point {
                        $extet = " <a id=\"{$anchor}\" href=\"{$url}#{$anchor}\">[–]</a>";
                }
                ?>
-               <tr>
-               <th><div style="margin-left: <?php echo (int)$indent; ?>em;">
-                       <?php echo htmlspecialchars( str_replace( ',', ', ', $this->name() ) ) . $extet ?>
-               </div></th>
+       <tr>
+               <th>
+                       <div style="margin-left: <?php echo (int)$indent; ?>em;">
+                               <?php echo htmlspecialchars( str_replace( ',', ', ', $this->name() ) ) . $extet ?>
+                       </div>
+               </th>
                <td class="mw-profileinfo-timep"><?php echo @wfPercent( $this->time() / self::$totaltime * 100 ); ?></td>
                <td class="mw-profileinfo-memoryp"><?php echo @wfPercent( $this->memory() / self::$totalmemory * 100 ); ?></td>
                <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>
-               </tr>
+               <td class="mw-profileinfo-mpr"><?php echo @round( sprintf( '%.2f'$this->memory() / self::$totalcount / 1024 ), 2 ); ?></td>
+       </tr>
                <?php
                if ( $ex ) {
                        foreach ( $this->children as $child ) {
@@ -274,135 +276,140 @@ class profile_point {
        }
 };
 
-function compare_point(profile_point $a, profile_point $b) {
+function compare_point( profile_point $a, profile_point $b ) {
        global $sort;
        switch ( $sort ) {
-       case 'name':
-               return strcmp( $a->name(), $b->name() );
-       case 'time':
-               return $a->time() > $b->time() ? -1 : 1;
-       case 'memory':
-               return $a->memory() > $b->memory() ? -1 : 1;
-       case 'count':
-               return $a->count() > $b->count() ? -1 : 1;
-       case 'time_per_call':
-               return $a->timePerCall() > $b->timePerCall() ? -1 : 1;
-       case 'memory_per_call':
-               return $a->memoryPerCall() > $b->memoryPerCall() ? -1 : 1;
-       case 'calls_per_req':
-               return $a->callsPerRequest() > $b->callsPerRequest() ? -1 : 1;
-       case 'time_per_req':
-               return $a->timePerRequest() > $b->timePerRequest() ? -1 : 1;
-       case 'memory_per_req':
-               return $a->memoryPerRequest() > $b->memoryPerRequest() ? -1 : 1;
+               case 'name':
+                       return strcmp( $a->name(), $b->name() );
+               case 'time':
+                       return $a->time() > $b->time() ? -1 : 1;
+               case 'memory':
+                       return $a->memory() > $b->memory() ? -1 : 1;
+               case 'count':
+                       return $a->count() > $b->count() ? -1 : 1;
+               case 'time_per_call':
+                       return $a->timePerCall() > $b->timePerCall() ? -1 : 1;
+               case 'memory_per_call':
+                       return $a->memoryPerCall() > $b->memoryPerCall() ? -1 : 1;
+               case 'calls_per_req':
+                       return $a->callsPerRequest() > $b->callsPerRequest() ? -1 : 1;
+               case 'time_per_req':
+                       return $a->timePerRequest() > $b->timePerRequest() ? -1 : 1;
+               case 'memory_per_req':
+                       return $a->memoryPerRequest() > $b->memoryPerRequest() ? -1 : 1;
        }
 }
 
 $sorts = array( 'time', 'memory', 'count', 'calls_per_req', 'name',
        'time_per_call', 'memory_per_call', 'time_per_req', 'memory_per_req' );
 $sort = 'time';
-if ( isset( $_REQUEST['sort'] ) && in_array( $_REQUEST['sort'], $sorts ) )
+if ( isset( $_REQUEST['sort'] ) && in_array( $_REQUEST['sort'], $sorts ) ) {
        $sort = $_REQUEST['sort'];
+}
 
 $res = $dbr->select( 'profiling', '*', array(), 'profileinfo.php', array( 'ORDER BY' => 'pf_name ASC' ) );
 
-if (isset( $_REQUEST['filter'] ) )
+if ( isset( $_REQUEST['filter'] ) ) {
        $filter = $_REQUEST['filter'];
-else
+} else {
        $filter = '';
+}
 
 ?>
 <form method="get" action="profileinfo.php">
-<p>
-<input type="text" name="filter" value="<?php echo htmlspecialchars($filter); ?>">
-<input type="hidden" name="sort" value="<?php echo htmlspecialchars($sort); ?>">
-<input type="hidden" name="expand" value="<?php echo htmlspecialchars(implode(",", array_keys($expand))); ?>">
-<input type="submit" value="Filter">
-</p>
+       <p>
+               <input type="text" name="filter" value="<?php echo htmlspecialchars( $filter ); ?>">
+               <input type="hidden" name="sort" value="<?php echo htmlspecialchars( $sort ); ?>">
+               <input type="hidden" name="expand" value="<?php echo htmlspecialchars( implode( ",", array_keys( $expand ) ) ); ?>">
+               <input type="submit" value="Filter">
+       </p>
 </form>
 
 <table class="mw-profileinfo-table table table-striped table-hover">
        <thead>
-               <tr>
-                       <th><a href="<?php echo getEscapedProfileUrl( false, 'name' ); ?>">Name</a></th>
-                       <th><a href="<?php echo getEscapedProfileUrl( false, 'time' ); ?>">Time (%)</a></th>
-                       <th><a href="<?php echo getEscapedProfileUrl( false, 'memory' ); ?>">Memory (%)</a></th>
-                       <th><a href="<?php echo getEscapedProfileUrl( false, 'count' ); ?>">Count</a></th>
-                       <th><a href="<?php echo getEscapedProfileUrl( false, 'calls_per_req' ); ?>">Calls/req</a></th>
-                       <th><a href="<?php echo getEscapedProfileUrl( false, 'time_per_call' ); ?>">ms/call</a></th>
-                       <th><a href="<?php echo getEscapedProfileUrl( false, 'memory_per_call' ); ?>">kb/call</a></th>
-                       <th><a href="<?php echo getEscapedProfileUrl( false, 'time_per_req' ); ?>">ms/req</a></th>
-                       <th><a href="<?php echo getEscapedProfileUrl( false, 'memory_per_req' ); ?>">kb/req</a></th>
-               </tr>
+       <tr>
+               <th><a href="<?php echo getEscapedProfileUrl( false, 'name' ); ?>">Name</a></th>
+               <th><a href="<?php echo getEscapedProfileUrl( false, 'time' ); ?>">Time (%)</a></th>
+               <th><a href="<?php echo getEscapedProfileUrl( false, 'memory' ); ?>">Memory (%)</a></th>
+               <th><a href="<?php echo getEscapedProfileUrl( false, 'count' ); ?>">Count</a></th>
+               <th><a href="<?php echo getEscapedProfileUrl( false, 'calls_per_req' ); ?>">Calls/req</a></th>
+               <th><a href="<?php echo getEscapedProfileUrl( false, 'time_per_call' ); ?>">ms/call</a></th>
+               <th><a href="<?php echo getEscapedProfileUrl( false, 'memory_per_call' ); ?>">kb/call</a></th>
+               <th><a href="<?php echo getEscapedProfileUrl( false, 'time_per_req' ); ?>">ms/req</a></th>
+               <th><a href="<?php echo getEscapedProfileUrl( false, 'memory_per_req' ); ?>">kb/req</a></th>
+       </tr>
        </thead>
        <tbody>
-<?php
-profile_point::$totaltime = 0.0;
-profile_point::$totalcount = 0;
-profile_point::$totalmemory = 0.0;
-
-function getEscapedProfileUrl( $_filter = false, $_sort = false, $_expand = false ) {
-       global $filter, $sort, $expand;
-
-       if ( $_expand === false )
-               $_expand = $expand;
-
-       return htmlspecialchars(
-               '?' .
-               wfArrayToCgi( array(
-                       'filter' => $_filter ? $_filter : $filter,
-                       'sort' => $_sort ? $_sort : $sort,
-                       'expand' => implode( ',', array_keys( $_expand ) )
-               ) )
-       );
-}
+       <?php
+       profile_point::$totaltime = 0.0;
+       profile_point::$totalcount = 0;
+       profile_point::$totalmemory = 0.0;
 
-$points = array();
-$queries = array();
-$sqltotal = 0.0;
-
-$last = false;
-foreach( $res as $o ) {
-       $next = new profile_point( $o->pf_name, $o->pf_count, $o->pf_time, $o->pf_memory );
-       if( $next->name() == '-total' ) {
-               profile_point::$totaltime = $next->time();
-               profile_point::$totalcount = $next->count();
-               profile_point::$totalmemory = $next->memory();
-       }
-       if ( $last !== false ) {
-               if ( preg_match( '/^'.preg_quote( $last->name(), '/' ).'/', $next->name() ) ) {
-                       $last->add_child($next);
-                       continue;
+       function getEscapedProfileUrl( $_filter = false, $_sort = false, $_expand = false ) {
+               global $filter, $sort, $expand;
+
+               if ( $_expand === false ) {
+                       $_expand = $expand;
+               }
+
+               return htmlspecialchars(
+                       '?' .
+                               wfArrayToCgi( array(
+                                       'filter' => $_filter ? $_filter : $filter,
+                                       'sort' => $_sort ? $_sort : $sort,
+                                       'expand' => implode( ',', array_keys( $_expand ) )
+                               ) )
+               );
+       }
+
+       $points = array();
+       $queries = array();
+       $sqltotal = 0.0;
+
+       $last = false;
+       foreach ( $res as $o ) {
+               $next = new profile_point( $o->pf_name, $o->pf_count, $o->pf_time, $o->pf_memory );
+               if ( $next->name() == '-total' ) {
+                       profile_point::$totaltime = $next->time();
+                       profile_point::$totalcount = $next->count();
+                       profile_point::$totalmemory = $next->memory();
+               }
+               if ( $last !== false ) {
+                       if ( preg_match( '/^' . preg_quote( $last->name(), '/' ) . '/', $next->name() ) ) {
+                               $last->add_child( $next );
+                               continue;
+                       }
+               }
+               $last = $next;
+               if ( preg_match( '/^query: /', $next->name() ) || preg_match( '/^query-m: /', $next->name() ) ) {
+                       $sqltotal += $next->time();
+                       $queries[] = $next;
+               } else {
+                       $points[] = $next;
                }
        }
-       $last = $next;
-       if ( preg_match( '/^query: /', $next->name() ) || preg_match( '/^query-m: /', $next->name() ) ) {
-               $sqltotal += $next->time();
-               $queries[] = $next;
-       } else {
-               $points[] = $next;
-       }
-}
 
-$s = new profile_point( 'SQL Queries', 0, $sqltotal, 0, 0 );
-foreach ( $queries as $q )
-       $s->add_child($q);
-$points[] = $s;
+       $s = new profile_point( 'SQL Queries', 0, $sqltotal, 0, 0 );
+       foreach ( $queries as $q )
+               $s->add_child( $q );
+       $points[] = $s;
 
-usort( $points, 'compare_point' );
+       usort( $points, 'compare_point' );
 
-foreach ( $points as $point ) {
-       if ( strlen( $filter ) && !strstr( $point->name(), $filter ) )
-               continue;
+       foreach ( $points as $point ) {
+               if ( strlen( $filter ) && !strstr( $point->name(), $filter ) ) {
+                       continue;
+               }
 
-       $point->display( $expand );
-}
-?>
+               $point->display( $expand );
+       }
+       ?>
        </tbody>
 </table>
 <hr>
-<p>Total time: <code><?php printf('%5.02f', profile_point::$totaltime); ?></code></p>
-<p>Total memory: <code><?php printf('%5.02f', profile_point::$totalmemory / 1024 ); ?></code></p>
-<hr>
+<p>Total time: <code><?php printf( '%5.02f', profile_point::$totaltime ); ?></code></p>
+
+<p>Total memory: <code><?php printf( '%5.02f', profile_point::$totalmemory / 1024 ); ?></code></p>
+<hr />
 </body>
 </html>
index d880079..51bf05f 100644 (file)
@@ -195,6 +195,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 303b18f..3448b7a 100644 (file)
@@ -79,13 +79,16 @@ $.suggestions = {
         * @param {Boolean} delayed Whether or not to delay this by the currently configured amount of time
         */
        update: function ( context, delayed ) {
-               // Only fetch if the value in the textbox changed and is not empty
+               // Only fetch if the value in the textbox changed and is not empty, or if the results were hidden
                // if the textbox is empty then clear the result div, but leave other settings intouched
                function maybeFetch() {
                        if ( context.data.$textbox.val().length === 0 ) {
                                context.data.$container.hide();
                                context.data.prevText = '';
-                       } else if ( context.data.$textbox.val() !== context.data.prevText ) {
+                       } else if (
+                               context.data.$textbox.val() !== context.data.prevText ||
+                               !context.data.$container.is( ':visible' )
+                       ) {
                                if ( typeof context.config.fetch === 'function' ) {
                                        context.data.prevText = context.data.$textbox.val();
                                        context.config.fetch.call( context.data.$textbox, context.data.$textbox.val() );
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..183b525 100644 (file)
                                'SITENAME' : mw.config.get( 'wgSiteName' )
                        },
                        messages : mw.messages,
-                       language : mw.language
+                       language : mw.language,
+
+                       // Same meaning as in mediawiki.js.
+                       //
+                       // Only 'text', 'parse', and 'escaped' are supported, and the
+                       // actual escaping for 'escaped' is done by other code (generally
+                       // through jqueryMsg).
+                       //
+                       // However, note that this default only
+                       // applies to direct calls to jqueryMsg. The default for mediawiki.js itself
+                       // is 'text', including when it uses jqueryMsg.
+                       format: 'parse'
+
                };
 
        /**
         * @return {Function} function suitable for assigning to window.gM
         */
        mw.jqueryMsg.getMessageFunction = function ( options ) {
-               var failableParserFn = getFailableParserFn( options );
+               var failableParserFn = getFailableParserFn( options ),
+                       format;
+
+               if ( options && options.format !== undefined ) {
+                       format = options.format;
+               } else {
+                       format = parserDefaults.format;
+               }
+
                /**
                 * N.B. replacements are variadic arguments or an array in second parameter. In other words:
                 *    somefunction(a, b, c, d)
                 * @return {string} Rendered HTML.
                 */
                return function () {
-                       return failableParserFn( arguments ).html();
+                       var failableResult = failableParserFn( arguments );
+                       if ( format === 'text' || format === 'escaped' ) {
+                               return failableResult.text();
+                       } else {
+                               return failableResult.html();
+                       }
                };
        };
 
         */
        mw.jqueryMsg.parser = function ( options ) {
                this.settings = $.extend( {}, parserDefaults, options );
+               this.settings.onlyCurlyBraceTransform = ( this.settings.format === 'text' || this.settings.format === 'escaped' );
+
                this.emitter = new mw.jqueryMsg.htmlEmitter( this.settings.language, this.settings.magic );
        };
 
        mw.jqueryMsg.parser.prototype = {
-               // cache, map of mediaWiki message key to the AST of the message. In most cases, the message is a string so this is identical.
-               // (This is why we would like to move this functionality server-side).
+               /**
+                * Cache mapping MediaWiki message keys and the value onlyCurlyBraceTransform, to the AST of the message.
+                *
+                * In most cases, the message is a string so this is identical.
+                * (This is why we would like to move this functionality server-side).
+                *
+                * The two parts of the key are separated by colon.  For example:
+                *
+                * "message-key:true": ast
+                *
+                * if they key is "message-key" and onlyCurlyBraceTransform is true.
+                *
+                * This cache is shared by all instances of mw.jqueryMsg.parser.
+                *
+                * @static
+                */
                astCache: {},
 
                /**
                 * @return {String|Array} string of '[key]' if message missing, simple string if possible, array of arrays if needs parsing
                 */
                getAst: function ( key ) {
-                       if ( this.astCache[ key ] === undefined ) {
-                               var wikiText = this.settings.messages.get( key );
+                       var cacheKey = [key, this.settings.onlyCurlyBraceTransform].join( ':' ), wikiText;
+
+                       if ( this.astCache[ cacheKey ] === undefined ) {
+                               wikiText = this.settings.messages.get( key );
                                if ( typeof wikiText !== 'string' ) {
                                        wikiText = '\\[' + key + '\\]';
                                }
-                               this.astCache[ key ] = this.wikiTextToAst( wikiText );
+                               this.astCache[ cacheKey ] = this.wikiTextToAst( wikiText );
                        }
-                       return this.astCache[ key ];
+                       return this.astCache[ cacheKey ];
                },
-               /*
+
+               /**
                 * Parses the input wikiText into an abstract syntax tree, essentially an s-expression.
                 *
                 * CAVEAT: This does not parse all wikitext. It could be more efficient, but it's pretty good already.
                 */
                wikiTextToAst: function ( input ) {
                        var pos,
-                               regularLiteral, regularLiteralWithoutBar, regularLiteralWithoutSpace, backslash, anyCharacter,
-                               escapedOrLiteralWithoutSpace, escapedOrLiteralWithoutBar, escapedOrRegularLiteral,
+                               regularLiteral, regularLiteralWithoutBar, regularLiteralWithoutSpace, regularLiteralWithSquareBrackets,
+                               backslash, anyCharacter, escapedOrLiteralWithoutSpace, escapedOrLiteralWithoutBar, escapedOrRegularLiteral,
                                whitespace, dollar, digits,
                                openExtlink, closeExtlink, wikilinkPage, wikilinkContents, openLink, closeLink, templateName, pipe, colon,
                                templateContents, openTemplate, closeTemplate,
-                               nonWhitespaceExpression, paramExpression, expression, result;
+                               nonWhitespaceExpression, paramExpression, expression, curlyBraceTransformExpression, result;
 
                        // Indicates current position in input as we parse through it.
                        // Shared among all parsing functions below.
                        regularLiteral = makeRegexParser( /^[^{}\[\]$\\]/ );
                        regularLiteralWithoutBar = makeRegexParser(/^[^{}\[\]$\\|]/);
                        regularLiteralWithoutSpace = makeRegexParser(/^[^{}\[\]$\s]/);
+                       regularLiteralWithSquareBrackets = makeRegexParser( /^[^{}$\\]/ );
                        backslash = makeStringParser( '\\' );
                        anyCharacter = makeRegexParser( /^./ );
                        function escapedLiteral() {
                        ] );
                        // Used to define "literals" without spaces, in space-delimited situations
                        function literalWithoutSpace() {
-                                var result = nOrMore( 1, escapedOrLiteralWithoutSpace )();
-                                return result === null ? null : result.join('');
+                               var result = nOrMore( 1, escapedOrLiteralWithoutSpace )();
+                               return result === null ? null : result.join('');
                        }
                        // Used to define "literals" within template parameters. The pipe character is the parameter delimeter, so by default
                        // it is not a literal in the parameter
                        function literalWithoutBar() {
-                                var result = nOrMore( 1, escapedOrLiteralWithoutBar )();
-                                return result === null ? null : result.join('');
+                               var result = nOrMore( 1, escapedOrLiteralWithoutBar )();
+                               return result === null ? null : result.join('');
                        }
 
                        // Used for wikilink page names.  Like literalWithoutBar, but
                        }
 
                        function literal() {
-                                var result = nOrMore( 1, escapedOrRegularLiteral )();
-                                return result === null ? null : result.join('');
+                               var result = nOrMore( 1, escapedOrRegularLiteral )();
+                               return result === null ? null : result.join('');
                        }
+
+                       function curlyBraceTransformExpressionLiteral() {
+                               var result = nOrMore( 1, regularLiteralWithSquareBrackets )();
+                               return result === null ? null : result.join('');
+                       }
+
                        whitespace = makeRegexParser( /^\s+/ );
                        dollar = makeStringParser( '$' );
                        digits = makeRegexParser( /^\d+/ );
                                literal
                        ] );
 
-                       function start() {
-                               var result = nOrMore( 0, expression )();
+                       // Used when only {{-transformation is wanted, for 'text'
+                       // or 'escaped' formats
+                       curlyBraceTransformExpression = choice( [
+                               template,
+                               replacement,
+                               curlyBraceTransformExpressionLiteral
+                       ] );
+
+
+                       /**
+                        * Starts the parse
+                        *
+                        * @param {Function} rootExpression root parse function
+                        */
+                       function start( rootExpression ) {
+                               var result = nOrMore( 0, rootExpression )();
                                if ( result === null ) {
                                        return null;
                                }
                        // everything above this point is supposed to be stateless/static, but
                        // I am deferring the work of turning it into prototypes & objects. It's quite fast enough
                        // finally let's do some actual work...
-                       result = start();
+
+                       // If you add another possible rootExpression, you must update the astCache key scheme.
+                       result = start( this.settings.onlyCurlyBraceTransform ? curlyBraceTransformExpression : expression );
 
                        /*
                         * For success, the p must have gotten to the end of the input
 
                /**
                 * 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
                 */
        // Replace the default message parser with jqueryMsg
        oldParser = mw.Message.prototype.parser;
        mw.Message.prototype.parser = function () {
+               var messageFunction;
+
                // TODO: should we cache the message function so we don't create a new one every time? Benchmark this maybe?
                // 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 );
                }
-               var messageFunction = mw.jqueryMsg.getMessageFunction( { 'messages': this.map } );
+
+               messageFunction = mw.jqueryMsg.getMessageFunction( {
+                       'messages': this.map,
+                       // For format 'escaped', escaping part is handled by mediawiki.js
+                       'format': this.format
+               } );
                return messageFunction( this.key, this.parameters );
        };
 
index b0abc9e..68a3a09 100644 (file)
@@ -127,7 +127,7 @@ var mw = ( function ( $, undefined ) {
         * @return Message
         */
        function Message( map, key, parameters ) {
-               this.format = 'plain';
+               this.format = 'text';
                this.map = map;
                this.key = key;
                this.parameters = parameters === undefined ? [] : slice.call( parameters );
@@ -136,9 +136,13 @@ var mw = ( function ( $, undefined ) {
 
        Message.prototype = {
                /**
-                * Simple message parser, does $N replacement and nothing else.
+                * Simple message parser, does $N replacement, HTML-escaping (only for
+                * 'escaped' format), and nothing else.
+                *
                 * This may be overridden to provide a more complex message parser.
                 *
+                * The primary override is in mediawiki.jqueryMsg.
+                *
                 * This function will not be called for nonexistent messages.
                 */
                parser: function () {
@@ -173,18 +177,14 @@ var mw = ( function ( $, undefined ) {
 
                        if ( !this.exists() ) {
                                // Use <key> as text if key does not exist
-                               if ( this.format !== 'plain' ) {
-                                       // format 'escape' and 'parse' need to have the brackets and key html escaped
+                               if ( this.format === 'escaped' || this.format === 'parse' ) {
+                                       // format 'escaped' and 'parse' need to have the brackets and key html escaped
                                        return mw.html.escape( '<' + this.key + '>' );
                                }
                                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 === 'text' || this.format === 'parse' ) {
                                text = this.parser();
                        }
 
@@ -193,15 +193,16 @@ var mw = ( function ( $, undefined ) {
                                text = mw.html.escape( text );
                        }
 
-                       if ( this.format === 'parse' ) {
-                               text = this.parser();
-                       }
-
                        return text;
                },
 
                /**
-                * Changes format to parse and converts message to string
+                * Changes format to 'parse' and converts message to string
+                *
+                * If jqueryMsg is loaded, this parses the message text from wikitext
+                * (where supported) to HTML
+                *
+                * Otherwise, it is equivalent to plain.
                 *
                 * @return {string} String form of parsed message
                 */
@@ -211,7 +212,10 @@ var mw = ( function ( $, undefined ) {
                },
 
                /**
-                * Changes format to plain and converts message to string
+                * Changes format to 'plain' and converts message to string
+                *
+                * This substitutes parameters, but otherwise does not change the
+                * message text.
                 *
                 * @return {string} String form of plain message
                 */
@@ -221,7 +225,23 @@ var mw = ( function ( $, undefined ) {
                },
 
                /**
-                * Changes the format to html escaped and converts message to string
+                * Changes format to 'text' and converts message to string
+                *
+                * If jqueryMsg is loaded, {{-transformation is done where supported
+                * (such as {{plural:}}, {{gender:}}, {{int:}}).
+                *
+                * Otherwise, it is equivalent to plain.
+                */
+               text: function () {
+                       this.format = 'text';
+                       return this.toString();
+               },
+
+               /**
+                * Changes the format to 'escaped' and converts message to string
+                *
+                * This is equivalent to using the 'text' format (see text method), then
+                * HTML-escaping the output.
                 *
                 * @return {string} String form of html escaped message
                 */
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 c4349c6..ee68abb 100644 (file)
@@ -230,7 +230,7 @@ class VectorTemplate extends BaseTemplate {
                <div id="mw-navigation">
                        <h2><?php $this->msg( 'navigation-heading' ) ?></h2>
                        <!-- header -->
-                       <div id="mw-head" class="noprint">
+                       <div id="mw-head">
                                <?php $this->renderNavigation( 'PERSONAL' ); ?>
                                <div id="left-navigation">
                                        <?php $this->renderNavigation( array( 'NAMESPACES', 'VARIANTS' ) ); ?>
@@ -241,7 +241,7 @@ class VectorTemplate extends BaseTemplate {
                        </div>
                        <!-- /header -->
                        <!-- panel -->
-                       <div id="mw-panel" class="noprint">
+                       <div id="mw-panel">
                                <!-- logo -->
                                        <div id="p-logo" role="banner"><a style="background-image: url(<?php $this->text( 'logopath' ) ?>);" href="<?php echo htmlspecialchars( $this->data['nav_urls']['mainpage']['href'] ) ?>" <?php echo Xml::expandAttributes( Linker::tooltipAndAccesskeyAttribs( 'p-logo' ) ) ?>></a></div>
                                <!-- /logo -->
index aa75a2a..1fe750e 100644 (file)
@@ -831,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),
@@ -838,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),
@@ -855,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) {
@@ -1073,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 28501ea..77dc7d4 100644 (file)
@@ -32,7 +32,7 @@ define( 'SELENIUMTEST', true );
 require( __DIR__ . '/../maintenance/Maintenance.php' );
 
 require_once( 'PHPUnit/Runner/Version.php' );
-if( version_compare( PHPUnit_Runner_Version::id(), '3.5.0', '>=' ) ) {
+if ( version_compare( PHPUnit_Runner_Version::id(), '3.5.0', '>=' ) ) {
        # PHPUnit 3.5.0 introduced a nice autoloader based on class name
        require_once( 'PHPUnit/Autoload.php' );
 } else {
@@ -75,7 +75,7 @@ class SeleniumTester extends Maintenance {
        public function listBrowsers() {
                $desc = "Available browsers:\n";
 
-               foreach ($this->selenium->getAvailableBrowsers() as $k => $v) {
+               foreach ( $this->selenium->getAvailableBrowsers() as $k => $v ) {
                        $desc .= "  $k => $v\n";
                }
 
@@ -85,8 +85,8 @@ class SeleniumTester extends Maintenance {
        protected function startServer() {
                if ( $this->seleniumServerExecPath == '' ) {
                        die ( "The selenium server exec path is not set in " .
-                                 "selenium_settings.ini. Cannot start server \n" .
-                                 "as requested - terminating RunSeleniumTests\n" );
+                               "selenium_settings.ini. Cannot start server \n" .
+                               "as requested - terminating RunSeleniumTests\n" );
                }
                $this->serverManager = new SeleniumServerManager( 'true',
                        $this->selenium->getPort(),
@@ -159,20 +159,20 @@ class SeleniumTester extends Maintenance {
 
                $configFile = $this->getOption( 'seleniumConfig', '' );
                if ( strlen( $configFile ) > 0 ) {
-                       $this->output("Using Selenium Configuration file: " . $configFile . "\n");
+                       $this->output( "Using Selenium Configuration file: " . $configFile . "\n" );
                        SeleniumConfig::getSeleniumSettings( $seleniumSettings,
                                $seleniumBrowsers,
                                $seleniumTestSuites,
                                $configFile );
                } elseif ( !isset( $wgHooks['SeleniumSettings'] ) ) {
-                       $this->output("No command line, configuration file or configuration hook found.\n");
+                       $this->output( "No command line, configuration file or configuration hook found.\n" );
                        SeleniumConfig::getSeleniumSettings( $seleniumSettings,
                                $seleniumBrowsers,
                                $seleniumTestSuites
-                                                                                                       );
+                       );
                } else {
-                       $this->output("Using 'SeleniumSettings' hook for configuration.\n");
-                       wfRunHooks('SeleniumSettings', array( $seleniumSettings,
+                       $this->output( "Using 'SeleniumSettings' hook for configuration.\n" );
+                       wfRunHooks( 'SeleniumSettings', array( $seleniumSettings,
                                $seleniumBrowsers,
                                $seleniumTestSuites ) );
                }
@@ -180,24 +180,48 @@ class SeleniumTester extends Maintenance {
                // State for starting/stopping the Selenium server has nothing to do with the Selenium
                // class. Keep this state local to SeleniumTester class. Using getOption() is clumsy, but
                // the Maintenance class does not have a setOption()
-               if ( ! isset( $seleniumSettings['startserver'] ) ) $this->getOption( 'startserver', true );
-               if ( ! isset( $seleniumSettings['stopserver'] ) ) $this->getOption( 'stopserver', true );
-               if ( !isset( $seleniumSettings['seleniumserverexecpath'] ) ) $seleniumSettings['seleniumserverexecpath'] = '';
+               if ( !isset( $seleniumSettings['startserver'] ) ) {
+                       $this->getOption( 'startserver', true );
+               }
+               if ( !isset( $seleniumSettings['stopserver'] ) ) {
+                       $this->getOption( 'stopserver', true );
+               }
+               if ( !isset( $seleniumSettings['seleniumserverexecpath'] ) ) {
+                       $seleniumSettings['seleniumserverexecpath'] = '';
+               }
                $this->seleniumServerExecPath = $seleniumSettings['seleniumserverexecpath'];
 
                //set reasonable defaults if we did not find the settings
-               if ( !isset( $seleniumBrowsers ) ) $seleniumBrowsers = array ('firefox' => '*firefox');
-               if ( !isset( $seleniumSettings['host'] ) ) $seleniumSettings['host'] = $wgServer . $wgScriptPath;
-               if ( !isset( $seleniumSettings['port'] ) ) $seleniumSettings['port'] = '4444';
-               if ( !isset( $seleniumSettings['wikiUrl'] ) ) $seleniumSettings['wikiUrl'] = 'http://localhost';
-               if ( !isset( $seleniumSettings['username'] ) ) $seleniumSettings['username'] = '';
-               if ( !isset( $seleniumSettings['userPassword'] ) ) $seleniumSettings['userPassword'] = '';
-               if ( !isset( $seleniumSettings['testBrowser'] ) ) $seleniumSettings['testBrowser'] = 'firefox';
-               if ( !isset( $seleniumSettings['jUnitLogFile'] ) ) $seleniumSettings['jUnitLogFile'] = false;
-               if ( !isset( $seleniumSettings['runAgainstGrid'] ) ) $seleniumSettings['runAgainstGrid'] = false;
+               if ( !isset( $seleniumBrowsers ) ) {
+                       $seleniumBrowsers = array( 'firefox' => '*firefox' );
+               }
+               if ( !isset( $seleniumSettings['host'] ) ) {
+                       $seleniumSettings['host'] = $wgServer . $wgScriptPath;
+               }
+               if ( !isset( $seleniumSettings['port'] ) ) {
+                       $seleniumSettings['port'] = '4444';
+               }
+               if ( !isset( $seleniumSettings['wikiUrl'] ) ) {
+                       $seleniumSettings['wikiUrl'] = 'http://localhost';
+               }
+               if ( !isset( $seleniumSettings['username'] ) ) {
+                       $seleniumSettings['username'] = '';
+               }
+               if ( !isset( $seleniumSettings['userPassword'] ) ) {
+                       $seleniumSettings['userPassword'] = '';
+               }
+               if ( !isset( $seleniumSettings['testBrowser'] ) ) {
+                       $seleniumSettings['testBrowser'] = 'firefox';
+               }
+               if ( !isset( $seleniumSettings['jUnitLogFile'] ) ) {
+                       $seleniumSettings['jUnitLogFile'] = false;
+               }
+               if ( !isset( $seleniumSettings['runAgainstGrid'] ) ) {
+                       $seleniumSettings['runAgainstGrid'] = false;
+               }
 
                // Setup Selenium class
-               $this->selenium = new Selenium( );
+               $this->selenium = new Selenium();
                $this->selenium->setAvailableBrowsers( $seleniumBrowsers );
                $this->selenium->setRunAgainstGrid( $this->getOption( 'runAgainstGrid', $seleniumSettings['runAgainstGrid'] ) );
                $this->selenium->setUrl( $this->getOption( 'wikiUrl', $seleniumSettings['wikiUrl'] ) );
@@ -209,9 +233,9 @@ class SeleniumTester extends Maintenance {
                $this->selenium->setVerbose( $this->hasOption( 'verbose' ) );
                $this->selenium->setJUnitLogFile( $this->getOption( 'jUnitLogFile', $seleniumSettings['jUnitLogFile'] ) );
 
-               if( $this->hasOption( 'list-browsers' ) ) {
+               if ( $this->hasOption( 'list-browsers' ) ) {
                        $this->listBrowsers();
-                       exit(0);
+                       exit( 0 );
                }
                if ( $this->hasOption( 'startserver' ) ) {
                        $this->startServer();
@@ -222,7 +246,7 @@ class SeleniumTester extends Maintenance {
 
                $this->runTests( $seleniumTestSuites );
 
-               if ( $this->hasOption( 'stopserver' )  ) {
+               if ( $this->hasOption( 'stopserver' ) ) {
                        $this->stopServer();
                }
        }
index db3c84a..b9bb33f 100644 (file)
@@ -74,6 +74,7 @@ class ParserTest {
 
        public $regex = "";
        private $savedGlobals = array();
+
        /**
         * Sets terminal colorization and diff/quick modes depending on OS and
         * command-line options (--color and --quick).
@@ -83,14 +84,14 @@ class ParserTest {
                $this->color = !wfIsWindows() && Maintenance::posix_isatty( 1 );
 
                if ( isset( $options['color'] ) ) {
-                       switch( $options['color'] ) {
-                       case 'no':
-                               $this->color = false;
-                               break;
-                       case 'yes':
-                       default:
-                               $this->color = true;
-                               break;
+                       switch ( $options['color'] ) {
+                               case 'no':
+                                       $this->color = false;
+                                       break;
+                               case 'yes':
+                               default:
+                                       $this->color = true;
+                                       break;
                        }
                }
 
@@ -102,7 +103,7 @@ class ParserTest {
                $this->showProgress = !isset( $options['quiet'] );
                $this->showFailure = !(
                        isset( $options['quiet'] )
-                       && ( isset( $options['record'] )
+                               && ( isset( $options['record'] )
                                || isset( $options['compare'] ) ) ); // redundant output
 
                $this->showOutput = isset( $options['show-output'] );
@@ -152,23 +153,26 @@ class ParserTest {
                $wgExtensionAssetsPath = '/extensions';
                $wgThumbnailScriptPath = false;
                $wgLockManagers = array( array(
-                       'name'          => 'fsLockManager',
-                       'class'         => 'FSLockManager',
+                       'name' => 'fsLockManager',
+                       'class' => 'FSLockManager',
                        'lockDirectory' => wfTempDir() . '/test-repo/lockdir',
+               ), array(
+                       'name' => 'nullLockManager',
+                       'class' => 'NullLockManager',
                ) );
                $wgLocalFileRepo = array(
-                       'class'           => 'LocalRepo',
-                       'name'            => 'local',
-                       'url'             => 'http://example.com/images',
-                       'hashLevels'      => 2,
+                       'class' => 'LocalRepo',
+                       'name' => 'local',
+                       'url' => 'http://example.com/images',
+                       'hashLevels' => 2,
                        'transformVia404' => false,
-                       'backend'         => new FSFileBackend( array(
-                               'name'        => 'local-backend',
+                       'backend' => new FSFileBackend( array(
+                               'name' => 'local-backend',
                                'lockManager' => 'fsLockManager',
                                'containerPaths' => array(
-                                       'local-public'  => wfTempDir() . '/test-repo/public',
-                                       'local-thumb'   => wfTempDir() . '/test-repo/thumb',
-                                       'local-temp'    => wfTempDir() . '/test-repo/temp',
+                                       'local-public' => wfTempDir() . '/test-repo/public',
+                                       'local-thumb' => wfTempDir() . '/test-repo/thumb',
+                                       'local-temp' => wfTempDir() . '/test-repo/temp',
                                        'local-deleted' => wfTempDir() . '/test-repo/deleted',
                                )
                        ) )
@@ -203,16 +207,16 @@ class ParserTest {
                $wgRequest = $context->getRequest();
 
                if ( $wgStyleDirectory === false ) {
-                       $wgStyleDirectory   = "$IP/skins";
+                       $wgStyleDirectory = "$IP/skins";
                }
 
        }
 
-       public function setupRecorder ( $options ) {
+       public function setupRecorder( $options ) {
                if ( isset( $options['record'] ) ) {
                        $this->recorder = new DbTestRecorder( $this );
                        $this->recorder->version = isset( $options['setversion'] ) ?
-                                       $options['setversion'] : SpecialVersion::getVersion();
+                               $options['setversion'] : SpecialVersion::getVersion();
                } elseif ( isset( $options['compare'] ) ) {
                        $this->recorder = new DbTestPreviewer( $this );
                } else {
@@ -227,8 +231,7 @@ class ParserTest {
        static public function chomp( $s ) {
                if ( substr( $s, -1 ) === "\n" ) {
                        return substr( $s, 0, -1 );
-               }
-               else {
+               } else {
                        return $s;
                }
        }
@@ -387,7 +390,7 @@ class ParserTest {
 
                        $this->teardownDatabase();
                        $this->recorder->report();
-               } catch (DBError $e) {
+               } catch ( DBError $e ) {
                        echo $e->getMessage();
                }
                $this->recorder->end();
@@ -460,8 +463,7 @@ class ParserTest {
 
                if ( isset( $opts['title'] ) ) {
                        $titleText = $opts['title'];
-               }
-               else {
+               } else {
                        $titleText = 'Parser test';
                }
 
@@ -634,24 +636,27 @@ class ParserTest {
                        'wgScriptPath' => '/',
                        'wgArticlePath' => '/wiki/$1',
                        'wgActionPaths' => array(),
-                       'wgLockManagers' => array(
-                               'name'          => 'fsLockManager',
-                               'class'         => 'FSLockManager',
+                       'wgLockManagers' => array( array(
+                               'name' => 'fsLockManager',
+                               'class' => 'FSLockManager',
                                'lockDirectory' => $this->uploadDir . '/lockdir',
-                       ),
+                       ), array(
+                               'name' => 'nullLockManager',
+                               'class' => 'NullLockManager',
+                       ) ),
                        'wgLocalFileRepo' => array(
                                'class' => 'LocalRepo',
                                'name' => 'local',
                                'url' => 'http://example.com/images',
                                'hashLevels' => 2,
                                'transformVia404' => false,
-                               'backend'         => new FSFileBackend( array(
-                                       'name'        => 'local-backend',
+                               'backend' => new FSFileBackend( array(
+                                       'name' => 'local-backend',
                                        'lockManager' => 'fsLockManager',
                                        'containerPaths' => array(
-                                               'local-public'  => $this->uploadDir,
-                                               'local-thumb'   => $this->uploadDir . '/thumb',
-                                               'local-temp'    => $this->uploadDir . '/temp',
+                                               'local-public' => $this->uploadDir,
+                                               'local-thumb' => $this->uploadDir . '/thumb',
+                                               'local-temp' => $this->uploadDir . '/temp',
                                                'local-deleted' => $this->uploadDir . '/delete',
                                        )
                                ) )
@@ -679,10 +684,10 @@ class ParserTest {
                        'wgVariantArticlePath' => false,
                        'wgGroupPermissions' => array( '*' => array(
                                'createaccount' => true,
-                               'read'          => true,
-                               'edit'          => true,
-                               'createpage'    => true,
-                               'createtalk'    => true,
+                               'read' => true,
+                               'edit' => true,
+                               'createpage' => true,
+                               'createtalk' => true,
                        ) ),
                        'wgNamespaceProtection' => array( NS_MEDIAWIKI => 'editinterface' ),
                        'wgDefaultExternalStore' => array(),
@@ -749,7 +754,7 @@ class ParserTest {
                $tables = array( 'user', 'user_properties', 'user_former_groups', 'page', 'page_restrictions',
                        'protected_titles', 'revision', 'text', 'pagelinks', 'imagelinks',
                        'categorylinks', 'templatelinks', 'externallinks', 'langlinks', 'iwlinks',
-                       'site_stats', 'hitcounter',     'ipblocks', 'image', 'oldimage',
+                       'site_stats', 'hitcounter', 'ipblocks', 'image', 'oldimage',
                        'recentchanges', 'watchlist', 'interwiki', 'logging',
                        'querycache', 'objectcache', 'job', 'l10n_cache', 'redirect', 'querycachetwo',
                        'archive', 'user_groups', 'page_props', 'category', 'msg_resource', 'msg_resource_links'
@@ -812,44 +817,44 @@ class ParserTest {
 
                        # Anonymous user
                        $this->db->insert( 'user', array(
-                               'user_id'         => 0,
-                               'user_name'       => 'Anonymous' ) );
+                               'user_id' => 0,
+                               'user_name' => 'Anonymous' ) );
                }
 
                # Hack: insert a few Wikipedia in-project interwiki prefixes,
                # for testing inter-language links
                $this->db->insert( 'interwiki', array(
                        array( 'iw_prefix' => 'wikipedia',
-                                  'iw_url'    => 'http://en.wikipedia.org/wiki/$1',
-                                  'iw_api'    => '',
-                                  'iw_wikiid' => '',
-                                  'iw_local'  => 0 ),
+                               'iw_url' => 'http://en.wikipedia.org/wiki/$1',
+                               'iw_api' => '',
+                               'iw_wikiid' => '',
+                               'iw_local' => 0 ),
                        array( 'iw_prefix' => 'meatball',
-                                  'iw_url'    => 'http://www.usemod.com/cgi-bin/mb.pl?$1',
-                                  'iw_api'    => '',
-                                  'iw_wikiid' => '',
-                                  'iw_local'  => 0 ),
+                               'iw_url' => 'http://www.usemod.com/cgi-bin/mb.pl?$1',
+                               'iw_api' => '',
+                               'iw_wikiid' => '',
+                               'iw_local' => 0 ),
                        array( 'iw_prefix' => 'zh',
-                                  'iw_url'    => 'http://zh.wikipedia.org/wiki/$1',
-                                  'iw_api'    => '',
-                                  'iw_wikiid' => '',
-                                  'iw_local'  => 1 ),
+                               'iw_url' => 'http://zh.wikipedia.org/wiki/$1',
+                               'iw_api' => '',
+                               'iw_wikiid' => '',
+                               'iw_local' => 1 ),
                        array( 'iw_prefix' => 'es',
-                                  'iw_url'    => 'http://es.wikipedia.org/wiki/$1',
-                                  'iw_api'    => '',
-                                  'iw_wikiid' => '',
-                                  'iw_local'  => 1 ),
+                               'iw_url' => 'http://es.wikipedia.org/wiki/$1',
+                               'iw_api' => '',
+                               'iw_wikiid' => '',
+                               'iw_local' => 1 ),
                        array( 'iw_prefix' => 'fr',
-                                  'iw_url'    => 'http://fr.wikipedia.org/wiki/$1',
-                                  'iw_api'    => '',
-                                  'iw_wikiid' => '',
-                                  'iw_local'  => 1 ),
+                               'iw_url' => 'http://fr.wikipedia.org/wiki/$1',
+                               'iw_api' => '',
+                               'iw_wikiid' => '',
+                               'iw_local' => 1 ),
                        array( 'iw_prefix' => 'ru',
-                                  'iw_url'    => 'http://ru.wikipedia.org/wiki/$1',
-                                  'iw_api'    => '',
-                                  'iw_wikiid' => '',
-                                  'iw_local'  => 1 ),
-                       ) );
+                               'iw_url' => 'http://ru.wikipedia.org/wiki/$1',
+                               'iw_api' => '',
+                               'iw_wikiid' => '',
+                               'iw_local' => 1 ),
+               ) );
 
                # Update certain things in site_stats
                $this->db->insert( 'site_stats', array( 'ss_row_id' => 1, 'ss_images' => 2, 'ss_good_articles' => 1 ) );
@@ -864,30 +869,30 @@ class ParserTest {
                $user = User::createNew( 'WikiSysop' );
                $image = wfLocalFile( Title::makeTitle( NS_FILE, 'Foobar.jpg' ) );
                $image->recordUpload2( '', 'Upload of some lame file', 'Some lame file', array(
-                       'size'        => 12345,
-                       'width'       => 1941,
-                       'height'      => 220,
-                       'bits'        => 24,
-                       'media_type'  => MEDIATYPE_BITMAP,
-                       'mime'        => 'image/jpeg',
-                       'metadata'    => serialize( array() ),
-                       'sha1'        => wfBaseConvert( '', 16, 36, 31 ),
-                       'fileExists'  => true
-                       ), $this->db->timestamp( '20010115123500' ), $user );
+                       'size' => 12345,
+                       'width' => 1941,
+                       'height' => 220,
+                       'bits' => 24,
+                       'media_type' => MEDIATYPE_BITMAP,
+                       'mime' => 'image/jpeg',
+                       'metadata' => serialize( array() ),
+                       'sha1' => wfBaseConvert( '', 16, 36, 31 ),
+                       'fileExists' => true
+               ), $this->db->timestamp( '20010115123500' ), $user );
 
                # This image will be blacklisted in [[MediaWiki:Bad image list]]
                $image = wfLocalFile( Title::makeTitle( NS_FILE, 'Bad.jpg' ) );
                $image->recordUpload2( '', 'zomgnotcensored', 'Borderline image', array(
-                       'size'        => 12345,
-                       'width'       => 320,
-                       'height'      => 240,
-                       'bits'        => 24,
-                       'media_type'  => MEDIATYPE_BITMAP,
-                       'mime'        => 'image/jpeg',
-                       'metadata'    => serialize( array() ),
-                       'sha1'        => wfBaseConvert( '', 16, 36, 31 ),
-                       'fileExists'  => true
-                       ), $this->db->timestamp( '20010115123500' ), $user );
+                       'size' => 12345,
+                       'width' => 320,
+                       'height' => 240,
+                       'bits' => 24,
+                       'media_type' => MEDIATYPE_BITMAP,
+                       'mime' => 'image/jpeg',
+                       'metadata' => serialize( array() ),
+                       'sha1' => wfBaseConvert( '', 16, 36, 31 ),
+                       'fileExists' => true
+               ), $this->db->timestamp( '20010115123500' ), $user );
        }
 
        public function teardownDatabase() {
@@ -901,7 +906,7 @@ class ParserTest {
                $this->databaseSetupDone = false;
 
                if ( $this->useTemporaryTables ) {
-                       if( $this->db->getType() == 'sqlite' ) {
+                       if ( $this->db->getType() == 'sqlite' ) {
                                # Under SQLite the searchindex table is virtual and need
                                # to be explicitly destroyed. See bug 29912
                                # See also MediaWikiTestCase::destroyDB()
@@ -920,8 +925,9 @@ class ParserTest {
                        $this->db->query( $sql );
                }
 
-               if ( $this->db->getType() == 'oracle' )
+               if ( $this->db->getType() == 'oracle' ) {
                        $this->db->query( 'BEGIN FILL_WIKI_INFO; END;' );
+               }
 
                $this->teardownGlobals();
        }
@@ -984,7 +990,7 @@ class ParserTest {
 
                // delete the files first, then the dirs.
                self::deleteFiles(
-                       array (
+                       array(
                                "$dir/3/3a/Foobar.jpg",
                                "$dir/thumb/3/3a/Foobar.jpg/180px-Foobar.jpg",
                                "$dir/thumb/3/3a/Foobar.jpg/200px-Foobar.jpg",
@@ -1008,7 +1014,7 @@ class ParserTest {
                );
 
                self::deleteDirs(
-                       array (
+                       array(
                                "$dir/3/3a",
                                "$dir/3",
                                "$dir/thumb/6/65",
@@ -1129,8 +1135,8 @@ class ParserTest {
                $outfile = "$prefix-$outFileTail";
                $this->dumpToFile( $output, $outfile );
 
-               $shellInfile = wfEscapeShellArg($infile);
-               $shellOutfile = wfEscapeShellArg($outfile);
+               $shellInfile = wfEscapeShellArg( $infile );
+               $shellOutfile = wfEscapeShellArg( $outfile );
 
                global $wgDiff3;
                // we assume that people with diff3 also have usual diff
@@ -1166,7 +1172,7 @@ class ParserTest {
                return preg_replace(
                        array( '/^(-.*)$/m', '/^(\+.*)$/m' ),
                        array( $this->term->color( 34 ) . '$1' . $this->term->reset(),
-                                  $this->term->color( 31 ) . '$1' . $this->term->reset() ),
+                               $this->term->color( 31 ) . '$1' . $this->term->reset() ),
                        $text );
        }
 
@@ -1231,7 +1237,7 @@ class ParserTest {
        public function requireHook( $name ) {
                global $wgParser;
 
-               $wgParser->firstCallInit( ); // make sure hooks are loaded.
+               $wgParser->firstCallInit(); // make sure hooks are loaded.
 
                if ( isset( $wgParser->mTagHooks[$name] ) ) {
                        $this->hooks[$name] = $wgParser->mTagHooks[$name];
@@ -1254,7 +1260,7 @@ class ParserTest {
        public function requireFunctionHook( $name ) {
                global $wgParser;
 
-               $wgParser->firstCallInit( ); // make sure hooks are loaded.
+               $wgParser->firstCallInit(); // make sure hooks are loaded.
 
                if ( isset( $wgParser->mFunctionHooks[$name] ) ) {
                        $this->functionHooks[$name] = $wgParser->mFunctionHooks[$name];
@@ -1286,9 +1292,9 @@ class ParserTest {
        private function wellFormed( $text ) {
                $html =
                        Sanitizer::hackDocType() .
-                       '<html>' .
-                       $text .
-                       '</html>';
+                               '<html>' .
+                               $text .
+                               '</html>';
 
                $parser = xml_parser_create( "UTF-8" );
 
index c25f158..1f84aae 100644 (file)
@@ -11806,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
@@ -11835,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
@@ -11855,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
index f01665c..c8b3e89 100644 (file)
@@ -35,18 +35,18 @@ class ParserTestParserHook {
 
        static function dumpHook( $in, $argv ) {
                return "<pre>\n" .
-                          var_export( $in, true ) . "\n" .
-                          var_export( $argv, true ) . "\n" .
-                          "</pre>";
+                       var_export( $in, true ) . "\n" .
+                       var_export( $argv, true ) . "\n" .
+                       "</pre>";
        }
 
        static function staticTagHook( $in, $argv, $parser ) {
-               if ( ! count( $argv ) ) {
+               if ( !count( $argv ) ) {
                        $parser->static_tag_buf = $in;
                        return '';
                } elseif ( count( $argv ) === 1 && isset( $argv['action'] )
-                       && $argv['action'] === 'flush' && $in === null )
-               {
+                       && $argv['action'] === 'flush' && $in === null
+               {
                        // Clear the buffer, we probably don't need to
                        if ( isset( $parser->static_tag_buf ) ) {
                                $tmp = $parser->static_tag_buf;
@@ -55,12 +55,12 @@ class ParserTestParserHook {
                        }
                        $parser->static_tag_buf = null;
                        return $tmp;
-               } else
-                       // wtf?
+               } else { // wtf?
                        return
                                "\nCall this extension as <statictag>string</statictag> or as" .
                                " <statictag action=flush/>, not in any other way.\n" .
                                "text: " . var_export( $in, true ) . "\n" .
                                "argv: " . var_export( $argv, true ) . "\n";
+               }
        }
 }
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 1ef6473..4d2c402 100644 (file)
@@ -72,7 +72,7 @@ if ( $wgDBtype == 'sqlite' ) {
 # refer to $wgTitle directly, but instead use the title
 # passed to it.
 $wgTitle = Title::newFromText( 'Parser test script do not use' );
-$tester = new ParserTest($options);
+$tester = new ParserTest( $options );
 
 if ( isset( $options['file'] ) ) {
        $files = array( $options['file'] );
index 3034601..0cf6e38 100644 (file)
@@ -10,7 +10,7 @@ abstract class MediaWikiLangTestCase extends MediaWikiTestCase {
                parent::setUp();
 
                if ( $wgLanguageCode != $wgContLang->getCode() ) {
-                       throw new MWException("Error in MediaWikiLangTestCase::setUp(): " .
+                       throw new MWException( "Error in MediaWikiLangTestCase::setUp(): " .
                                "\$wgLanguageCode ('$wgLanguageCode') is different from " .
                                "\$wgContLang->getCode() (" . $wgContLang->getCode() . ")" );
                }
index 0434bb3..c139f0b 100644 (file)
@@ -14,7 +14,7 @@ class MediaWikiPHPUnitCommand extends PHPUnit_TextUI_Command {
        );
 
        public function __construct() {
-               foreach( self::$additionalOptions as $option => $default ) {
+               foreach ( self::$additionalOptions as $option => $default ) {
                        $this->longOptions[$option] = $option . 'Handler';
                }
 
@@ -23,7 +23,7 @@ class MediaWikiPHPUnitCommand extends PHPUnit_TextUI_Command {
        public static function main( $exit = true ) {
                $command = new self;
 
-               if( wfIsWindows() ) {
+               if ( wfIsWindows() ) {
                        # Windows does not come anymore with ANSI.SYS loaded by default
                        # PHPUnit uses the suite.xml parameters to enable/disable colors
                        # which can be then forced to be enabled with --colors.
@@ -40,18 +40,20 @@ class MediaWikiPHPUnitCommand extends PHPUnit_TextUI_Command {
                # See bug 32022
                set_include_path(
                        __DIR__
-                       .PATH_SEPARATOR
-                       . get_include_path()
+                               . PATH_SEPARATOR
+                               . get_include_path()
                );
 
-               $command->run($_SERVER['argv'], $exit);
+               $command->run( $_SERVER['argv'], $exit );
        }
 
        public function __call( $func, $args ) {
 
-               if( substr( $func, -7 ) == 'Handler' ) {
-                       if( is_null( $args[0] ) ) $args[0] = true; //Booleans
-                       self::$additionalOptions[substr( $func, 0, -7 ) ] = $args[0];
+               if ( substr( $func, -7 ) == 'Handler' ) {
+                       if ( is_null( $args[0] ) ) {
+                               $args[0] = true;
+                       } //Booleans
+                       self::$additionalOptions[substr( $func, 0, -7 )] = $args[0];
                }
        }
 
index dfc5881..f16d06c 100644 (file)
@@ -81,17 +81,17 @@ abstract class MediaWikiTestCase extends PHPUnit_Framework_TestCase {
                $needsResetDB = false;
                $logName = get_class( $this ) . '::' . $this->getName( false );
 
-               if( $this->needsDB() ) {
+               if ( $this->needsDB() ) {
                        // set up a DB connection for this test to use
 
                        self::$useTemporaryTables = !$this->getCliArg( 'use-normal-tables' );
-                       self::$reuseDB = $this->getCliArg('reuse-db');
+                       self::$reuseDB = $this->getCliArg( 'reuse-db' );
 
                        $this->db = wfGetDB( DB_MASTER );
 
                        $this->checkDbIsSupported();
 
-                       if( !self::$dbSetup ) {
+                       if ( !self::$dbSetup ) {
                                wfProfileIn( $logName . ' (clone-db)' );
 
                                // switch to a temporary clone of the database
@@ -116,7 +116,7 @@ abstract class MediaWikiTestCase extends PHPUnit_Framework_TestCase {
                parent::run( $result );
                wfProfileOut( $logName );
 
-               if( $needsResetDB ) {
+               if ( $needsResetDB ) {
                        wfProfileIn( $logName . ' (reset-db)' );
                        $this->resetDB();
                        wfProfileOut( $logName . ' (reset-db)' );
@@ -188,7 +188,7 @@ abstract class MediaWikiTestCase extends PHPUnit_Framework_TestCase {
 
                if ( $this->needsDB() && $this->db ) {
                        // Clean up open transactions
-                       while( $this->db->trxLevel() > 0 ) {
+                       while ( $this->db->trxLevel() > 0 ) {
                                $this->db->rollback();
                        }
 
@@ -213,7 +213,7 @@ abstract class MediaWikiTestCase extends PHPUnit_Framework_TestCase {
 
                if ( $this->needsDB() && $this->db ) {
                        // Clean up open transactions
-                       while( $this->db->trxLevel() > 0 ) {
+                       while ( $this->db->trxLevel() > 0 ) {
                                $this->db->rollback();
                        }
 
@@ -276,7 +276,7 @@ abstract class MediaWikiTestCase extends PHPUnit_Framework_TestCase {
        protected function setMwGlobals( $pairs, $value = null ) {
 
                // Normalize (string, value) to an array
-               if( is_string( $pairs ) ) {
+               if ( is_string( $pairs ) ) {
                        $pairs = array( $pairs => $value );
                }
 
@@ -356,8 +356,8 @@ abstract class MediaWikiTestCase extends PHPUnit_Framework_TestCase {
                        # Insert 0 user to prevent FK violations
                        # Anonymous user
                        $this->db->insert( 'user', array(
-                               'user_id'               => 0,
-                               'user_name'     => 'Anonymous' ), __METHOD__, array( 'IGNORE' ) );
+                               'user_id' => 0,
+                               'user_name' => 'Anonymous' ), __METHOD__, array( 'IGNORE' ) );
 
                        # Insert 0 page to prevent FK violations
                        # Blank page
@@ -471,20 +471,24 @@ abstract class MediaWikiTestCase extends PHPUnit_Framework_TestCase {
         * Empty all tables so they can be repopulated for tests
         */
        private function resetDB() {
-               if( $this->db ) {
-                       if ( $this->db->getType() == 'oracle' )  {
+               if ( $this->db ) {
+                       if ( $this->db->getType() == 'oracle' ) {
                                if ( self::$useTemporaryTables ) {
                                        wfGetLB()->closeAll();
                                        $this->db = wfGetDB( DB_MASTER );
                                } else {
-                                       foreach( $this->tablesUsed as $tbl ) {
-                                               if( $tbl == 'interwiki') continue;
-                                               $this->db->query( 'TRUNCATE TABLE '.$this->db->tableName($tbl), __METHOD__ );
+                                       foreach ( $this->tablesUsed as $tbl ) {
+                                               if ( $tbl == 'interwiki' ) {
+                                                       continue;
+                                               }
+                                               $this->db->query( 'TRUNCATE TABLE ' . $this->db->tableName( $tbl ), __METHOD__ );
                                        }
                                }
                        } else {
-                               foreach( $this->tablesUsed as $tbl ) {
-                                       if( $tbl == 'interwiki' || $tbl == 'user' ) continue;
+                               foreach ( $this->tablesUsed as $tbl ) {
+                                       if ( $tbl == 'interwiki' || $tbl == 'user' ) {
+                                               continue;
+                                       }
                                        $this->db->delete( $tbl, '*', __METHOD__ );
                                }
                        }
@@ -500,9 +504,9 @@ abstract class MediaWikiTestCase extends PHPUnit_Framework_TestCase {
                );
 
                if ( method_exists( $this->suite, $func ) ) {
-                       return call_user_func_array( array( $this->suite, $func ), $args);
+                       return call_user_func_array( array( $this->suite, $func ), $args );
                } elseif ( isset( $compatibility[$func] ) ) {
-                       return call_user_func_array( array( $this, $compatibility[$func] ), $args);
+                       return call_user_func_array( array( $this, $compatibility[$func] ), $args );
                } else {
                        throw new MWException( "Called non-existant $func method on "
                                . get_class( $this ) );
@@ -543,14 +547,14 @@ abstract class MediaWikiTestCase extends PHPUnit_Framework_TestCase {
        }
 
        protected function checkDbIsSupported() {
-               if( !in_array( $this->db->getType(), $this->supportedDBs ) ) {
+               if ( !in_array( $this->db->getType(), $this->supportedDBs ) ) {
                        throw new MWException( $this->db->getType() . " is not currently supported for unit testing." );
                }
        }
 
        public function getCliArg( $offset ) {
 
-               if( isset( MediaWikiPHPUnitCommand::$additionalOptions[$offset] ) ) {
+               if ( isset( MediaWikiPHPUnitCommand::$additionalOptions[$offset] ) ) {
                        return MediaWikiPHPUnitCommand::$additionalOptions[$offset];
                }
 
@@ -595,7 +599,7 @@ abstract class MediaWikiTestCase extends PHPUnit_Framework_TestCase {
        protected function assertSelect( $table, $fields, $condition, array $expectedRows ) {
                if ( !$this->needsDB() ) {
                        throw new MWException( 'When testing database state, the test cases\'s needDB()' .
-                               ' method should return true. Use @group Database or $this->tablesUsed.');
+                               ' method should return true. Use @group Database or $this->tablesUsed.' );
                }
 
                $db = wfGetDB( DB_SLAVE );
@@ -634,7 +638,7 @@ abstract class MediaWikiTestCase extends PHPUnit_Framework_TestCase {
         */
        protected function arrayWrap( array $elements ) {
                return array_map(
-                       function( $element ) {
+                       function ( $element ) {
                                return array( $element );
                        },
                        $elements
@@ -682,9 +686,9 @@ abstract class MediaWikiTestCase extends PHPUnit_Framework_TestCase {
         * @param String $actual HTML on oneline
         * @param String $msg Optional message
         */
-       protected function assertHTMLEquals( $expected, $actual, $msg='' ) {
+       protected function assertHTMLEquals( $expected, $actual, $msg = '' ) {
                $expected = str_replace( '>', ">\n", $expected );
-               $actual   = str_replace( '>', ">\n", $actual   );
+               $actual = str_replace( '>', ">\n", $actual );
 
                $this->assertEquals( $expected, $actual, $msg );
        }
@@ -699,7 +703,7 @@ abstract class MediaWikiTestCase extends PHPUnit_Framework_TestCase {
        protected function objectAssociativeSort( array &$array ) {
                uasort(
                        $array,
-                       function( $a, $b ) {
+                       function ( $a, $b ) {
                                return serialize( $a ) > serialize( $b ) ? 1 : -1;
                        }
                );
@@ -742,8 +746,7 @@ abstract class MediaWikiTestCase extends PHPUnit_Framework_TestCase {
        protected function assertTypeOrValue( $type, $actual, $value = false, $message = '' ) {
                if ( $actual === $value ) {
                        $this->assertTrue( true, $message );
-               }
-               else {
+               } else {
                        $this->assertType( $type, $actual, $message );
                }
        }
@@ -762,8 +765,7 @@ abstract class MediaWikiTestCase extends PHPUnit_Framework_TestCase {
        protected function assertType( $type, $actual, $message = '' ) {
                if ( class_exists( $type ) || interface_exists( $type ) ) {
                        $this->assertInstanceOf( $type, $actual, $message );
-               }
-               else {
+               } else {
                        $this->assertInternalType( $type, $actual, $message );
                }
        }
@@ -816,7 +818,7 @@ abstract class MediaWikiTestCase extends PHPUnit_Framework_TestCase {
 
                $namespaces = array_diff( $namespaces, array(
                        NS_FILE, NS_CATEGORY, NS_MEDIAWIKI, NS_USER // don't mess with magic namespaces
-               ));
+               ) );
 
                $talk = array_filter( $namespaces, function ( $ns ) {
                        return MWNamespace::isTalk( $ns );
@@ -829,7 +831,8 @@ abstract class MediaWikiTestCase extends PHPUnit_Framework_TestCase {
                // check default content model of each namespace
                foreach ( $namespaces as $ns ) {
                        if ( !isset( $wgNamespaceContentModels[$ns] ) ||
-                               $wgNamespaceContentModels[$ns] === CONTENT_MODEL_WIKITEXT ) {
+                               $wgNamespaceContentModels[$ns] === CONTENT_MODEL_WIKITEXT
+                       ) {
 
                                $wikitextNS = $ns;
                                return $wikitextNS;
@@ -857,7 +860,7 @@ abstract class MediaWikiTestCase extends PHPUnit_Framework_TestCase {
                $haveDiff3 = $wgDiff3 && file_exists( $wgDiff3 );
                wfRestoreWarnings();
 
-               if( !$haveDiff3 ) {
+               if ( !$haveDiff3 ) {
                        $this->markTestSkipped( "Skip test, since diff3 is not configured" );
                }
        }
@@ -875,13 +878,13 @@ abstract class MediaWikiTestCase extends PHPUnit_Framework_TestCase {
        protected function checkHasGzip() {
                static $haveGzip;
 
-               if( $haveGzip === null ) {
+               if ( $haveGzip === null ) {
                        $retval = null;
                        wfShellExec( 'gzip -V', $retval );
-                       $haveGzip = ($retval === 0);
+                       $haveGzip = ( $retval === 0 );
                }
 
-               if( !$haveGzip ) {
+               if ( !$haveGzip ) {
                        $this->markTestSkipped( "Skip test, requires the gzip utility in PATH" );
                }
 
@@ -896,7 +899,7 @@ abstract class MediaWikiTestCase extends PHPUnit_Framework_TestCase {
         */
        protected function checkPHPExtension( $extName ) {
                $loaded = extension_loaded( $extName );
-               if( ! $loaded ) {
+               if ( !$loaded ) {
                        $this->markTestSkipped( "PHP extension '$extName' is not loaded, skipping." );
                }
                return $loaded;
@@ -917,8 +920,7 @@ abstract class MediaWikiTestCase extends PHPUnit_Framework_TestCase {
 
                try {
                        call_user_func( $code );
-               }
-               catch ( Exception $pokemons ) {
+               } catch ( Exception $pokemons ) {
                        // Gotta Catch 'Em All!
                }
 
index dfbcc9d..e3e2138 100644 (file)
@@ -29,7 +29,7 @@ class StructureTest extends MediaWikiTestCase {
 
                $results = null;
                $exitCode = null;
-               exec($finder, $results, $exitCode);
+               exec( $finder, $results, $exitCode );
 
                $this->assertEquals(
                        0,
@@ -42,7 +42,7 @@ class StructureTest extends MediaWikiTestCase {
                        array( $this, 'filterSuites' )
                );
                $strip = strlen( $rootPath ) - 1;
-               foreach( $results as $k => $v) {
+               foreach ( $results as $k => $v ) {
                        $results[$k] = substr( $v, $strip );
                }
                $this->assertEquals(
index 933767e..01caf8f 100644 (file)
@@ -16,7 +16,7 @@ EOF;
 
 // Output a notice when running with older versions of PHPUnit
 if ( version_compare( PHPUnit_Runner_Version::id(), "3.6.7", "<" ) ) {
-  echo <<<EOF
+       echo <<<EOF
 ********************************************************************************
 
 These tests run best with version PHPUnit 3.6.7 or better. Earlier versions may
index 211de26..b09487a 100644 (file)
@@ -32,7 +32,7 @@ class ExportDemoTest extends DumpTestCase {
                try {
                        $this->assertTrue( $dom->schemaValidate( "../../docs/export-" . $version . ".xsd" ),
                                "schemaValidate has found an error" );
-               } catch( Exception $e ) {
+               } catch ( Exception $e ) {
                        $this->fail( "xml not valid against xsd: " . $e->getMessage() );
                }
        }
index 82b947b..867c4f0 100644 (file)
@@ -50,7 +50,7 @@ class ArticleTest extends MediaWikiTestCase {
                $this->article->ext_someNewProperty = 12;
                $this->assertEquals( 12, $this->article->ext_someNewProperty,
                        "Article get/set magic on new field" );
-               
+
                $this->article->ext_someNewProperty = -8;
                $this->assertEquals( -8, $this->article->ext_someNewProperty,
                        "Article get/set magic on update to new field" );
@@ -80,11 +80,11 @@ class ArticleTest extends MediaWikiTestCase {
                $title = Title::makeTitle( NS_FILE, 'Someimage.png' );
                $page = WikiPage::factory( $title );
                $this->assertEquals( 'WikiFilePage', get_class( $page ) );
-               
+
                $title = Title::makeTitle( NS_CATEGORY, 'SomeCategory' );
                $page = WikiPage::factory( $title );
                $this->assertEquals( 'WikiCategoryPage', get_class( $page ) );
-               
+
                $title = Title::makeTitle( NS_MAIN, 'SomePage' );
                $page = WikiPage::factory( $title );
                $this->assertEquals( 'WikiPage', get_class( $page ) );
index bdd4853..19c9b68 100644 (file)
@@ -59,7 +59,7 @@ class BlockTest extends MediaWikiLangTestCase {
        function dumpBlocks() {
                $v = $this->db->query( 'SELECT * FROM unittest_ipblocks' );
                print "Got " . $v->numRows() . " rows. Full dump follow:\n";
-               foreach( $v as $row ) {
+               foreach ( $v as $row ) {
                        print_r( $row );
                }
        }
@@ -67,9 +67,9 @@ class BlockTest extends MediaWikiLangTestCase {
        function testInitializerFunctionsReturnCorrectBlock() {
                // $this->dumpBlocks();
 
-               $this->assertTrue( $this->block->equals( Block::newFromTarget('UTBlockee') ), "newFromTarget() returns the same block as the one that was made");
+               $this->assertTrue( $this->block->equals( Block::newFromTarget( 'UTBlockee' ) ), "newFromTarget() returns the same block as the one that was made" );
 
-               $this->assertTrue( $this->block->equals( Block::newFromID( $this->blockId ) ), "newFromID() returns the same block as the one that was made");
+               $this->assertTrue( $this->block->equals( Block::newFromID( $this->blockId ) ), "newFromID() returns the same block as the one that was made" );
 
        }
 
@@ -79,7 +79,7 @@ class BlockTest extends MediaWikiLangTestCase {
        function testBug26425BlockTimestampDefaultsToTime() {
                // delta to stop one-off errors when things happen to go over a second mark.
                $delta = abs( $this->madeAt - $this->block->mTimestamp );
-               $this->assertLessThan( 2, $delta, "If no timestamp is specified, the block is recorded as time()");
+               $this->assertLessThan( 2, $delta, "If no timestamp is specified, the block is recorded as time()" );
 
        }
 
@@ -95,7 +95,7 @@ class BlockTest extends MediaWikiLangTestCase {
                $this->hideDeprecated( 'Block::load' );
 
                $uid = User::idFromName( 'UTBlockee' );
-               $this->assertTrue( ($uid > 0), 'Must be able to look up the target user during tests' );
+               $this->assertTrue( ( $uid > 0 ), 'Must be able to look up the target user during tests' );
 
                $block = new Block();
                $ok = $block->load( $vagueTarget, $uid );
@@ -112,7 +112,7 @@ class BlockTest extends MediaWikiLangTestCase {
         * @dataProvider provideBug29116Data
         */
        function testBug29116NewFromTargetWithEmptyIp( $vagueTarget ) {
-               $block = Block::newFromTarget('UTBlockee', $vagueTarget);
+               $block = Block::newFromTarget( 'UTBlockee', $vagueTarget );
                $this->assertTrue( $this->block->equals( $block ), "newFromTarget() returns the same block as the one that was made when given empty vagueTarget param " . var_export( $vagueTarget, true ) );
        }
 
index 36fde85..b64a54e 100644 (file)
@@ -59,8 +59,8 @@ class EditPageTest extends MediaWikiTestCase {
         * wrapper around assertEquals() which calls rrtrim() to normalize the
         * expected and actual texts.
         */
-       function assertEditedTextEquals( $expected, $actual, $msg='' ) {
-               return $this->assertEquals( rtrim($expected), rtrim($actual), $msg );
+       function assertEditedTextEquals( $expected, $actual, $msg = '' ) {
+               return $this->assertEquals( rtrim( $expected ), rtrim( $actual ), $msg );
        }
 
        /**
@@ -209,8 +209,7 @@ class EditPageTest extends MediaWikiTestCase {
        }
 
        public static function provideSectionEdit() {
-               $text =
-'Intro
+               $text = 'Intro
 
 == one ==
 first section.
@@ -219,19 +218,19 @@ first section.
 second section.
 ';
 
-               $sectionOne =
-'== one ==
+               $sectionOne = '== one ==
 hello
 ';
 
-               $newSection =
-'== new section ==
+               $newSection = '== new section ==
 
 hello
 ';
 
-               $textWithNewSectionOne = preg_replace( '/== one ==.*== two ==/ms',
-                                                                               "$sectionOne\n== two ==", $text );
+               $textWithNewSectionOne = preg_replace(
+                       '/== one ==.*== two ==/ms',
+                       "$sectionOne\n== two ==", $text
+               );
 
                $textWithNewSectionAdded = "$text\n$newSection";
 
@@ -343,12 +342,12 @@ hello
                );
 
                // see whether it makes a difference who did the base edit
-               $testsWithAdam = array_map( function( $test ) {
+               $testsWithAdam = array_map( function ( $test ) {
                        $test[0] = 'Adam'; // change base edit user
                        return $test;
                }, $tests );
 
-               $testsWithBerta = array_map( function( $test ) {
+               $testsWithBerta = array_map( function ( $test ) {
                        $test[0] = 'Berta'; // change base edit user
                        return $test;
                }, $tests );
@@ -360,7 +359,7 @@ hello
         * @dataProvider provideAutoMerge
         */
        public function testAutoMerge( $baseUser, $text, $adamsEdit, $bertasEdit,
-                               $expectedCode, $expectedText, $message = null
+               $expectedCode, $expectedText, $message = null
        ) {
                $this->checkHasDiff3();
 
@@ -378,7 +377,7 @@ hello
                );
 
                $page = $this->assertEdit( 'EditPageTest_testAutoMerge', null,
-                                       $baseUser, $baseEdit, null, null, __METHOD__ );
+                       $baseUser, $baseEdit, null, null, __METHOD__ );
 
                $this->forceRevisionDate( $page, '20120101000000' );
 
index 46aa6fc..067cfc4 100644 (file)
@@ -18,7 +18,7 @@ class ExtraParserTest extends MediaWikiTestCase {
                        'wgAlwaysUseTidy' => false,
                        'wgCleanSignatures' => true,
                ) );
-               
+
                $this->options = ParserOptions::newFromUserAndLang( new User, $contLang );
                $this->options->setTemplateCallback( array( __CLASS__, 'statelessFetchTemplate' ) );
                $this->parser = new Parser;
@@ -30,20 +30,20 @@ class ExtraParserTest extends MediaWikiTestCase {
        function testBug8689() {
                global $wgUser;
                $longLine = '1.' . str_repeat( '1234567890', 100000 ) . "\n";
-               
+
                $t = Title::newFromText( 'Unit test' );
                $options = ParserOptions::newFromUser( $wgUser );
                $this->assertEquals( "<p>$longLine</p>",
                        $this->parser->parse( $longLine, $t, $options )->getText() );
        }
-       
+
        /* Test the parser entry points */
        function testParse() {
                $title = Title::newFromText( __FUNCTION__ );
                $parserOutput = $this->parser->parse( "Test\n{{Foo}}\n{{Bar}}", $title, $this->options );
                $this->assertEquals( "<p>Test\nContent of <i>Template:Foo</i>\nContent of <i>Template:Bar</i>\n</p>", $parserOutput->getText() );
        }
-       
+
        function testPreSaveTransform() {
                global $wgUser;
                $title = Title::newFromText( __FUNCTION__ );
@@ -51,21 +51,21 @@ class ExtraParserTest extends MediaWikiTestCase {
 
                $this->assertEquals( "Test\nContent of ''Template:Foo''\n{{Bar}}", $outputText );
        }
-       
+
        function testPreprocess() {
                $title = Title::newFromText( __FUNCTION__ );
                $outputText = $this->parser->preprocess( "Test\n{{Foo}}\n{{Bar}}", $title, $this->options );
-               
+
                $this->assertEquals( "Test\nContent of ''Template:Foo''\nContent of ''Template:Bar''", $outputText );
        }
-       
+
        /**
         * cleanSig() makes all templates substs and removes tildes
         */
        function testCleanSig() {
                $title = Title::newFromText( __FUNCTION__ );
                $outputText = $this->parser->cleanSig( "{{Foo}} ~~~~" );
-               
+
                $this->assertEquals( "{{SUBST:Foo}} ", $outputText );
        }
 
@@ -78,18 +78,18 @@ class ExtraParserTest extends MediaWikiTestCase {
 
                $title = Title::newFromText( __FUNCTION__ );
                $outputText = $this->parser->cleanSig( "{{Foo}} ~~~~" );
-               
+
                $this->assertEquals( "{{Foo}} ~~~~", $outputText );
        }
-       
+
        /**
         * cleanSigInSig() just removes tildes
         * @dataProvider provideStringsForCleanSigInSig
         */
        function testCleanSigInSig( $in, $out ) {
-               $this->assertEquals( Parser::cleanSigInSig( $in), $out );
+               $this->assertEquals( Parser::cleanSigInSig( $in ), $out );
        }
-       
+
        public static function provideStringsForCleanSigInSig() {
                return array(
                        array( "{{Foo}} ~~~~", "{{Foo}} " ),
@@ -97,35 +97,35 @@ class ExtraParserTest extends MediaWikiTestCase {
                        array( "~~~~~", "" ),
                );
        }
-       
+
        function testGetSection() {
                $outputText2 = $this->parser->getSection( "Section 0\n== Heading 1 ==\nSection 1\n=== Heading 2 ===\nSection 2\n== Heading 3 ==\nSection 3\n", 2 );
                $outputText1 = $this->parser->getSection( "Section 0\n== Heading 1 ==\nSection 1\n=== Heading 2 ===\nSection 2\n== Heading 3 ==\nSection 3\n", 1 );
-               
+
                $this->assertEquals( "=== Heading 2 ===\nSection 2", $outputText2 );
                $this->assertEquals( "== Heading 1 ==\nSection 1\n=== Heading 2 ===\nSection 2", $outputText1 );
        }
-       
+
        function testReplaceSection() {
                $outputText = $this->parser->replaceSection( "Section 0\n== Heading 1 ==\nSection 1\n=== Heading 2 ===\nSection 2\n== Heading 3 ==\nSection 3\n", 1, "New section 1" );
-               
+
                $this->assertEquals( "Section 0\nNew section 1\n\n== Heading 3 ==\nSection 3", $outputText );
        }
-       
+
        /**
         * Templates and comments are not affected, but noinclude/onlyinclude is.
         */
        function testGetPreloadText() {
                $title = Title::newFromText( __FUNCTION__ );
                $outputText = $this->parser->getPreloadText( "{{Foo}}<noinclude> censored</noinclude> information <!-- is very secret -->", $title, $this->options );
-               
+
                $this->assertEquals( "{{Foo}} information <!-- is very secret -->", $outputText );
        }
-       
-       static function statelessFetchTemplate( $title, $parser=false ) {
+
+       static function statelessFetchTemplate( $title, $parser = false ) {
                $text = "Content of ''" . $title->getFullText() . "''";
                $deps = array();
-               
+
                return array(
                        'text' => $text,
                        'finalTitle' => $title,
@@ -137,7 +137,7 @@ class ExtraParserTest extends MediaWikiTestCase {
         */
        function testTrackingCategory() {
                $title = Title::newFromText( __FUNCTION__ );
-               $catName =  wfMessage( 'broken-file-category' )->inContentLanguage()->text();
+               $catName = wfMessage( 'broken-file-category' )->inContentLanguage()->text();
                $cat = Title::makeTitleSafe( NS_CATEGORY, $catName );
                $expected = array( $cat->getDBkey() );
                $parserOutput = $this->parser->parse( "[[file:nonexistent]]", $title, $this->options );
@@ -155,4 +155,4 @@ class ExtraParserTest extends MediaWikiTestCase {
                $result = $parserOutput->getCategoryLinks();
                $this->assertEmpty( $result );
        }
- }
+}
index 99f8fb7..4053683 100644 (file)
@@ -46,15 +46,15 @@ class FormOptionsInitializationTest extends MediaWikiTestCase {
        }
 
        public function testAddStringOption() {
-               $this->object->add( 'foo', 'string value' ); 
+               $this->object->add( 'foo', 'string value' );
                $this->assertEquals(
                        array(
                                'foo' => array(
-                                       'default'  => 'string value',
+                                       'default' => 'string value',
                                        'consumed' => false,
-                                       'type'   => FormOptions::STRING,
-                                       'value' => null,
-                                       )
+                                       'type' => FormOptions::STRING,
+                                       'value' => null,
+                               )
                        ),
                        $this->object->getOptions()
                );
@@ -66,17 +66,17 @@ class FormOptionsInitializationTest extends MediaWikiTestCase {
                $this->assertEquals(
                        array(
                                'negone' => array(
-                                       'default'  => -1,
-                                       'value' => null,
+                                       'default' => -1,
+                                       'value' => null,
                                        'consumed' => false,
-                                       'type'   => FormOptions::INT,
-                                       ),
+                                       'type' => FormOptions::INT,
+                               ),
                                'one' => array(
-                                       'default'  => 1,
-                                       'value' => null,
+                                       'default' => 1,
+                                       'value' => null,
                                        'consumed' => false,
-                                       'type'   => FormOptions::INT,
-                                       )
+                                       'type' => FormOptions::INT,
+                               )
                        ),
                        $this->object->getOptions()
                );
index bdc5f12..0a13cfe 100644 (file)
@@ -62,30 +62,30 @@ class FormOptionsTest extends MediaWikiTestCase {
         * Reuse helpers above assertGuessBoolean assertGuessInt assertGuessString
         */
        public function testGuessTypeDetection() {
-               $this->assertGuessBoolean( true  );
+               $this->assertGuessBoolean( true );
                $this->assertGuessBoolean( false );
 
-               $this->assertGuessInt(    0 );
-               $this->assertGuessInt(   -5 );
-               $this->assertGuessInt(    5 );
+               $this->assertGuessInt( 0 );
+               $this->assertGuessInt( -5 );
+               $this->assertGuessInt( 5 );
                $this->assertGuessInt( 0x0F );
 
-               $this->assertGuessString( 'true'  );
-               $this->assertGuessString( 'false' ); 
-               $this->assertGuessString( '5'     ); 
-               $this->assertGuessString( '0'     ); 
+               $this->assertGuessString( 'true' );
+               $this->assertGuessString( 'false' );
+               $this->assertGuessString( '5' );
+               $this->assertGuessString( '0' );
        }
 
        /**
-        * @expectedException MWException 
+        * @expectedException MWException
         */
        public function testGuessTypeOnArrayThrowException() {
-               $this->object->guessType( array( 'foo' ) ); 
+               $this->object->guessType( array( 'foo' ) );
        }
        /**
-        * @expectedException MWException 
+        * @expectedException MWException
         */
        public function testGuessTypeOnNullThrowException() {
-               $this->object->guessType( null ); 
+               $this->object->guessType( null );
        }
 }
index 105ce6d..24fc47c 100644 (file)
@@ -32,7 +32,7 @@ class GlobalTest extends MediaWikiTestCase {
        /** @dataProvider provideForWfArrayDiff2 */
        public function testWfArrayDiff2( $a, $b, $expected ) {
                $this->assertEquals(
-                       wfArrayDiff2( $a, $b), $expected
+                       wfArrayDiff2( $a, $b ), $expected
                );
        }
 
@@ -41,13 +41,13 @@ class GlobalTest extends MediaWikiTestCase {
                // $a $b $expected
                return array(
                        array(
-                               array( 'a', 'b'),
-                               array( 'a', 'b'),
+                               array( 'a', 'b' ),
+                               array( 'a', 'b' ),
                                array(),
                        ),
                        array(
-                               array( array( 'a'), array( 'a', 'b', 'c' )),
-                               array( array( 'a'), array( 'a', 'b' )),
+                               array( array( 'a' ), array( 'a', 'b', 'c' ) ),
+                               array( array( 'a' ), array( 'a', 'b' ) ),
                                array( 1 => array( 'a', 'b', 'c' ) ),
                        ),
                );
@@ -191,21 +191,21 @@ class GlobalTest extends MediaWikiTestCase {
                        'text/html',
                        mimeTypeMatch( 'text/html',
                                array( 'application/xhtml+xml' => 1.0,
-                                      'text/html'             => 0.7,
-                                      'text/plain'            => 0.3 ) ) );
+                                       'text/html' => 0.7,
+                                       'text/plain' => 0.3 ) ) );
                $this->assertEquals(
                        'text/*',
                        mimeTypeMatch( 'text/html',
                                array( 'image/*' => 1.0,
-                                      'text/*'  => 0.5 ) ) );
+                                       'text/*' => 0.5 ) ) );
                $this->assertEquals(
                        '*/*',
                        mimeTypeMatch( 'text/html',
                                array( '*/*' => 1.0 ) ) );
                $this->assertNull(
                        mimeTypeMatch( 'text/html',
-                               array( 'image/png'     => 1.0,
-                                      'image/svg+xml' => 0.5 ) ) );
+                               array( 'image/png' => 1.0,
+                                       'image/svg+xml' => 0.5 ) ) );
        }
 
        function testNegotiateType() {
@@ -213,51 +213,51 @@ class GlobalTest extends MediaWikiTestCase {
                        'text/html',
                        wfNegotiateType(
                                array( 'application/xhtml+xml' => 1.0,
-                                      'text/html'             => 0.7,
-                                      'text/plain'            => 0.5,
-                                      'text/*'                => 0.2 ),
-                               array( 'text/html'             => 1.0 ) ) );
+                                       'text/html' => 0.7,
+                                       'text/plain' => 0.5,
+                                       'text/*' => 0.2 ),
+                               array( 'text/html' => 1.0 ) ) );
                $this->assertEquals(
                        'application/xhtml+xml',
                        wfNegotiateType(
                                array( 'application/xhtml+xml' => 1.0,
-                                      'text/html'             => 0.7,
-                                      'text/plain'            => 0.5,
-                                      'text/*'                => 0.2 ),
+                                       'text/html' => 0.7,
+                                       'text/plain' => 0.5,
+                                       'text/*' => 0.2 ),
                                array( 'application/xhtml+xml' => 1.0,
-                                      'text/html'             => 0.5 ) ) );
+                                       'text/html' => 0.5 ) ) );
                $this->assertEquals(
                        'text/html',
                        wfNegotiateType(
-                               array( 'text/html'             => 1.0,
-                                      'text/plain'            => 0.5,
-                                      'text/*'                => 0.5,
-                                      'application/xhtml+xml' => 0.2 ),
+                               array( 'text/html' => 1.0,
+                                       'text/plain' => 0.5,
+                                       'text/*' => 0.5,
+                                       'application/xhtml+xml' => 0.2 ),
                                array( 'application/xhtml+xml' => 1.0,
-                                      'text/html'             => 0.5 ) ) );
+                                       'text/html' => 0.5 ) ) );
                $this->assertEquals(
                        'text/html',
                        wfNegotiateType(
-                               array( 'text/*'                => 1.0,
-                                      'image/*'               => 0.7,
-                                      '*/*'                   => 0.3 ),
+                               array( 'text/*' => 1.0,
+                                       'image/*' => 0.7,
+                                       '*/*' => 0.3 ),
                                array( 'application/xhtml+xml' => 1.0,
-                                      'text/html'             => 0.5 ) ) );
+                                       'text/html' => 0.5 ) ) );
                $this->assertNull(
                        wfNegotiateType(
-                               array( 'text/*'                => 1.0 ),
+                               array( 'text/*' => 1.0 ),
                                array( 'application/xhtml+xml' => 1.0 ) ) );
        }
-       
+
        function testFallbackMbstringFunctions() {
-               
-               if( !extension_loaded( 'mbstring' ) ) {
+
+               if ( !extension_loaded( 'mbstring' ) ) {
                        $this->markTestSkipped( "The mb_string functions must be installed to test the fallback functions" );
                }
-               
+
                $sampleUTF = "Östergötland_coat_of_arms.png";
-               
-               
+
+
                //mb_substr
                $substr_params = array(
                        array( 0, 0 ),
@@ -268,27 +268,27 @@ class GlobalTest extends MediaWikiTestCase {
                        array( 1, 1 ),
                        array( 2, -1 )
                );
-               
-               foreach( $substr_params as $param_set ) {
+
+               foreach ( $substr_params as $param_set ) {
                        $old_param_set = $param_set;
                        array_unshift( $param_set, $sampleUTF );
-                       
+
                        $this->assertEquals(
                                MWFunction::callArray( 'mb_substr', $param_set ),
                                MWFunction::callArray( 'Fallback::mb_substr', $param_set ),
                                'Fallback mb_substr with params ' . implode( ', ', $old_param_set )
-                       );                      
+                       );
                }
-               
-               
+
+
                //mb_strlen
                $this->assertEquals(
                        mb_strlen( $sampleUTF ),
                        Fallback::mb_strlen( $sampleUTF ),
                        'Fallback mb_strlen'
-               );                      
-               
-               
+               );
+
+
                //mb_str(r?)pos
                $strpos_params = array(
                        //array( 'ter' ),
@@ -298,24 +298,24 @@ class GlobalTest extends MediaWikiTestCase {
                        //array( 'c', -10 ),
                        //Broken for now
                );
-               
-               foreach( $strpos_params as $param_set ) {
+
+               foreach ( $strpos_params as $param_set ) {
                        $old_param_set = $param_set;
                        array_unshift( $param_set, $sampleUTF );
-                       
+
                        $this->assertEquals(
                                MWFunction::callArray( 'mb_strpos', $param_set ),
                                MWFunction::callArray( 'Fallback::mb_strpos', $param_set ),
                                'Fallback mb_strpos with params ' . implode( ', ', $old_param_set )
-                       );              
-                       
+                       );
+
                        $this->assertEquals(
                                MWFunction::callArray( 'mb_strrpos', $param_set ),
                                MWFunction::callArray( 'Fallback::mb_strrpos', $param_set ),
                                'Fallback mb_strrpos with params ' . implode( ', ', $old_param_set )
-                       );      
+                       );
                }
-               
+
        }
 
 
@@ -347,7 +347,7 @@ class GlobalTest extends MediaWikiTestCase {
                $this->assertGreaterThan( 5000, preg_replace( '/\D/', '', file_get_contents( $wgDebugLogFile ) ) );
                unlink( $wgDebugLogFile );
 
-               wfDebugMem(true);
+               wfDebugMem( true );
                $this->assertGreaterThan( 5000000, preg_replace( '/\D/', '', file_get_contents( $wgDebugLogFile ) ) );
                unlink( $wgDebugLogFile );
 
@@ -357,7 +357,7 @@ class GlobalTest extends MediaWikiTestCase {
        }
 
        function testClientAcceptsGzipTest() {
-               
+
                $settings = array(
                        'gzip' => true,
                        'bzip' => false,
@@ -370,25 +370,24 @@ class GlobalTest extends MediaWikiTestCase {
                        'gzip;q=12345678.9' => true,
                        ' gzip' => true,
                );
-               
-               if( isset( $_SERVER['HTTP_ACCEPT_ENCODING'] ) ) $old_server_setting = $_SERVER['HTTP_ACCEPT_ENCODING'];
-               
+
+               if ( isset( $_SERVER['HTTP_ACCEPT_ENCODING'] ) ) {
+                       $old_server_setting = $_SERVER['HTTP_ACCEPT_ENCODING'];
+               }
+
                foreach ( $settings as $encoding => $expect ) {
                        $_SERVER['HTTP_ACCEPT_ENCODING'] = $encoding;
-                       
+
                        $this->assertEquals( $expect, wfClientAcceptsGzip( true ),
                                "'$encoding' => " . wfBoolToStr( $expect ) );
                }
-               
-               if( isset( $old_server_setting ) ) $_SERVER['HTTP_ACCEPT_ENCODING'] = $old_server_setting;
 
+               if ( isset( $old_server_setting ) ) {
+                       $_SERVER['HTTP_ACCEPT_ENCODING'] = $old_server_setting;
+               }
        }
-       
-       
-       
-       function testSwapVarsTest() {
-       
 
+       function testSwapVarsTest() {
                $var1 = 1;
                $var2 = 2;
 
@@ -402,36 +401,29 @@ class GlobalTest extends MediaWikiTestCase {
 
        }
 
-
        function testWfPercentTest() {
 
                $pcts = array(
-                       array( 6/7, '0.86%', 2, false ),
-                       array( 3/3, '1%' ),
-                       array( 22/7, '3.14286%', 5 ),
-                       array( 3/6, '0.5%' ),
-                       array( 1/3, '0%', 0 ),
-                       array( 10/3, '0%', -1 ),
-                       array( 3/4/5, '0.1%', 1 ),
-                       array( 6/7*8, '6.8571428571%', 10 ),
+                       array( 6 / 7, '0.86%', 2, false ),
+                       array( 3 / 3, '1%' ),
+                       array( 22 / 7, '3.14286%', 5 ),
+                       array( 3 / 6, '0.5%' ),
+                       array( 1 / 3, '0%', 0 ),
+                       array( 10 / 3, '0%', -1 ),
+                       array( 3 / 4 / 5, '0.1%', 1 ),
+                       array( 6 / 7 * 8, '6.8571428571%', 10 ),
                );
-               
-               foreach( $pcts as $pct ) {
-                       if( !isset( $pct[2] ) ) $pct[2] = 2;
-                       if( !isset( $pct[3] ) ) $pct[3] = true;
-                       
-                       $this->assertEquals( wfPercent( $pct[0], $pct[2], $pct[3] ), $pct[1], $pct[1] );
-               }
-
-       }
 
+               foreach ( $pcts as $pct ) {
+                       if ( !isset( $pct[2] ) ) {
+                               $pct[2] = 2;
+                       }
+                       if ( !isset( $pct[3] ) ) {
+                               $pct[3] = true;
+                       }
 
-       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' );
-       
+                       $this->assertEquals( wfPercent( $pct[0], $pct[2], $pct[3] ), $pct[1], $pct[1] );
+               }
        }
 
        /**
@@ -441,47 +433,47 @@ class GlobalTest extends MediaWikiTestCase {
        public function testWfShorthandToInteger( $shorthand, $expected ) {
                $this->assertEquals( $expected,
                        wfShorthandToInteger( $shorthand )
-               );      
+               );
        }
 
        /** array( shorthand, expected integer ) */
        public static function provideShorthand() {
                return array(
                        # Null, empty ... 
-                       array(     '', -1),
-                       array(   '  ', -1),
-                       array(   null, -1),
+                       array( '', -1 ),
+                       array( '  ', -1 ),
+                       array( null, -1 ),
 
                        # Failures returns 0 :(
                        array( 'ABCDEFG', 0 ),
-                       array( 'Ak',      0 ),
+                       array( 'Ak', 0 ),
 
                        # Int, strings with spaces
-                       array(        1,    1 ),
-                       array(    ' 1 ',    1 ),
-                       array(     1023, 1023 ),
+                       array( 1, 1 ),
+                       array( ' 1 ', 1 ),
+                       array( 1023, 1023 ),
                        array( ' 1023 ', 1023 ),
 
                        # kilo, Mega, Giga
-                       array(   '1k', 1024 ),
-                       array(   '1K', 1024 ),
-                       array(   '1m', 1024 * 1024 ),
-                       array(   '1M', 1024 * 1024 ),
-                       array(   '1g', 1024 * 1024 * 1024 ),
-                       array(   '1G', 1024 * 1024 * 1024 ),
+                       array( '1k', 1024 ),
+                       array( '1K', 1024 ),
+                       array( '1m', 1024 * 1024 ),
+                       array( '1M', 1024 * 1024 ),
+                       array( '1g', 1024 * 1024 * 1024 ),
+                       array( '1G', 1024 * 1024 * 1024 ),
 
                        # Negatives
-                       array(     -1,    -1 ),
-                       array(   -500,  -500 ),
-                       array( '-500',  -500 ),
-                       array(  '-1k', -1024 ),
+                       array( -1, -1 ),
+                       array( -500, -500 ),
+                       array( '-500', -500 ),
+                       array( '-1k', -1024 ),
 
                        # Zeroes
-                       array(   '0', 0 ),
-                       array(  '0k', 0 ),
-                       array(  '0M', 0 ),
-                       array(  '0G', 0 ),
-                       array(  '-0', 0 ),
+                       array( '0', 0 ),
+                       array( '0k', 0 ),
+                       array( '0M', 0 ),
+                       array( '0G', 0 ),
+                       array( '-0', 0 ),
                        array( '-0k', 0 ),
                        array( '-0M', 0 ),
                        array( '-0G', 0 ),
@@ -508,7 +500,7 @@ class GlobalTest extends MediaWikiTestCase {
                $msg .= $expectedMergeResult ? 'success' : 'failure';
                $this->assertEquals( $expectedMergeResult, $isMerged, $msg );
 
-               if( $isMerged ) {
+               if ( $isMerged ) {
                        // Verify the merged text
                        $this->assertEquals( $expectedText, $mergedText,
                                'is merged text as expected?' );
@@ -520,31 +512,30 @@ class GlobalTest extends MediaWikiTestCase {
                $EXPECT_MERGE_FAILURE = false;
 
                return array(
-
                        // #0: clean merge
                        array(
                                // old:
                                "one one one\n" . // trimmed
-                               "\n" .
-                               "two two two",
+                                       "\n" .
+                                       "two two two",
 
                                // mine:
                                "one one one ONE ONE\n" .
-                               "\n" .
-                               "two two two\n", // with tailing whitespace
+                                       "\n" .
+                                       "two two two\n", // with tailing whitespace
 
                                // yours:
                                "one one one\n" .
-                               "\n" .
-                               "two two TWO TWO", // trimmed
+                                       "\n" .
+                                       "two two TWO TWO", // trimmed
 
                                // ok:
                                $EXPECT_MERGE_SUCCESS,
 
                                // result:
                                "one one one ONE ONE\n" .
-                               "\n" .
-                               "two two TWO TWO\n", // note: will always end in a newline
+                                       "\n" .
+                                       "two two TWO TWO\n", // note: will always end in a newline
                        ),
 
                        // #1: conflict, fail
@@ -554,14 +545,14 @@ class GlobalTest extends MediaWikiTestCase {
 
                                // mine:
                                "one one one ONE ONE\n" .
-                               "\n" .
-                               "bla bla\n" .
-                               "\n", // with tailing whitespace
+                                       "\n" .
+                                       "bla bla\n" .
+                                       "\n", // with tailing whitespace
 
                                // yours:
                                "one one one\n" .
-                               "\n" .
-                               "two two", // trimmed
+                                       "\n" .
+                                       "two two", // trimmed
 
                                $EXPECT_MERGE_FAILURE,
 
@@ -627,7 +618,7 @@ class GlobalTest extends MediaWikiTestCase {
                        ),
                );
        }
-       
+
        /**
         * @dataProvider provideWfMatchesDomainList
         */
@@ -635,7 +626,7 @@ class GlobalTest extends MediaWikiTestCase {
                $actual = wfMatchesDomainList( $url, $domains );
                $this->assertEquals( $expected, $actual, $description );
        }
-       
+
        function provideWfMatchesDomainList() {
                $a = array();
                $protocols = array( 'HTTP' => 'http:', 'HTTPS' => 'https:', 'protocol-relative' => '' );
@@ -647,7 +638,7 @@ class GlobalTest extends MediaWikiTestCase {
                                array( "$p//www.example2.com", array( 'www.example.com', 'www.example2.com', 'www.example3.com' ), true, "Exact match with other domains in array, $pDesc URL" ),
                                array( "$p//www.example2.com", array( 'example.com', 'example2.com', 'example3,com' ), true, "Match without subdomain with other domains in array, $pDesc URL" ),
                                array( "$p//www.example4.com", array( 'example.com', 'example2.com', 'example3,com' ), false, "Domain not in array, $pDesc URL" ),
-                               
+
                                // FIXME: This is a bug in wfMatchesDomainList(). If and when this is fixed, update this test case
                                array( "$p//nds-nl.wikipedia.org", array( 'nl.wikipedia.org' ), true, "Substrings of domains match while they shouldn't, $pDesc URL" ),
                        ) );
@@ -659,7 +650,7 @@ class GlobalTest extends MediaWikiTestCase {
         * @dataProvider provideWfShellMaintenanceCmdList
         */
        function testWfShellMaintenanceCmd( $script, $parameters, $options, $expected, $description ) {
-               if( wfIsWindows() ) {
+               if ( wfIsWindows() ) {
                        // Approximation that's good enough for our purposes just now
                        $expected = str_replace( "'", '"', $expected );
                }
@@ -673,13 +664,13 @@ class GlobalTest extends MediaWikiTestCase {
                        array( 'eval.php', array( '--help', '--test' ), array(),
                                "'$wgPhpCli' 'eval.php' '--help' '--test'",
                                "Called eval.php --help --test" ),
-                       array( 'eval.php', array( '--help', '--test space' ), array('php' => 'php5'),
+                       array( 'eval.php', array( '--help', '--test space' ), array( 'php' => 'php5' ),
                                "'php5' 'eval.php' '--help' '--test space'",
                                "Called eval.php --help --test with php option" ),
-                       array( 'eval.php', array( '--help', '--test', 'X' ), array('wrapper' => 'MWScript.php'),
+                       array( 'eval.php', array( '--help', '--test', 'X' ), array( 'wrapper' => 'MWScript.php' ),
                                "'$wgPhpCli' 'MWScript.php' 'eval.php' '--help' '--test' 'X'",
                                "Called eval.php --help --test with wrapper option" ),
-                       array( 'eval.php', array( '--help', '--test', 'y' ), array('php' => 'php5', 'wrapper' => 'MWScript.php'),
+                       array( 'eval.php', array( '--help', '--test', 'y' ), array( 'php' => 'php5', 'wrapper' => 'MWScript.php' ),
                                "'php5' 'MWScript.php' 'eval.php' '--help' '--test' 'y'",
                                "Called eval.php --help --test with wrapper and php option" ),
                );
index bed435a..21fff68 100644 (file)
@@ -83,7 +83,7 @@ class wfAssembleUrl extends MediaWikiTestCase {
                                                                $parts['query'] = $query;
                                                                $url .= '?' . $query;
                                                        }
-                                                       if( $fragment ) {
+                                                       if ( $fragment ) {
                                                                $parts['fragment'] = $fragment;
                                                                $url .= '#' . $fragment;
                                                        }
index 4a0f406..0b048b4 100644 (file)
@@ -15,12 +15,12 @@ class wfBCP47 extends MediaWikiTestCase {
         */
        function testBCP47( $code, $expected ) {
                $code = strtolower( $code );
-               $this->assertEquals( $expected, wfBCP47($code),
+               $this->assertEquals( $expected, wfBCP47( $code ),
                        "Applying BCP47 standard to lower case '$code'"
                );
 
                $code = strtoupper( $code );
-               $this->assertEquals( $expected, wfBCP47($code),
+               $this->assertEquals( $expected, wfBCP47( $code ),
                        "Applying BCP47 standard to upper case '$code'"
                );
        }
@@ -32,15 +32,15 @@ class wfBCP47 extends MediaWikiTestCase {
                return array(
                        // Extracted from BCP47 (list not exhaustive)
                        # 2.1.1
-                       array( 'en-ca-x-ca'    , 'en-CA-x-ca'     ),
-                       array( 'sgn-be-fr'     , 'sgn-BE-FR'      ),
+                       array( 'en-ca-x-ca', 'en-CA-x-ca' ),
+                       array( 'sgn-be-fr', 'sgn-BE-FR' ),
                        array( 'az-latn-x-latn', 'az-Latn-x-latn' ),
                        # 2.2
                        array( 'sr-Latn-RS', 'sr-Latn-RS' ),
                        array( 'az-arab-ir', 'az-Arab-IR' ),
 
                        # 2.2.5
-                       array( 'sl-nedis'  , 'sl-nedis'   ),
+                       array( 'sl-nedis', 'sl-nedis' ),
                        array( 'de-ch-1996', 'de-CH-1996' ),
 
                        # 2.2.6
@@ -56,40 +56,40 @@ class wfBCP47 extends MediaWikiTestCase {
                        array( 'ja', 'ja' ),
 
                        # Language subtag plus script subtag:
-                       array( 'zh-hans', 'zh-Hans'),
-                       array( 'sr-cyrl', 'sr-Cyrl'),
-                       array( 'sr-latn', 'sr-Latn'),
+                       array( 'zh-hans', 'zh-Hans' ),
+                       array( 'sr-cyrl', 'sr-Cyrl' ),
+                       array( 'sr-latn', 'sr-Latn' ),
 
                        # Extended language subtags and their primary language subtag
                        # counterparts:
                        array( 'zh-cmn-hans-cn', 'zh-cmn-Hans-CN' ),
-                       array( 'cmn-hans-cn'   , 'cmn-Hans-CN'    ),
-                       array( 'zh-yue-hk'     , 'zh-yue-HK'      ),
-                       array( 'yue-hk'        , 'yue-HK'         ),
+                       array( 'cmn-hans-cn', 'cmn-Hans-CN' ),
+                       array( 'zh-yue-hk', 'zh-yue-HK' ),
+                       array( 'yue-hk', 'yue-HK' ),
 
                        # Language-Script-Region:
                        array( 'zh-hans-cn', 'zh-Hans-CN' ),
                        array( 'sr-latn-RS', 'sr-Latn-RS' ),
 
                        # Language-Variant:
-                       array( 'sl-rozaj'      , 'sl-rozaj'       ),
+                       array( 'sl-rozaj', 'sl-rozaj' ),
                        array( 'sl-rozaj-biske', 'sl-rozaj-biske' ),
-                       array( 'sl-nedis'      , 'sl-nedis'       ),
+                       array( 'sl-nedis', 'sl-nedis' ),
 
                        # Language-Region-Variant:
-                       array( 'de-ch-1901'  , 'de-CH-1901'  ),
-                       array( 'sl-it-nedis' , 'sl-IT-nedis' ),
+                       array( 'de-ch-1901', 'de-CH-1901' ),
+                       array( 'sl-it-nedis', 'sl-IT-nedis' ),
 
                        # Language-Script-Region-Variant:
                        array( 'hy-latn-it-arevela', 'hy-Latn-IT-arevela' ),
 
                        # Language-Region:
-                       array( 'de-de' , 'de-DE' ),
-                       array( 'en-us' , 'en-US' ),
-                       array( 'es-419', 'es-419'),
+                       array( 'de-de', 'de-DE' ),
+                       array( 'en-us', 'en-US' ),
+                       array( 'es-419', 'es-419' ),
 
                        # Private use subtags:
-                       array( 'de-ch-x-phonebk'      , 'de-CH-x-phonebk' ),
+                       array( 'de-ch-x-phonebk', 'de-CH-x-phonebk' ),
                        array( 'az-arab-x-aze-derbend', 'az-Arab-x-aze-derbend' ),
                        /**
                         * Previous test does not reflect the BCP which states:
@@ -102,7 +102,7 @@ class wfBCP47 extends MediaWikiTestCase {
                        # Private use registry values:
                        array( 'x-whatever', 'x-whatever' ),
                        array( 'qaa-qaaa-qm-x-southern', 'qaa-Qaaa-QM-x-southern' ),
-                       array( 'de-qaaa'   , 'de-Qaaa'    ),
+                       array( 'de-qaaa', 'de-Qaaa' ),
                        array( 'sr-latn-qm', 'sr-Latn-QM' ),
                        array( 'sr-qaaa-rs', 'sr-Qaaa-RS' ),
 
@@ -115,8 +115,8 @@ class wfBCP47 extends MediaWikiTestCase {
                        // de-419-DE
                        // a-DE
                        // ar-a-aaa-b-bbb-a-ccc
-       
-               /*      
+
+                       /*
                        // ISO 15924 :
                        array( 'sr-Cyrl', 'sr-Cyrl' ),
                        # @todo FIXME: Fix our function?
@@ -128,6 +128,7 @@ class wfBCP47 extends MediaWikiTestCase {
                        array( 'uS', 'us' ),  # USA
                        array( 'Fr', 'fr' ),  # France
                        array( 'va', 'va' ),  # Holy See (Vatican City State)
-                */);
+                        */
+               );
        }
 }
index 21e5032..1731fa0 100644 (file)
@@ -142,13 +142,13 @@ class wfBaseConvertTest extends MediaWikiTestCase {
        public static function provideNumbers() {
                $x = array();
                $chars = '0123456789abcdefghijklmnopqrstuvwxyz';
-               for( $i = 0; $i < 50; $i++ ) {
+               for ( $i = 0; $i < 50; $i++ ) {
                        $base = mt_rand( 2, 36 );
                        $len = mt_rand( 10, 100 );
 
                        $str = '';
-                       for( $j = 0; $j < $len; $j++ ) {
-                               $str .= $chars[mt_rand(0, $base - 1)];
+                       for ( $j = 0; $j < $len; $j++ ) {
+                               $str .= $chars[mt_rand( 0, $base - 1 )];
                        }
 
                        $x[] = array( $base, $str );
index 59954b2..f90c8d0 100644 (file)
@@ -8,9 +8,9 @@ class wfBaseName extends MediaWikiTestCase {
         */
        function testBaseName( $fullpath, $basename ) {
                $this->assertEquals( $basename, wfBaseName( $fullpath ),
-                               "wfBaseName('$fullpath') => '$basename'" );
+                       "wfBaseName('$fullpath') => '$basename'" );
        }
-       
+
        function providePaths() {
                return array(
                        array( '', '' ),
index cb6e6c4..ac39c80 100644 (file)
@@ -51,7 +51,7 @@ class wfExpandUrl extends MediaWikiTestCase {
                foreach ( $modes as $mode ) {
                        $httpsMode = $mode == 'https';
                        foreach ( $servers as $serverDesc => $server ) {
-                               foreach ( $modes as $canServerMode  ) {
+                               foreach ( $modes as $canServerMode ) {
                                        $canServer = "$canServerMode://example2.com";
                                        foreach ( $defaultProtos as $protoDesc => $defaultProto ) {
                                                $retval[] = array(
index 15f3507..3b4ac65 100644 (file)
@@ -15,8 +15,9 @@ class wfGetCaller extends MediaWikiTestCase {
        }
 
        function intermediateFunction( $level = 2, $n = 0 ) {
-               if ( $n > 0 )
+               if ( $n > 0 ) {
                        return self::intermediateFunction( $level, $n - 1 );
+               }
                return wfGetCaller( $level );
        }
 
@@ -28,7 +29,7 @@ class wfGetCaller extends MediaWikiTestCase {
                $this->assertEquals( "wfGetCaller::testN", self::intermediateFunction( 2, 0 ) );
                $this->assertEquals( "wfGetCaller::intermediateFunction", self::intermediateFunction( 1, 0 ) );
 
-               for ($i=0; $i < 10; $i++)
+               for ( $i = 0; $i < 10; $i++ )
                        $this->assertEquals( "wfGetCaller::intermediateFunction", self::intermediateFunction( $i + 1, $i ) );
        }
 }
index 1df26d2..da6c936 100644 (file)
@@ -24,5 +24,5 @@ class wfShorthandToIntegerTest extends MediaWikiTestCase {
                        array( '1k', 1024, 'One kb lowercased' ),
                );
        }
-       
+
 }
index 505c28c..5fd0ed0 100644 (file)
@@ -13,7 +13,7 @@ class wfTimestamp extends MediaWikiTestCase {
 
        function provideNormalTimestamps() {
                $t = gmmktime( 12, 34, 56, 1, 15, 2001 );
-               return array (
+               return array(
                        // TS_UNIX
                        array( $t, TS_MW, '20010115123456', 'TS_UNIX to TS_MW' ),
                        array( -30281104, TS_MW, '19690115123456', 'Negative TS_UNIX to TS_MW' ),
@@ -21,13 +21,13 @@ class wfTimestamp extends MediaWikiTestCase {
                        array( $t, TS_DB, '2001-01-15 12:34:56', 'TS_UNIX to TS_DB' ),
 
                        array( $t, TS_ISO_8601_BASIC, '20010115T123456Z', 'TS_ISO_8601_BASIC to TS_DB' ),
-                       
+
                        // TS_MW
                        array( '20010115123456', TS_MW, '20010115123456', 'TS_MW to TS_MW' ),
                        array( '20010115123456', TS_UNIX, 979562096, 'TS_MW to TS_UNIX' ),
                        array( '20010115123456', TS_DB, '2001-01-15 12:34:56', 'TS_MW to TS_DB' ),
                        array( '20010115123456', TS_ISO_8601_BASIC, '20010115T123456Z', 'TS_MW to TS_ISO_8601_BASIC' ),
-                       
+
                        // TS_DB
                        array( '2001-01-15 12:34:56', TS_MW, '20010115123456', 'TS_DB to TS_MW' ),
                        array( '2001-01-15 12:34:56', TS_UNIX, 979562096, 'TS_DB to TS_UNIX' ),
@@ -62,7 +62,7 @@ class wfTimestamp extends MediaWikiTestCase {
        }
 
        function provideOldTimestamps() {
-               return array (
+               return array(
                        array( '19011213204554', TS_RFC2822, 'Fri, 13 Dec 1901 20:45:54 GMT', 'Earliest time according to php documentation' ),
                        array( '20380119031407', TS_RFC2822, 'Tue, 19 Jan 2038 03:14:07 GMT', 'Latest 32 bit time' ),
                        array( '19011213204552', TS_UNIX, '-2147483648', 'Earliest 32 bit unix time' ),
index 673702e..285a2d6 100644 (file)
@@ -6,9 +6,8 @@
  */
 
 class wfUrlencodeTest extends MediaWikiTestCase {
-
        #### TESTS ##############################################################
-       
+
        /** @dataProvider provideURLS */
        public function testEncodingUrlWith( $input, $expected ) {
                $this->verifyEncodingFor( 'Apache', $input, $expected );
@@ -20,7 +19,7 @@ class wfUrlencodeTest extends MediaWikiTestCase {
        }
 
        #### HELPERS #############################################################
-       
+
        /**
         * Internal helper that actually run the test.
         * Called by the public methods testEncodingUrlWith...()
@@ -30,10 +29,9 @@ class wfUrlencodeTest extends MediaWikiTestCase {
                $expected = $this->extractExpect( $server, $expectations );
 
                // save up global
-               $old = isset($_SERVER['SERVER_SOFTWARE'])
+               $old = isset( $_SERVER['SERVER_SOFTWARE'] )
                        ? $_SERVER['SERVER_SOFTWARE']
-                       : null
-               ;
+                       : null;
                $_SERVER['SERVER_SOFTWARE'] = $server;
                wfUrlencode( null );
 
@@ -45,7 +43,7 @@ class wfUrlencodeTest extends MediaWikiTestCase {
                );
 
                // restore global
-               if( $old === null ) {
+               if ( $old === null ) {
                        unset( $_SERVER['SERVER_SOFTWARE'] );
                } else {
                        $_SERVER['SERVER_SOFTWARE'] = $old;
@@ -58,19 +56,18 @@ class wfUrlencodeTest extends MediaWikiTestCase {
         * the HTTP server name.
         */
        private function extractExpect( $server, $expectations ) {
-               if( is_string( $expectations ) ) {
+               if ( is_string( $expectations ) ) {
                        return $expectations;
-               } elseif( is_array( $expectations ) ) {
-                       if( !array_key_exists( $server, $expectations ) ) {
+               } elseif ( is_array( $expectations ) ) {
+                       if ( !array_key_exists( $server, $expectations ) ) {
                                throw new MWException( __METHOD__ . " expectation does not have any value for server name $server. Check the provider array.\n" );
                        } else {
                                return $expectations[$server];
                        }
-               } else {
+               } else {
                        throw new MWException( __METHOD__ . " given invalid expectation for '$server'. Should be a string or an array( <http server name> => <string> ).\n" );
-               }
-       }  
-
+               }
+       }
 
        #### PROVIDERS ###########################################################
 
@@ -83,11 +80,11 @@ class wfUrlencodeTest extends MediaWikiTestCase {
         *       array( 'Microsoft-IIS/7', 'expected' ),
         *    ),
         * If you want to add other HTTP server name, you will have to add a new
-        * testing method much like the testEncodingUrlWith() method above. 
+        * testing method much like the testEncodingUrlWith() method above.
         */
        public static function provideURLS() {
                return array(
-               ### RFC 1738 chars      
+                       ### RFC 1738 chars
                        // + is not safe
                        array( '+', '%2B' ),
                        // & and = not safe in queries
@@ -95,7 +92,7 @@ class wfUrlencodeTest extends MediaWikiTestCase {
                        array( '=', '%3D' ),
 
                        array( ':', array(
-                               'Apache'          => ':',
+                               'Apache' => ':',
                                'Microsoft-IIS/7' => '%3A',
                        ) ),
 
@@ -105,10 +102,10 @@ class wfUrlencodeTest extends MediaWikiTestCase {
                                ';@$-_.!*',
                        ),
 
-               ### Other tests
+                       ### Other tests
                        // slash remain unchanged. %2F seems to break things
                        array( '/', '/' ),
-       
+
                        // Other 'funnies' chars
                        array( '[]', '%5B%5D' ),
                        array( '<>', '%3C%3E' ),
index 47fa5f4..b6e23ab 100644 (file)
@@ -15,22 +15,22 @@ class HtmlTest extends MediaWikiTestCase {
                $langObj->setNamespaces( array(
                        -2 => 'Media',
                        -1 => 'Special',
-                       0  => '',
-                       1  => 'Talk',
-                       2  => 'User',
-                       3  => 'User_talk',
-                       4  => 'MyWiki',
-                       5  => 'MyWiki_Talk',
-                       6  => 'File',
-                       7  => 'File_talk',
-                       8  => 'MediaWiki',
-                       9  => 'MediaWiki_talk',
-                       10  => 'Template',
-                       11  => 'Template_talk',
-                       14  => 'Category',
-                       15  => 'Category_talk',
-                       100  => 'Custom',
-                       101  => 'Custom_talk',
+                       0 => '',
+                       1 => 'Talk',
+                       2 => 'User',
+                       3 => 'User_talk',
+                       4 => 'MyWiki',
+                       5 => 'MyWiki_Talk',
+                       6 => 'File',
+                       7 => 'File_talk',
+                       8 => 'MediaWiki',
+                       9 => 'MediaWiki_talk',
+                       10 => 'Template',
+                       11 => 'Template_talk',
+                       14 => 'Category',
+                       15 => 'Category_talk',
+                       100 => 'Custom',
+                       101 => 'Custom_talk',
                ) );
 
                $this->setMwGlobals( array(
@@ -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'
                );
        }
 
@@ -248,12 +248,12 @@ class HtmlTest extends MediaWikiTestCase {
                                'one' => 1,
 
                                # Method use isset() internally, make sure we do discard
-                           # attributes values which have been assigned well known values
+                               # attributes values which have been assigned well known values
                                'emptystring' => '',
                                'boolfalse' => false,
                                'zero' => 0,
                                'null' => null,
-                       )))
+                       ) ) )
                );
        }
 
@@ -271,55 +271,55 @@ class HtmlTest extends MediaWikiTestCase {
                                'GREEN',
                                'GREEN' => false,
                                'GREEN',
-                       )))
+                       ) ) )
                );
        }
 
        function testNamespaceSelector() {
                $this->assertEquals(
                        '<select id=namespace name=namespace>' . "\n" .
-'<option value=0>(Main)</option>' . "\n" .
-'<option value=1>Talk</option>' . "\n" .
-'<option value=2>User</option>' . "\n" .
-'<option value=3>User talk</option>' . "\n" .
-'<option value=4>MyWiki</option>' . "\n" .
-'<option value=5>MyWiki Talk</option>' . "\n" .
-'<option value=6>File</option>' . "\n" .
-'<option value=7>File talk</option>' . "\n" .
-'<option value=8>MediaWiki</option>' . "\n" .
-'<option value=9>MediaWiki talk</option>' . "\n" .
-'<option value=10>Template</option>' . "\n" .
-'<option value=11>Template talk</option>' . "\n" .
-'<option value=14>Category</option>' . "\n" .
-'<option value=15>Category talk</option>' . "\n" .
-'<option value=100>Custom</option>' . "\n" .
-'<option value=101>Custom talk</option>' . "\n" .
-'</select>',
+                               '<option value=0>(Main)</option>' . "\n" .
+                               '<option value=1>Talk</option>' . "\n" .
+                               '<option value=2>User</option>' . "\n" .
+                               '<option value=3>User talk</option>' . "\n" .
+                               '<option value=4>MyWiki</option>' . "\n" .
+                               '<option value=5>MyWiki Talk</option>' . "\n" .
+                               '<option value=6>File</option>' . "\n" .
+                               '<option value=7>File talk</option>' . "\n" .
+                               '<option value=8>MediaWiki</option>' . "\n" .
+                               '<option value=9>MediaWiki talk</option>' . "\n" .
+                               '<option value=10>Template</option>' . "\n" .
+                               '<option value=11>Template talk</option>' . "\n" .
+                               '<option value=14>Category</option>' . "\n" .
+                               '<option value=15>Category talk</option>' . "\n" .
+                               '<option value=100>Custom</option>' . "\n" .
+                               '<option value=101>Custom talk</option>' . "\n" .
+                               '</select>',
                        Html::namespaceSelector(),
                        'Basic namespace selector without custom options'
                );
 
                $this->assertEquals(
                        '<label for=mw-test-namespace>Select a namespace:</label>&#160;' .
-'<select id=mw-test-namespace name=wpNamespace>' . "\n" .
-'<option value=all>all</option>' . "\n" .
-'<option value=0>(Main)</option>' . "\n" .
-'<option value=1>Talk</option>' . "\n" .
-'<option value=2 selected>User</option>' . "\n" .
-'<option value=3>User talk</option>' . "\n" .
-'<option value=4>MyWiki</option>' . "\n" .
-'<option value=5>MyWiki Talk</option>' . "\n" .
-'<option value=6>File</option>' . "\n" .
-'<option value=7>File talk</option>' . "\n" .
-'<option value=8>MediaWiki</option>' . "\n" .
-'<option value=9>MediaWiki talk</option>' . "\n" .
-'<option value=10>Template</option>' . "\n" .
-'<option value=11>Template talk</option>' . "\n" .
-'<option value=14>Category</option>' . "\n" .
-'<option value=15>Category talk</option>' . "\n" .
-'<option value=100>Custom</option>' . "\n" .
-'<option value=101>Custom talk</option>' . "\n" .
-'</select>',
+                               '<select id=mw-test-namespace name=wpNamespace>' . "\n" .
+                               '<option value=all>all</option>' . "\n" .
+                               '<option value=0>(Main)</option>' . "\n" .
+                               '<option value=1>Talk</option>' . "\n" .
+                               '<option value=2 selected>User</option>' . "\n" .
+                               '<option value=3>User talk</option>' . "\n" .
+                               '<option value=4>MyWiki</option>' . "\n" .
+                               '<option value=5>MyWiki Talk</option>' . "\n" .
+                               '<option value=6>File</option>' . "\n" .
+                               '<option value=7>File talk</option>' . "\n" .
+                               '<option value=8>MediaWiki</option>' . "\n" .
+                               '<option value=9>MediaWiki talk</option>' . "\n" .
+                               '<option value=10>Template</option>' . "\n" .
+                               '<option value=11>Template talk</option>' . "\n" .
+                               '<option value=14>Category</option>' . "\n" .
+                               '<option value=15>Category talk</option>' . "\n" .
+                               '<option value=100>Custom</option>' . "\n" .
+                               '<option value=101>Custom talk</option>' . "\n" .
+                               '</select>',
                        Html::namespaceSelector(
                                array( 'selected' => '2', 'all' => 'all', 'label' => 'Select a namespace:' ),
                                array( 'name' => 'wpNamespace', 'id' => 'mw-test-namespace' )
@@ -329,24 +329,24 @@ class HtmlTest extends MediaWikiTestCase {
 
                $this->assertEquals(
                        '<label for=namespace>Select a namespace:</label>&#160;' .
-'<select id=namespace name=namespace>' . "\n" .
-'<option value=0>(Main)</option>' . "\n" .
-'<option value=1>Talk</option>' . "\n" .
-'<option value=2>User</option>' . "\n" .
-'<option value=3>User talk</option>' . "\n" .
-'<option value=4>MyWiki</option>' . "\n" .
-'<option value=5>MyWiki Talk</option>' . "\n" .
-'<option value=6>File</option>' . "\n" .
-'<option value=7>File talk</option>' . "\n" .
-'<option value=8>MediaWiki</option>' . "\n" .
-'<option value=9>MediaWiki talk</option>' . "\n" .
-'<option value=10>Template</option>' . "\n" .
-'<option value=11>Template talk</option>' . "\n" .
-'<option value=14>Category</option>' . "\n" .
-'<option value=15>Category talk</option>' . "\n" .
-'<option value=100>Custom</option>' . "\n" .
-'<option value=101>Custom talk</option>' . "\n" .
-'</select>',
+                               '<select id=namespace name=namespace>' . "\n" .
+                               '<option value=0>(Main)</option>' . "\n" .
+                               '<option value=1>Talk</option>' . "\n" .
+                               '<option value=2>User</option>' . "\n" .
+                               '<option value=3>User talk</option>' . "\n" .
+                               '<option value=4>MyWiki</option>' . "\n" .
+                               '<option value=5>MyWiki Talk</option>' . "\n" .
+                               '<option value=6>File</option>' . "\n" .
+                               '<option value=7>File talk</option>' . "\n" .
+                               '<option value=8>MediaWiki</option>' . "\n" .
+                               '<option value=9>MediaWiki talk</option>' . "\n" .
+                               '<option value=10>Template</option>' . "\n" .
+                               '<option value=11>Template talk</option>' . "\n" .
+                               '<option value=14>Category</option>' . "\n" .
+                               '<option value=15>Category talk</option>' . "\n" .
+                               '<option value=100>Custom</option>' . "\n" .
+                               '<option value=101>Custom talk</option>' . "\n" .
+                               '</select>',
                        Html::namespaceSelector(
                                array( 'label' => 'Select a namespace:' )
                        ),
@@ -356,19 +356,19 @@ class HtmlTest extends MediaWikiTestCase {
 
        function testCanFilterOutNamespaces() {
                $this->assertEquals(
-'<select id=namespace name=namespace>' . "\n" .
-'<option value=2>User</option>' . "\n" .
-'<option value=4>MyWiki</option>' . "\n" .
-'<option value=5>MyWiki Talk</option>' . "\n" .
-'<option value=6>File</option>' . "\n" .
-'<option value=7>File talk</option>' . "\n" .
-'<option value=8>MediaWiki</option>' . "\n" .
-'<option value=9>MediaWiki talk</option>' . "\n" .
-'<option value=10>Template</option>' . "\n" .
-'<option value=11>Template talk</option>' . "\n" .
-'<option value=14>Category</option>' . "\n" .
-'<option value=15>Category talk</option>' . "\n" .
-'</select>',
+                       '<select id=namespace name=namespace>' . "\n" .
+                               '<option value=2>User</option>' . "\n" .
+                               '<option value=4>MyWiki</option>' . "\n" .
+                               '<option value=5>MyWiki Talk</option>' . "\n" .
+                               '<option value=6>File</option>' . "\n" .
+                               '<option value=7>File talk</option>' . "\n" .
+                               '<option value=8>MediaWiki</option>' . "\n" .
+                               '<option value=9>MediaWiki talk</option>' . "\n" .
+                               '<option value=10>Template</option>' . "\n" .
+                               '<option value=11>Template talk</option>' . "\n" .
+                               '<option value=14>Category</option>' . "\n" .
+                               '<option value=15>Category talk</option>' . "\n" .
+                               '</select>',
                        Html::namespaceSelector(
                                array( 'exclude' => array( 0, 1, 3, 100, 101 ) )
                        ),
@@ -378,24 +378,24 @@ class HtmlTest extends MediaWikiTestCase {
 
        function testCanDisableANamespaces() {
                $this->assertEquals(
-'<select id=namespace name=namespace>' . "\n" .
-'<option disabled value=0>(Main)</option>' . "\n" .
-'<option disabled value=1>Talk</option>' . "\n" .
-'<option disabled value=2>User</option>' . "\n" .
-'<option disabled value=3>User talk</option>' . "\n" .
-'<option disabled value=4>MyWiki</option>' . "\n" .
-'<option value=5>MyWiki Talk</option>' . "\n" .
-'<option value=6>File</option>' . "\n" .
-'<option value=7>File talk</option>' . "\n" .
-'<option value=8>MediaWiki</option>' . "\n" .
-'<option value=9>MediaWiki talk</option>' . "\n" .
-'<option value=10>Template</option>' . "\n" .
-'<option value=11>Template talk</option>' . "\n" .
-'<option value=14>Category</option>' . "\n" .
-'<option value=15>Category talk</option>' . "\n" .
-'<option value=100>Custom</option>' . "\n" .
-'<option value=101>Custom talk</option>' . "\n" .
-'</select>',
+                       '<select id=namespace name=namespace>' . "\n" .
+                               '<option disabled value=0>(Main)</option>' . "\n" .
+                               '<option disabled value=1>Talk</option>' . "\n" .
+                               '<option disabled value=2>User</option>' . "\n" .
+                               '<option disabled value=3>User talk</option>' . "\n" .
+                               '<option disabled value=4>MyWiki</option>' . "\n" .
+                               '<option value=5>MyWiki Talk</option>' . "\n" .
+                               '<option value=6>File</option>' . "\n" .
+                               '<option value=7>File talk</option>' . "\n" .
+                               '<option value=8>MediaWiki</option>' . "\n" .
+                               '<option value=9>MediaWiki talk</option>' . "\n" .
+                               '<option value=10>Template</option>' . "\n" .
+                               '<option value=11>Template talk</option>' . "\n" .
+                               '<option value=14>Category</option>' . "\n" .
+                               '<option value=15>Category talk</option>' . "\n" .
+                               '<option value=100>Custom</option>' . "\n" .
+                               '<option value=101>Custom talk</option>' . "\n" .
+                               '</select>',
                        Html::namespaceSelector( array(
                                'disable' => array( 0, 1, 2, 3, 4 )
                        ) ),
@@ -435,7 +435,7 @@ class HtmlTest extends MediaWikiTestCase {
                        'color',
                );
                $cases = array();
-               foreach( $types as $type ) {
+               foreach ( $types as $type ) {
                        $cases[] = array( $type );
                }
                return $cases;
@@ -595,7 +595,7 @@ class HtmlTest extends MediaWikiTestCase {
 
                # Craft the Html elements
                $ret = array();
-               foreach( $cases as $case ) {
+               foreach ( $cases as $case ) {
                        $ret[] = array(
                                $case[0],
                                $case[1], $case[2],
index 92a1c9c..7698776 100644 (file)
@@ -19,10 +19,10 @@ class HttpTest extends MediaWikiTestCase {
 
        public static function cookieDomains() {
                return array(
-                       array( false, "org"),
-                       array( false, ".org"),
-                       array( true, "wikipedia.org"),
-                       array( true, ".wikipedia.org"),
+                       array( false, "org" ),
+                       array( false, ".org" ),
+                       array( true, "wikipedia.org" ),
+                       array( true, ".wikipedia.org" ),
                        array( false, "co.uk" ),
                        array( false, ".co.uk" ),
                        array( false, "gov.uk" ),
@@ -68,26 +68,26 @@ class HttpTest extends MediaWikiTestCase {
                        array( false, '¿non sens before!! http://a', 'Allow anything before URI' ),
 
                        # (http|https) - only two schemes allowed
-                       array( true,  'http://www.example.org/' ),
-                       array( true,  'https://www.example.org/' ),
-                       array( true,  'http://www.example.org', 'URI without directory' ),
-                       array( true,  'http://a', 'Short name' ),
-                       array( true, 'http://étoile', 'Allow UTF-8 in hostname' ),  # 'étoile' is french for 'star'
+                       array( true, 'http://www.example.org/' ),
+                       array( true, 'https://www.example.org/' ),
+                       array( true, 'http://www.example.org', 'URI without directory' ),
+                       array( true, 'http://a', 'Short name' ),
+                       array( true, 'http://étoile', 'Allow UTF-8 in hostname' ), # 'étoile' is french for 'star'
                        array( false, '\\host\directory', 'CIFS share' ),
                        array( false, 'gopher://host/dir', 'Reject gopher scheme' ),
                        array( false, 'telnet://host', 'Reject telnet scheme' ),
 
                        # :\/\/ - double slashes
-                       array( false,  'http//example.org', 'Reject missing colon in protocol' ),
-                       array( false,  'http:/example.org', 'Reject missing slash in protocol' ),
-                       array( false,  'http:example.org', 'Must have two slashes' ),
+                       array( false, 'http//example.org', 'Reject missing colon in protocol' ),
+                       array( false, 'http:/example.org', 'Reject missing slash in protocol' ),
+                       array( false, 'http:example.org', 'Must have two slashes' ),
                        # Following fail since hostname can be made of anything
-                       array( false,  'http:///example.org', 'Must have exactly two slashes, not three' ),
+                       array( false, 'http:///example.org', 'Must have exactly two slashes, not three' ),
 
                        # (\w+:{0,1}\w*@)? - optional user:pass
-                       array( true,  'http://user@host', 'Username provided' ),
-                       array( true,  'http://user:@host', 'Username provided, no password' ),
-                       array( true,  'http://user:pass@host', 'Username and password provided' ),
+                       array( true, 'http://user@host', 'Username provided' ),
+                       array( true, 'http://user:@host', 'Username provided, no password' ),
+                       array( true, 'http://user:pass@host', 'Username and password provided' ),
 
                        # (\S+) - host part is made of anything not whitespaces
                        array( false, 'http://!"èèè¿¿¿~~\'', 'hostname is made of any non whitespace' ),
@@ -115,7 +115,7 @@ class HttpTest extends MediaWikiTestCase {
                        array( true, 'http://example/&' ),
 
                        # Fragment
-                       array( true, 'http://exam#ple.org', ),  # This one is valid, really!
+                       array( true, 'http://exam#ple.org', ), # This one is valid, really!
                        array( true, 'http://example.org:80#anchor' ),
                        array( true, 'http://example.org/?id#anchor' ),
                        array( true, 'http://example.org/?#anchor' ),
@@ -126,7 +126,7 @@ class HttpTest extends MediaWikiTestCase {
 
        /**
         * Warning:
-        * 
+        *
         * These tests are for code that makes use of an artifact of how CURL
         * handles header reporting on redirect pages, and will need to be
         * rewritten when bug 29232 is taken care of (high-level handling of
@@ -137,8 +137,8 @@ class HttpTest extends MediaWikiTestCase {
 
                # Forge a Location header
                $h->setRespHeaders( 'location', array(
-                       'http://newsite/file.ext',
-                       '/newfile.ext',
+                               'http://newsite/file.ext',
+                               '/newfile.ext',
                        )
                );
                # Verify we correctly fix the Location
@@ -149,7 +149,7 @@ class HttpTest extends MediaWikiTestCase {
                );
 
                $h->setRespHeaders( 'location', array(
-                       'https://oldsite/file.ext'
+                               'https://oldsite/file.ext'
                        )
                );
                $this->assertEquals(
@@ -159,14 +159,14 @@ class HttpTest extends MediaWikiTestCase {
                );
 
                $h->setRespHeaders( 'location', array(
-                       '/anotherfile.ext',
-                       'http://anotherfile/hoster.ext',
-                       'https://anotherfile/hoster.ext'
+                               '/anotherfile.ext',
+                               'http://anotherfile/hoster.ext',
+                               'https://anotherfile/hoster.ext'
                        )
                );
                $this->assertEquals(
                        'https://anotherfile/hoster.ext',
-                       $h->getFinalUrl( "Relative file path Location: should keep the latest host and scheme!")
+                       $h->getFinalUrl( "Relative file path Location: should keep the latest host and scheme!" )
                );
        }
 }
@@ -183,10 +183,10 @@ class MWHttpRequestTester extends 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 ) {
+               switch ( Http::$httpEngine ) {
                        case 'curl':
                                return new CurlHttpRequestTester( $url, $options );
                        case 'php':
index 5284812..7bc2938 100644 (file)
@@ -11,13 +11,13 @@ class IPTest extends MediaWikiTestCase {
         */
        public function testisIPAddress() {
                $this->assertFalse( IP::isIPAddress( false ), 'Boolean false is not an IP' );
-               $this->assertFalse( IP::isIPAddress( true  ), 'Boolean true is not an IP' );
+               $this->assertFalse( IP::isIPAddress( true ), 'Boolean true is not an IP' );
                $this->assertFalse( IP::isIPAddress( "" ), 'Empty string is not an IP' );
                $this->assertFalse( IP::isIPAddress( 'abc' ), 'Garbage IP string' );
                $this->assertFalse( IP::isIPAddress( ':' ), 'Single ":" is not an IP' );
-               $this->assertFalse( IP::isIPAddress( '2001:0DB8::A:1::1'), 'IPv6 with a double :: occurrence' );
-               $this->assertFalse( IP::isIPAddress( '2001:0DB8::A:1::'), 'IPv6 with a double :: occurrence, last at end' );
-               $this->assertFalse( IP::isIPAddress( '::2001:0DB8::5:1'), 'IPv6 with a double :: occurrence, firt at beginning' );
+               $this->assertFalse( IP::isIPAddress( '2001:0DB8::A:1::1' ), 'IPv6 with a double :: occurrence' );
+               $this->assertFalse( IP::isIPAddress( '2001:0DB8::A:1::' ), 'IPv6 with a double :: occurrence, last at end' );
+               $this->assertFalse( IP::isIPAddress( '::2001:0DB8::5:1' ), 'IPv6 with a double :: occurrence, firt at beginning' );
                $this->assertFalse( IP::isIPAddress( '124.24.52' ), 'IPv4 not enough quads' );
                $this->assertFalse( IP::isIPAddress( '24.324.52.13' ), 'IPv4 out of range' );
                $this->assertFalse( IP::isIPAddress( '.24.52.13' ), 'IPv4 starts with period' );
@@ -81,9 +81,9 @@ class IPTest extends MediaWikiTestCase {
                $this->assertTrue( IP::isIPv6( 'fc::100:a:d:1' ), 'IPv6 with "::" and 5 words' );
                $this->assertTrue( IP::isIPv6( 'fc::100:a:d:1:e' ), 'IPv6 with "::" and 6 words' );
                $this->assertTrue( IP::isIPv6( 'fc::100:a:d:1:e:ac' ), 'IPv6 with "::" and 7 words' );
-               $this->assertTrue( IP::isIPv6( '2001::df'), 'IPv6 with "::" and 2 words' );
-               $this->assertTrue( IP::isIPv6( '2001:5c0:1400:a::df'), 'IPv6 with "::" and 5 words' );
-               $this->assertTrue( IP::isIPv6( '2001:5c0:1400:a::df:2'), 'IPv6 with "::" and 6 words' );
+               $this->assertTrue( IP::isIPv6( '2001::df' ), 'IPv6 with "::" and 2 words' );
+               $this->assertTrue( IP::isIPv6( '2001:5c0:1400:a::df' ), 'IPv6 with "::" and 5 words' );
+               $this->assertTrue( IP::isIPv6( '2001:5c0:1400:a::df:2' ), 'IPv6 with "::" and 6 words' );
 
                $this->assertFalse( IP::isIPv6( 'fc::100:a:d:1:e:ac:0' ), 'IPv6 with "::" and 8 words' );
                $this->assertFalse( IP::isIPv6( 'fc::100:a:d:1:e:ac:0:1' ), 'IPv6 with 9 words' );
@@ -96,7 +96,7 @@ class IPTest extends MediaWikiTestCase {
         */
        public function testisIPv4() {
                $this->assertFalse( IP::isIPv4( false ), 'Boolean false is not an IP' );
-               $this->assertFalse( IP::isIPv4( true  ), 'Boolean true is not an IP' );
+               $this->assertFalse( IP::isIPv4( true ), 'Boolean true is not an IP' );
                $this->assertFalse( IP::isIPv4( "" ), 'Empty string is not an IP' );
                $this->assertFalse( IP::isIPv4( 'abc' ) );
                $this->assertFalse( IP::isIPv4( ':' ) );
@@ -143,9 +143,9 @@ class IPTest extends MediaWikiTestCase {
 
                $this->assertTrue( IP::isValid( 'fc::100' ), 'IPv6 with "::" and 2 words' );
                $this->assertTrue( IP::isValid( 'fc::100:a' ), 'IPv6 with "::" and 3 words' );
-               $this->assertTrue( IP::isValid( '2001::df'), 'IPv6 with "::" and 2 words' );
-               $this->assertTrue( IP::isValid( '2001:5c0:1400:a::df'), 'IPv6 with "::" and 5 words' );
-               $this->assertTrue( IP::isValid( '2001:5c0:1400:a::df:2'), 'IPv6 with "::" and 6 words' );
+               $this->assertTrue( IP::isValid( '2001::df' ), 'IPv6 with "::" and 2 words' );
+               $this->assertTrue( IP::isValid( '2001:5c0:1400:a::df' ), 'IPv6 with "::" and 5 words' );
+               $this->assertTrue( IP::isValid( '2001:5c0:1400:a::df:2' ), 'IPv6 with "::" and 6 words' );
                $this->assertTrue( IP::isValid( 'fc::100:a:d:1' ), 'IPv6 with "::" and 5 words' );
                $this->assertTrue( IP::isValid( 'fc::100:a:d:1:e:ac' ), 'IPv6 with "::" and 7 words' );
 
@@ -254,8 +254,8 @@ class IPTest extends MediaWikiTestCase {
         * @todo Most probably incomplete
         */
        public function testSanitizeIP() {
-               $this->assertNull( IP::sanitizeIP('')  );
-               $this->assertNull( IP::sanitizeIP(' ') );
+               $this->assertNull( IP::sanitizeIP( '' ) );
+               $this->assertNull( IP::sanitizeIP( ' ' ) );
        }
 
        /**
@@ -264,7 +264,7 @@ class IPTest extends MediaWikiTestCase {
         */
        public function testip2longWrapper() {
                // @todo FIXME: Add more tests ?
-               $this->assertEquals( pow(2,32) - 1, IP::toUnsigned( '255.255.255.255' ) );
+               $this->assertEquals( pow( 2, 32 ) - 1, IP::toUnsigned( '255.255.255.255' ) );
                $i = 'IN.VA.LI.D';
                $this->assertFalse( IP::toUnSigned( $i ) );
        }
@@ -284,7 +284,7 @@ class IPTest extends MediaWikiTestCase {
        }
 
        // Private wrapper used to test CIDR Parsing.
-       private function assertFalseCIDR( $CIDR, $msg='' ) {
+       private function assertFalseCIDR( $CIDR, $msg = '' ) {
                $ff = array( false, false );
                $this->assertEquals( $ff, IP::parseCIDR( $CIDR ), $msg );
        }
@@ -299,15 +299,15 @@ class IPTest extends MediaWikiTestCase {
         * @covers IP::hexToQuad
         */
        public function testHexToQuad() {
-               $this->assertEquals( '0.0.0.1'        , IP::hexToQuad( '00000001' ) );
-               $this->assertEquals( '255.0.0.0'      , IP::hexToQuad( 'FF000000' ) );
+               $this->assertEquals( '0.0.0.1', IP::hexToQuad( '00000001' ) );
+               $this->assertEquals( '255.0.0.0', IP::hexToQuad( 'FF000000' ) );
                $this->assertEquals( '255.255.255.255', IP::hexToQuad( 'FFFFFFFF' ) );
-               $this->assertEquals( '10.188.222.255' , IP::hexToQuad( '0ABCDEFF' ) );
+               $this->assertEquals( '10.188.222.255', IP::hexToQuad( '0ABCDEFF' ) );
                // hex not left-padded...
-               $this->assertEquals( '0.0.0.0'     , IP::hexToQuad( '0' ) );
-               $this->assertEquals( '0.0.0.1'     , IP::hexToQuad( '1' ) );
-               $this->assertEquals( '0.0.0.255'   , IP::hexToQuad( 'FF' ) );
-               $this->assertEquals( '0.0.255.0'   , IP::hexToQuad( 'FF00' ) );
+               $this->assertEquals( '0.0.0.0', IP::hexToQuad( '0' ) );
+               $this->assertEquals( '0.0.0.1', IP::hexToQuad( '1' ) );
+               $this->assertEquals( '0.0.0.255', IP::hexToQuad( 'FF' ) );
+               $this->assertEquals( '0.0.255.0', IP::hexToQuad( 'FF00' ) );
        }
 
        /**
@@ -325,11 +325,11 @@ class IPTest extends MediaWikiTestCase {
                $this->assertEquals( 'FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF',
                        IP::hexToOctet( 'FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF' ) );
                // hex not left-padded...
-               $this->assertEquals( '0:0:0:0:0:0:0:0'          , IP::hexToOctet( '0' ) );
-               $this->assertEquals( '0:0:0:0:0:0:0:1'          , IP::hexToOctet( '1' ) );
-               $this->assertEquals( '0:0:0:0:0:0:0:FF'         , IP::hexToOctet( 'FF' ) );
-               $this->assertEquals( '0:0:0:0:0:0:0:FFD0'       , IP::hexToOctet( 'FFD0' ) );
-               $this->assertEquals( '0:0:0:0:0:0:FA00:0'       , IP::hexToOctet( 'FA000000' ) );
+               $this->assertEquals( '0:0:0:0:0:0:0:0', IP::hexToOctet( '0' ) );
+               $this->assertEquals( '0:0:0:0:0:0:0:1', IP::hexToOctet( '1' ) );
+               $this->assertEquals( '0:0:0:0:0:0:0:FF', IP::hexToOctet( 'FF' ) );
+               $this->assertEquals( '0:0:0:0:0:0:0:FFD0', IP::hexToOctet( 'FFD0' ) );
+               $this->assertEquals( '0:0:0:0:0:0:FA00:0', IP::hexToOctet( 'FA000000' ) );
                $this->assertEquals( '0:0:0:0:0:0:FCCF:FAFF', IP::hexToOctet( 'FCCFFAFF' ) );
        }
 
@@ -339,42 +339,41 @@ class IPTest extends MediaWikiTestCase {
         * @covers IP::parseCIDR
         */
        function testCIDRParsing() {
-               $this->assertFalseCIDR( '192.0.2.0' , "missing mask"    );
+               $this->assertFalseCIDR( '192.0.2.0', "missing mask" );
                $this->assertFalseCIDR( '192.0.2.0/', "missing bitmask" );
 
                // Verify if statement
-               $this->assertFalseCIDR( '256.0.0.0/32', "invalid net"      );
+               $this->assertFalseCIDR( '256.0.0.0/32', "invalid net" );
                $this->assertFalseCIDR( '192.0.2.0/AA', "mask not numeric" );
-               $this->assertFalseCIDR( '192.0.2.0/-1', "mask < 0"         );
-               $this->assertFalseCIDR( '192.0.2.0/33', "mask > 32"        );
+               $this->assertFalseCIDR( '192.0.2.0/-1', "mask < 0" );
+               $this->assertFalseCIDR( '192.0.2.0/33', "mask > 32" );
 
                // Check internal logic
                # 0 mask always result in array(0,0)
-               $this->assertEquals( array( 0, 0 ), IP::parseCIDR('192.0.0.2/0') );
-               $this->assertEquals( array( 0, 0 ), IP::parseCIDR('0.0.0.0/0') );
-               $this->assertEquals( array( 0, 0 ), IP::parseCIDR('255.255.255.255/0') );
+               $this->assertEquals( array( 0, 0 ), IP::parseCIDR( '192.0.0.2/0' ) );
+               $this->assertEquals( array( 0, 0 ), IP::parseCIDR( '0.0.0.0/0' ) );
+               $this->assertEquals( array( 0, 0 ), IP::parseCIDR( '255.255.255.255/0' ) );
 
                // @todo FIXME: Add more tests.
 
                # This part test network shifting
-               $this->assertNet( '192.0.0.0'  , '192.0.0.2/24'   );
-               $this->assertNet( '192.168.5.0', '192.168.5.13/24');
-               $this->assertNet( '10.0.0.160' , '10.0.0.161/28'  );
-               $this->assertNet( '10.0.0.0'   , '10.0.0.3/28'  );
-               $this->assertNet( '10.0.0.0'   , '10.0.0.3/30'  );
-               $this->assertNet( '10.0.0.4'   , '10.0.0.4/30'  );
+               $this->assertNet( '192.0.0.0', '192.0.0.2/24' );
+               $this->assertNet( '192.168.5.0', '192.168.5.13/24' );
+               $this->assertNet( '10.0.0.160', '10.0.0.161/28' );
+               $this->assertNet( '10.0.0.0', '10.0.0.3/28' );
+               $this->assertNet( '10.0.0.0', '10.0.0.3/30' );
+               $this->assertNet( '10.0.0.4', '10.0.0.4/30' );
                $this->assertNet( '172.17.32.0', '172.17.35.48/21' );
-               $this->assertNet( '10.128.0.0' , '10.135.0.0/9' );
-               $this->assertNet( '134.0.0.0'  , '134.0.5.1/8'  );
+               $this->assertNet( '10.128.0.0', '10.135.0.0/9' );
+               $this->assertNet( '134.0.0.0', '134.0.5.1/8' );
        }
 
-
        /**
         * @covers IP::canonicalize
         */
        public function testIPCanonicalizeOnValidIp() {
                $this->assertEquals( '192.0.2.152', IP::canonicalize( '192.0.2.152' ),
-               'Canonicalization of a valid IP returns it unchanged' );
+                       'Canonicalization of a valid IP returns it unchanged' );
        }
 
        /**
@@ -406,26 +405,26 @@ class IPTest extends MediaWikiTestCase {
 
        /** Provider for testIPIsInRange() */
        public static function provideIPsAndRanges() {
-                       # Format: (expected boolean, address, range, optional message)
+               # Format: (expected boolean, address, range, optional message)
                return array(
                        # IPv4
-                       array( true , '192.0.2.0'   , '192.0.2.0/24', 'Network address' ),
-                       array( true , '192.0.2.77'  , '192.0.2.0/24', 'Simple address' ),
-                       array( true , '192.0.2.255' , '192.0.2.0/24', 'Broadcast address' ),
+                       array( true, '192.0.2.0', '192.0.2.0/24', 'Network address' ),
+                       array( true, '192.0.2.77', '192.0.2.0/24', 'Simple address' ),
+                       array( true, '192.0.2.255', '192.0.2.0/24', 'Broadcast address' ),
 
-                       array( false, '0.0.0.0'     , '192.0.2.0/24' ),
-                       array( false, '255.255.255' , '192.0.2.0/24' ),
+                       array( false, '0.0.0.0', '192.0.2.0/24' ),
+                       array( false, '255.255.255', '192.0.2.0/24' ),
 
                        # IPv6
-                       array( false, '::1'    , '2001:DB8::/32' ),
-                       array( false, '::'     , '2001:DB8::/32' ),
+                       array( false, '::1', '2001:DB8::/32' ),
+                       array( false, '::', '2001:DB8::/32' ),
                        array( false, 'FE80::1', '2001:DB8::/32' ),
 
-                       array( true , '2001:DB8::'  , '2001:DB8::/32' ),
-                       array( true , '2001:0DB8::' , '2001:DB8::/32' ),
-                       array( true , '2001:DB8::1' , '2001:DB8::/32' ),
-                       array( true , '2001:0DB8::1', '2001:DB8::/32' ),
-                       array( true , '2001:0DB8:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF',
+                       array( true, '2001:DB8::', '2001:DB8::/32' ),
+                       array( true, '2001:0DB8::', '2001:DB8::/32' ),
+                       array( true, '2001:DB8::1', '2001:DB8::/32' ),
+                       array( true, '2001:0DB8::1', '2001:DB8::/32' ),
+                       array( true, '2001:0DB8:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF',
                                '2001:DB8::/32' ),
 
                        array( false, '2001:0DB8:F::', '2001:DB8::/96' ),
index 9b508f7..96a2ead 100644 (file)
@@ -1,25 +1,25 @@
 <?php
 
 class JsonTest extends MediaWikiTestCase {
-       
+
        function testPhpBug46944Test() {
-               $this->assertNotEquals( 
-                       '\ud840\udc00',                 
+               $this->assertNotEquals(
+                       '\ud840\udc00',
                        strtolower( FormatJson::encode( "\xf0\xa0\x80\x80" ) ),
                        'Test encoding an broken json_encode character (U+20000)'
                );
 
        }
-       
+
        function testDecodeVarTypes() {
-               $this->assertInternalType( 
-                       'object',                       
+               $this->assertInternalType(
+                       'object',
                        FormatJson::decode( '{"Name": "Cheeso", "Rank": 7}' ),
                        'Default to object'
                );
 
-               $this->assertInternalType( 
-                       'array',                        
+               $this->assertInternalType(
+                       'array',
                        FormatJson::decode( '{"Name": "Cheeso", "Rank": 7}', true ),
                        'Optional array'
                );
index eb8912d..d4d93b0 100644 (file)
@@ -84,8 +84,8 @@ class LanguageConverterTest extends MediaWikiLangTestCase {
                $wgUser->setId( 1 );
                $wgUser->mFrom = 'defaults';
                $wgUser->mOptionsLoaded = true;
-               $wgUser->setOption( 'variant', 'tg-latn' ); // The user's data is ignored
-                                                                                                 // because the variant is set in the URL.
+               // The user's data is ignored because the variant is set in the URL.
+               $wgUser->setOption( 'variant', 'tg-latn' ); 
                $this->assertEquals( 'tg', $this->lc->getPreferredVariant() );
        }
 
@@ -120,7 +120,7 @@ class TestConverter extends LanguageConverter {
        function loadDefaultTables() {
                $this->mTables = array(
                        'tg-latn' => new ReplacementArray( $this->table ),
-                       'tg'      => new ReplacementArray()
+                       'tg' => new ReplacementArray()
                );
        }
 
index e467f3c..212b3b3 100644 (file)
@@ -14,8 +14,8 @@ class LicensesTest extends MediaWikiTestCase {
                        'section' => 'description',
                        'id' => 'wpLicense',
                        'label' => 'A label text', # Note can't test label-message because $wgOut is not defined
-                       'name' => 'AnotherName', 
-                       'licenses' => $str,             
+                       'name' => 'AnotherName',
+                       'licenses' => $str,
                ) );
                $this->assertThat( $lc, $this->isInstanceOf( 'Licenses' ) );
        }
index abb8374..90de96d 100644 (file)
@@ -6,11 +6,11 @@ class LinkerTest extends MediaWikiLangTestCase {
         * @dataProvider provideCasesForUserLink
         * @cover Linker::userLink
         */
-       function testUserLink( $expected, $userId, $userName, $altUserName = false, $msg='' ) {
+       function testUserLink( $expected, $userId, $userName, $altUserName = false, $msg = '' ) {
                $this->setMwGlobals( array(
                        'wgArticlePath' => '/wiki/$1',
                        'wgWellFormedXml' => true,
-               ) );
+               ) );
 
                $this->assertEquals( $expected,
                        Linker::userLink( $userId, $userName, $altUserName, $msg )
index 7b64a33..d6f0d2e 100644 (file)
@@ -13,13 +13,13 @@ class LocalFileTest extends MediaWikiTestCase {
                $this->setMwGlobals( 'wgCapitalLinks', true );
 
                $info = array(
-                       'name'            => 'test',
-                       'directory'       => '/testdir',
-                       'url'             => '/testurl',
-                       'hashLevels'      => 2,
+                       'name' => 'test',
+                       'directory' => '/testdir',
+                       'url' => '/testurl',
+                       'hashLevels' => 2,
                        'transformVia404' => false,
-                       'backend'         => new FSFileBackend( array(
-                               'name'        => 'local-backend',
+                       'backend' => new FSFileBackend( array(
+                               'name' => 'local-backend',
                                'lockManager' => 'fsLockManager',
                                'containerPaths' => array(
                                        'cont1' => "/testdir/local-backend/tempimages/cont1",
index f7be59f..6c17bf4 100644 (file)
@@ -1,27 +1,26 @@
 <?php
 
 class MWFunctionTest extends MediaWikiTestCase {
-       
        function testCallUserFuncWorkarounds() {
-               $this->assertEquals( 
+               $this->assertEquals(
                        call_user_func( array( 'MWFunctionTest', 'someMethod' ) ),
                        MWFunction::call( 'MWFunctionTest::someMethod' )
                );
-               $this->assertEquals( 
+               $this->assertEquals(
                        call_user_func( array( 'MWFunctionTest', 'someMethod' ), 'foo', 'bar', 'baz' ),
                        MWFunction::call( 'MWFunctionTest::someMethod', 'foo', 'bar', 'baz' )
                );
 
-               $this->assertEquals( 
+               $this->assertEquals(
                        call_user_func_array( array( 'MWFunctionTest', 'someMethod' ), array() ),
                        MWFunction::callArray( 'MWFunctionTest::someMethod', array() )
                );
-               $this->assertEquals( 
+               $this->assertEquals(
                        call_user_func_array( array( 'MWFunctionTest', 'someMethod' ), array( 'foo', 'bar', 'baz' ) ),
                        MWFunction::callArray( 'MWFunctionTest::someMethod', array( 'foo', 'bar', 'baz' ) )
                );
        }
-       
+
        function testNewObjFunction() {
                $arg1 = 'Foo';
                $arg2 = 'Bar';
@@ -31,36 +30,36 @@ class MWFunctionTest extends MediaWikiTestCase {
                $args = array( $arg1, $arg2, $arg3, $arg4 );
 
                $newObject = new MWBlankClass( $arg1, $arg2, $arg3, $arg4 );
-               $this->assertEquals( 
-                       MWFunction::newObj( 'MWBlankClass', $args )->args, 
+               $this->assertEquals(
+                       MWFunction::newObj( 'MWBlankClass', $args )->args,
                        $newObject->args
                );
 
-               $this->assertEquals( 
-                       MWFunction::newObj( 'MWBlankClass', $args, true )->args, 
+               $this->assertEquals(
+                       MWFunction::newObj( 'MWBlankClass', $args, true )->args,
                        $newObject->args,
                        'Works even with PHP version < 5.1.3'
                );
        }
-       
+
        /**
         * @expectedException MWException
         */
        function testCallingParentFails() {
                MWFunction::call( 'parent::foo' );
        }
-       
+
        /**
         * @expectedException MWException
         */
        function testCallingSelfFails() {
                MWFunction::call( 'self::foo' );
        }
-       
+
        public static function someMethod() {
                return func_get_args();
        }
-       
+
 }
 
 class MWBlankClass {
index d0b3814..45f8daf 100644 (file)
@@ -17,9 +17,9 @@ class MWNamespaceTest extends MediaWikiTestCase {
                $this->setMwGlobals( array(
                        'wgContentNamespaces' => array( NS_MAIN ),
                        'wgNamespacesWithSubpages' => array(
-                               NS_TALK           => true,
-                               NS_USER           => true,
-                               NS_USER_TALK      => true,
+                               NS_TALK => true,
+                               NS_USER => true,
+                               NS_USER_TALK => true,
                        ),
                        'wgCapitalLinks' => true,
                        'wgCapitalLinkOverrides' => array(),
@@ -42,18 +42,18 @@ class MWNamespaceTest extends MediaWikiTestCase {
         */
        public function testIsSubject() {
                // Special namespaces
-               $this->assertIsSubject( NS_MEDIA   );
+               $this->assertIsSubject( NS_MEDIA );
                $this->assertIsSubject( NS_SPECIAL );
 
                // Subject pages
                $this->assertIsSubject( NS_MAIN );
                $this->assertIsSubject( NS_USER );
-               $this->assertIsSubject( 100     );  # user defined
+               $this->assertIsSubject( 100 ); # user defined
 
                // Talk pages
-               $this->assertIsNotSubject( NS_TALK      );
+               $this->assertIsNotSubject( NS_TALK );
                $this->assertIsNotSubject( NS_USER_TALK );
-               $this->assertIsNotSubject( 101          ); # user defined
+               $this->assertIsNotSubject( 101 ); # user defined
        }
 
        /**
@@ -62,18 +62,18 @@ class MWNamespaceTest extends MediaWikiTestCase {
         */
        public function testIsTalk() {
                // Special namespaces
-               $this->assertIsNotTalk( NS_MEDIA   );
+               $this->assertIsNotTalk( NS_MEDIA );
                $this->assertIsNotTalk( NS_SPECIAL );
 
                // Subject pages
-               $this->assertIsNotTalk( NS_MAIN   );
-               $this->assertIsNotTalk( NS_USER   );
-               $this->assertIsNotTalk( 100       );  # user defined
+               $this->assertIsNotTalk( NS_MAIN );
+               $this->assertIsNotTalk( NS_USER );
+               $this->assertIsNotTalk( 100 ); # user defined
 
                // Talk pages
-               $this->assertIsTalk( NS_TALK      );
+               $this->assertIsTalk( NS_TALK );
                $this->assertIsTalk( NS_USER_TALK );
-               $this->assertIsTalk( 101          ); # user defined
+               $this->assertIsTalk( 101 ); # user defined
        }
 
        /**
@@ -135,7 +135,7 @@ class MWNamespaceTest extends MediaWikiTestCase {
         * @expectedException MWException
         */
        public function testGetAssociatedExceptionsForNsMedia() {
-               $this->assertNull( MWNamespace::getAssociated( NS_MEDIA   ) );
+               $this->assertNull( MWNamespace::getAssociated( NS_MEDIA ) );
        }
 
        /**
@@ -148,14 +148,14 @@ class MWNamespaceTest extends MediaWikiTestCase {
        /**
         * @todo Implement testExists().
         */
-/*
+       /*
        public function testExists() {
                // Remove the following lines when you implement this test.
                $this->markTestIncomplete(
                  'This test has not been implemented yet. Rely on $wgCanonicalNamespaces.'
                );
        }
-*/
+       */
 
        /**
         * Test MWNamespace::equals
@@ -189,7 +189,7 @@ class MWNamespaceTest extends MediaWikiTestCase {
                $this->assertSameSubject( NS_USER, NS_USER_TALK );
 
                $this->assertDifferentSubject( NS_PROJECT, NS_TEMPLATE );
-               $this->assertDifferentSubject( NS_SPECIAL, NS_MAIN     );
+               $this->assertDifferentSubject( NS_SPECIAL, NS_MAIN );
        }
 
        public function testSpecialAndMediaAreDifferentSubjects() {
@@ -207,56 +207,58 @@ class MWNamespaceTest extends MediaWikiTestCase {
        /**
         * @todo Implement testGetCanonicalNamespaces().
         */
-/*
+       /*
        public function testGetCanonicalNamespaces() {
                // Remove the following lines when you implement this test.
                $this->markTestIncomplete(
                  'This test has not been implemented yet. Rely on $wgCanonicalNamespaces.'
                );
        }
-*/
+       */
        /**
         * @todo Implement testGetCanonicalName().
         */
-/*
-       public function testGetCanonicalName() {
-               // Remove the following lines when you implement this test.
-               $this->markTestIncomplete(
-                 'This test has not been implemented yet. Rely on $wgCanonicalNamespaces.'
-               );
-       }
-*/
+       /*
+               public function testGetCanonicalName() {
+                       // Remove the following lines when you implement this test.
+                       $this->markTestIncomplete(
+                         'This test has not been implemented yet. Rely on $wgCanonicalNamespaces.'
+                       );
+               }
+       */
        /**
         * @todo Implement testGetCanonicalIndex().
         */
-/*
+       /*
        public function testGetCanonicalIndex() {
                // Remove the following lines when you implement this test.
                $this->markTestIncomplete(
                  'This test has not been implemented yet. Rely on $wgCanonicalNamespaces.'
                );
        }
-*/
+       */
+
        /**
         * @todo Implement testGetValidNamespaces().
         */
-/*
+       /*
        public function testGetValidNamespaces() {
                // Remove the following lines when you implement this test.
                $this->markTestIncomplete(
                  'This test has not been implemented yet. Rely on $wgCanonicalNamespaces.'
                );
        }
-*/
+       */
+
        /**
         */
        public function testCanTalk() {
-               $this->assertCanNotTalk( NS_MEDIA   );
+               $this->assertCanNotTalk( NS_MEDIA );
                $this->assertCanNotTalk( NS_SPECIAL );
 
-               $this->assertCanTalk( NS_MAIN      );
-               $this->assertCanTalk( NS_TALK      );
-               $this->assertCanTalk( NS_USER      );
+               $this->assertCanTalk( NS_MAIN );
+               $this->assertCanTalk( NS_TALK );
+               $this->assertCanTalk( NS_USER );
                $this->assertCanTalk( NS_USER_TALK );
 
                // User defined namespaces
@@ -303,7 +305,7 @@ class MWNamespaceTest extends MediaWikiTestCase {
 
        public function testIsWatchable() {
                // Specials namespaces are not watchable
-               $this->assertIsNotWatchable( NS_MEDIA   );
+               $this->assertIsNotWatchable( NS_MEDIA );
                $this->assertIsNotWatchable( NS_SPECIAL );
 
                // Core defined namespaces are watchables
@@ -319,7 +321,7 @@ class MWNamespaceTest extends MediaWikiTestCase {
                global $wgNamespacesWithSubpages;
 
                // Special namespaces:
-               $this->assertHasNotSubpages( NS_MEDIA   );
+               $this->assertHasNotSubpages( NS_MEDIA );
                $this->assertHasNotSubpages( NS_SPECIAL );
 
                // Namespaces without subpages
@@ -332,8 +334,8 @@ class MWNamespaceTest extends MediaWikiTestCase {
                $this->assertHasNotSubpages( NS_MAIN );
 
                // Some namespaces with subpages
-               $this->assertHasSubpages( NS_TALK      );
-               $this->assertHasSubpages( NS_USER      );
+               $this->assertHasSubpages( NS_TALK );
+               $this->assertHasSubpages( NS_USER );
                $this->assertHasSubpages( NS_USER_TALK );
        }
 
@@ -392,7 +394,7 @@ class MWNamespaceTest extends MediaWikiTestCase {
         */
        public function testGetSubjectNamespaces() {
                $subjectsNS = MWNamespace::getSubjectNamespaces();
-               $this->assertContains(    NS_MAIN, $subjectsNS,
+               $this->assertContains( NS_MAIN, $subjectsNS,
                        "Talk namespaces should have NS_MAIN" );
                $this->assertNotContains( NS_TALK, $subjectsNS,
                        "Talk namespaces should have NS_TALK" );
@@ -407,7 +409,7 @@ class MWNamespaceTest extends MediaWikiTestCase {
         */
        public function testGetTalkNamespaces() {
                $talkNS = MWNamespace::getTalkNamespaces();
-               $this->assertContains(    NS_TALK, $talkNS,
+               $this->assertContains( NS_TALK, $talkNS,
                        "Subject namespaces should have NS_TALK" );
                $this->assertNotContains( NS_MAIN, $talkNS,
                        "Subject namespaces should not have NS_MAIN" );
@@ -426,18 +428,18 @@ class MWNamespaceTest extends MediaWikiTestCase {
                // NS_MEDIA and NS_FILE are treated the same
                $this->assertEquals(
                        MWNamespace::isCapitalized( NS_MEDIA ),
-                       MWNamespace::isCapitalized( NS_FILE  ),
+                       MWNamespace::isCapitalized( NS_FILE ),
                        'NS_MEDIA and NS_FILE have same capitalization rendering'
                );
 
                // Boths are capitalized by default
                $this->assertIsCapitalized( NS_MEDIA );
-               $this->assertIsCapitalized( NS_FILE  );
+               $this->assertIsCapitalized( NS_FILE );
 
                // Always capitalized namespaces
                // @see MWNamespace::$alwaysCapitalizedNamespaces
-               $this->assertIsCapitalized( NS_SPECIAL   );
-               $this->assertIsCapitalized( NS_USER      );
+               $this->assertIsCapitalized( NS_SPECIAL );
+               $this->assertIsCapitalized( NS_USER );
                $this->assertIsCapitalized( NS_MEDIAWIKI );
        }
 
@@ -456,18 +458,18 @@ class MWNamespaceTest extends MediaWikiTestCase {
        public function testIsCapitalizedWithWgCapitalLinks() {
                global $wgCapitalLinks;
 
-               $this->assertIsCapitalized( NS_PROJECT      );
+               $this->assertIsCapitalized( NS_PROJECT );
                $this->assertIsCapitalized( NS_PROJECT_TALK );
 
                $wgCapitalLinks = false;
 
                // hardcoded namespaces (see above function) are still capitalized:
-               $this->assertIsCapitalized( NS_SPECIAL   );
-               $this->assertIsCapitalized( NS_USER      );
+               $this->assertIsCapitalized( NS_SPECIAL );
+               $this->assertIsCapitalized( NS_USER );
                $this->assertIsCapitalized( NS_MEDIAWIKI );
 
                // setting is correctly applied
-               $this->assertIsNotCapitalized( NS_PROJECT      );
+               $this->assertIsNotCapitalized( NS_PROJECT );
                $this->assertIsNotCapitalized( NS_PROJECT_TALK );
        }
 
@@ -481,27 +483,27 @@ class MWNamespaceTest extends MediaWikiTestCase {
                global $wgCapitalLinkOverrides;
 
                // Test default settings
-               $this->assertIsCapitalized( NS_PROJECT      );
+               $this->assertIsCapitalized( NS_PROJECT );
                $this->assertIsCapitalized( NS_PROJECT_TALK );
 
                // hardcoded namespaces (see above function) are capitalized:
-               $this->assertIsCapitalized( NS_SPECIAL   );
-               $this->assertIsCapitalized( NS_USER      );
+               $this->assertIsCapitalized( NS_SPECIAL );
+               $this->assertIsCapitalized( NS_USER );
                $this->assertIsCapitalized( NS_MEDIAWIKI );
 
                // Hardcoded namespaces remains capitalized
-               $wgCapitalLinkOverrides[NS_SPECIAL]   = false;
-               $wgCapitalLinkOverrides[NS_USER]      = false;
+               $wgCapitalLinkOverrides[NS_SPECIAL] = false;
+               $wgCapitalLinkOverrides[NS_USER] = false;
                $wgCapitalLinkOverrides[NS_MEDIAWIKI] = false;
 
-               $this->assertIsCapitalized( NS_SPECIAL   );
-               $this->assertIsCapitalized( NS_USER      );
+               $this->assertIsCapitalized( NS_SPECIAL );
+               $this->assertIsCapitalized( NS_USER );
                $this->assertIsCapitalized( NS_MEDIAWIKI );
 
                $wgCapitalLinkOverrides[NS_PROJECT] = false;
                $this->assertIsNotCapitalized( NS_PROJECT );
 
-               $wgCapitalLinkOverrides[NS_PROJECT] = true ;
+               $wgCapitalLinkOverrides[NS_PROJECT] = true;
                $this->assertIsCapitalized( NS_PROJECT );
 
                unset( $wgCapitalLinkOverrides[NS_PROJECT] );
@@ -510,15 +512,14 @@ class MWNamespaceTest extends MediaWikiTestCase {
 
        public function testHasGenderDistinction() {
                // Namespaces with gender distinctions
-               $this->assertTrue( MWNamespace::hasGenderDistinction( NS_USER      ) );
+               $this->assertTrue( MWNamespace::hasGenderDistinction( NS_USER ) );
                $this->assertTrue( MWNamespace::hasGenderDistinction( NS_USER_TALK ) );
 
                // Other ones, "genderless"
-               $this->assertFalse( MWNamespace::hasGenderDistinction( NS_MEDIA   ) );
+               $this->assertFalse( MWNamespace::hasGenderDistinction( NS_MEDIA ) );
                $this->assertFalse( MWNamespace::hasGenderDistinction( NS_SPECIAL ) );
-               $this->assertFalse( MWNamespace::hasGenderDistinction( NS_MAIN    ) );
-               $this->assertFalse( MWNamespace::hasGenderDistinction( NS_TALK    ) );
-
+               $this->assertFalse( MWNamespace::hasGenderDistinction( NS_MAIN ) );
+               $this->assertFalse( MWNamespace::hasGenderDistinction( NS_TALK ) );
        }
 
        public function testIsNonincludable() {
@@ -533,25 +534,25 @@ class MWNamespaceTest extends MediaWikiTestCase {
        ####### HELPERS ###########################################################
        function __call( $method, $args ) {
                // Call the real method if it exists
-               if( method_exists($this, $method ) ) {
+               if ( method_exists( $this, $method ) ) {
                        return $this->$method( $args );
                }
 
-               if( preg_match( '/^assert(Has|Is|Can)(Not|)(Subject|Talk|Watchable|Content|Subpages|Capitalized)$/', $method, $m ) ) {
+               if ( preg_match( '/^assert(Has|Is|Can)(Not|)(Subject|Talk|Watchable|Content|Subpages|Capitalized)$/', $method, $m ) ) {
                        # Interprets arguments:
-                       $ns  = $args[0];
-                       $msg = isset($args[1]) ? $args[1] : " dummy message";
+                       $ns = $args[0];
+                       $msg = isset( $args[1] ) ? $args[1] : " dummy message";
 
                        # Forge the namespace constant name:
-                       if( $ns === 0 ) {
+                       if ( $ns === 0 ) {
                                $ns_name = "NS_MAIN";
                        } else {
-                               $ns_name = "NS_" . strtoupper(  MWNamespace::getCanonicalName( $ns ) );
+                               $ns_name = "NS_" . strtoupper( MWNamespace::getCanonicalName( $ns ) );
                        }
                        # ... and the MWNamespace method name
                        $nsMethod = strtolower( $m[1] ) . $m[3];
 
-                       $expect = ($m[2] === '');
+                       $expect = ( $m[2] === '' );
                        $expect_name = $expect ? 'TRUE' : 'FALSE';
 
                        return $this->assertEquals( $expect,
@@ -566,6 +567,7 @@ class MWNamespaceTest extends MediaWikiTestCase {
        function assertSameSubject( $ns1, $ns2, $msg = '' ) {
                $this->assertTrue( MWNamespace::subjectEquals( $ns1, $ns2, $msg ) );
        }
+
        function assertDifferentSubject( $ns1, $ns2, $msg = '' ) {
                $this->assertFalse( MWNamespace::subjectEquals( $ns1, $ns2, $msg ) );
        }
index 8b68703..4084fb1 100644 (file)
@@ -26,7 +26,7 @@ class OutputPageTest extends MediaWikiTestCase {
         *
         * @param array $args key-value array of arguments as shown above
         */
-       protected function assertTransformCssMediaCase($args) {
+       protected function assertTransformCssMediaCase( $args ) {
                $queryData = array();
                if ( isset( $args['printableQuery'] ) ) {
                        $queryData['printable'] = $args['printableQuery'];
@@ -38,12 +38,12 @@ class OutputPageTest extends MediaWikiTestCase {
 
                $fauxRequest = new FauxRequest( $queryData, false );
                $this->setMWGlobals( array(
-                               'wgRequest' => $fauxRequest,
-                               'wgHandheldForIPhone' => $args['handheldForIPhone']
+                       'wgRequest' => $fauxRequest,
+                       'wgHandheldForIPhone' => $args['handheldForIPhone']
                ) );
 
                $actualReturn = OutputPage::transformCssMedia( $args['media'] );
-               $this->assertSame( $args['expectedReturn'], $actualReturn, $args['message']);
+               $this->assertSame( $args['expectedReturn'], $actualReturn, $args['message'] );
        }
 
        /**
@@ -55,11 +55,11 @@ class OutputPageTest extends MediaWikiTestCase {
         * @param array $args key-value array of arguments as shown in assertTransformCssMediaCase.
         * Will be mutated.
         */
-       protected function assertTransformCssMediaCaseWithBothHandheldForIPhone($args) {
+       protected function assertTransformCssMediaCaseWithBothHandheldForIPhone( $args ) {
                $message = $args['message'];
-               foreach( array( true, false ) as $handheldForIPhone ) {
+               foreach ( array( true, false ) as $handheldForIPhone ) {
                        $args['handheldForIPhone'] = $handheldForIPhone;
-                       $stringHandheldForIPhone = var_export($handheldForIPhone, true);
+                       $stringHandheldForIPhone = var_export( $handheldForIPhone, true );
                        $args['message'] = "$message. \$wgHandheldForIPhone was $stringHandheldForIPhone";
                        $this->assertTransformCssMediaCase( $args );
                }
@@ -132,14 +132,14 @@ class OutputPageTest extends MediaWikiTestCase {
         * Tests handheld and wgHandheldForIPhone behavior
         */
        public function testHandheld() {
-               $this->assertTransformCssMediaCaseWithBothHandheldForIPhone(array(
+               $this->assertTransformCssMediaCaseWithBothHandheldForIPhone( array(
                        'handheldQuery' => '1',
                        'media' => 'handheld',
                        'expectedReturn' => '',
                        'message' => 'On request with handheld querystring and media is handheld, returns empty string'
                ) );
 
-               $this->assertTransformCssMediaCaseWithBothHandheldForIPhone(array(
+               $this->assertTransformCssMediaCaseWithBothHandheldForIPhone( array(
                        'handheldQuery' => '1',
                        'media' => 'screen',
                        'expectedReturn' => null,
@@ -147,7 +147,7 @@ class OutputPageTest extends MediaWikiTestCase {
                ) );
 
                // A bit counter-intuitively, $wgHandheldForIPhone should only matter if the query handheld is false or omitted
-               $this->assertTransformCssMediaCase(array(
+               $this->assertTransformCssMediaCase( array(
                        'handheldQuery' => '0',
                        'media' => 'screen',
                        'handheldForIPhone' => true,
@@ -155,7 +155,7 @@ class OutputPageTest extends MediaWikiTestCase {
                        'message' => 'With $wgHandheldForIPhone true, screen media type is transformed'
                ) );
 
-               $this->assertTransformCssMediaCase(array(
+               $this->assertTransformCssMediaCase( array(
                        'media' => 'handheld',
                        'handheldForIPhone' => true,
                        'expectedReturn' => 'handheld, only screen and (max-device-width: 480px)',
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 );
-       }
-}
index 910743e..f24cbab 100644 (file)
@@ -8,7 +8,7 @@ class PathRouterTest extends MediaWikiTestCase {
        protected function setUp() {
                parent::setUp();
                $router = new PathRouter;
-               $router->add("/wiki/$1");
+               $router->add( "/wiki/$1" );
                $this->basicRouter = $router;
        }
 
@@ -25,17 +25,17 @@ class PathRouterTest extends MediaWikiTestCase {
         */
        public function testLoose() {
                $router = new PathRouter;
-               $router->add("/"); # Should be the same as "/$1"
+               $router->add( "/" ); # Should be the same as "/$1"
                $matches = $router->parse( "/Foo" );
                $this->assertEquals( $matches, array( 'title' => "Foo" ) );
 
                $router = new PathRouter;
-               $router->add("/wiki"); # Should be the same as /wiki/$1
+               $router->add( "/wiki" ); # Should be the same as /wiki/$1
                $matches = $router->parse( "/wiki/Foo" );
                $this->assertEquals( $matches, array( 'title' => "Foo" ) );
 
                $router = new PathRouter;
-               $router->add("/wiki/"); # Should be the same as /wiki/$1
+               $router->add( "/wiki/" ); # Should be the same as /wiki/$1
                $matches = $router->parse( "/wiki/Foo" );
                $this->assertEquals( $matches, array( 'title' => "Foo" ) );
        }
@@ -45,16 +45,16 @@ class PathRouterTest extends MediaWikiTestCase {
         */
        public function testOrder() {
                $router = new PathRouter;
-               $router->add("/$1");
-               $router->add("/a/$1");
-               $router->add("/b/$1");
+               $router->add( "/$1" );
+               $router->add( "/a/$1" );
+               $router->add( "/b/$1" );
                $matches = $router->parse( "/a/Foo" );
                $this->assertEquals( $matches, array( 'title' => "Foo" ) );
 
                $router = new PathRouter;
-               $router->add("/b/$1");
-               $router->add("/a/$1");
-               $router->add("/$1");
+               $router->add( "/b/$1" );
+               $router->add( "/a/$1" );
+               $router->add( "/$1" );
                $matches = $router->parse( "/a/Foo" );
                $this->assertEquals( $matches, array( 'title' => "Foo" ) );
        }
@@ -151,18 +151,18 @@ class PathRouterTest extends MediaWikiTestCase {
                $router->add( array( 'qwerty' => "/qwerty/$1" ), array( 'qwerty' => '$key' ) );
                $router->add( "/$2/$1", array( 'restricted-to-y' => '$2' ), array( '$2' => 'y' ) );
 
-               foreach( array(
-                       "/Foo" => array( 'title' => "Foo" ),
-                       "/Bar" => array( 'ping' => 'pong' ),
-                       "/Baz" => array( 'marco' => 'polo' ),
-                       "/asdf-foo" => array( 'title' => "qwerty-foo" ),
-                       "/qwerty-bar" => array( 'title' => "asdf-bar" ),
-                       "/a/Foo" => array( 'title' => "Foo" ),
-                       "/asdf/Foo" => array( 'title' => "Foo" ),
-                       "/qwerty/Foo" => array( 'title' => "Foo", 'qwerty' => 'qwerty' ),
-                       "/baz/Foo" => array( 'title' => "Foo", 'unrestricted' => 'baz' ),
-                       "/y/Foo" => array( 'title' => "Foo", 'restricted-to-y' => 'y' ),
-               ) as $path => $result ) {
+               foreach ( array(
+                                         "/Foo" => array( 'title' => "Foo" ),
+                                         "/Bar" => array( 'ping' => 'pong' ),
+                                         "/Baz" => array( 'marco' => 'polo' ),
+                                         "/asdf-foo" => array( 'title' => "qwerty-foo" ),
+                                         "/qwerty-bar" => array( 'title' => "asdf-bar" ),
+                                         "/a/Foo" => array( 'title' => "Foo" ),
+                                         "/asdf/Foo" => array( 'title' => "Foo" ),
+                                         "/qwerty/Foo" => array( 'title' => "Foo", 'qwerty' => 'qwerty' ),
+                                         "/baz/Foo" => array( 'title' => "Foo", 'unrestricted' => 'baz' ),
+                                         "/y/Foo" => array( 'title' => "Foo", 'restricted-to-y' => 'y' ),
+                                 ) as $path => $result ) {
                        $this->assertEquals( $router->parse( $path ), $result );
                }
        }
index 5e546ce..7aa3c4a 100644 (file)
@@ -17,14 +17,14 @@ class PreferencesTest extends MediaWikiTestCase {
                $this->prefUsers['notauth']
                        ->setEmail( 'noauth@example.org' );
 
-               $this->prefUsers['auth']    = new User;
+               $this->prefUsers['auth'] = new User;
                $this->prefUsers['auth']
                        ->setEmail( 'noauth@example.org' );
                $this->prefUsers['auth']
                        ->setEmailAuthenticationTimestamp( 1330946623 );
 
                $this->context = new RequestContext;
-               $this->context->setTitle( Title::newFromText('PreferencesTest') );
+               $this->context->setTitle( Title::newFromText( 'PreferencesTest' ) );
        }
 
        protected function setUp() {
@@ -44,6 +44,7 @@ class PreferencesTest extends MediaWikiTestCase {
                );
                $this->assertEquals( 'mw-email-none', $prefs['emailaddress']['cssclass'] );
        }
+
        /**
         * Placeholder to verify bug 34302
         * @covers Preferences::profilePreferences
@@ -55,6 +56,7 @@ class PreferencesTest extends MediaWikiTestCase {
                );
                $this->assertEquals( 'mw-email-not-authenticated', $prefs['emailaddress']['cssclass'] );
        }
+
        /**
         * Placeholder to verify bug 34302
         * @covers Preferences::profilePreferences
index f451f8a..948b635 100644 (file)
@@ -13,7 +13,7 @@ class MediaWikiProvide {
        /* provide an array of numbers from 1 up to @param $num */
        private static function createProviderUpTo( $num ) {
                $ret = array();
-               for( $i=1; $i<=$num;$i++ ) {
+               for ( $i = 1; $i <= $num; $i++ ) {
                        $ret[] = array( $i );
                }
                return $ret;
@@ -33,9 +33,9 @@ class MediaWikiProvide {
                $ret = array();
 
                $months = self::Months();
-               $days   = self::Days();
-               foreach( $months as $month) {
-                       foreach( $days as $day ) {
+               $days = self::Days();
+               foreach ( $months as $month ) {
+                       foreach ( $days as $day ) {
                                $ret[] = array( $day[0], $month[0] );
                        }
                }
index 5b99628..a1e6236 100644 (file)
@@ -12,9 +12,9 @@ class RecentChangeTest extends MediaWikiTestCase {
        function __construct() {
                parent::__construct();
 
-               $this->title  = Title::newFromText( 'SomeTitle' );
+               $this->title = Title::newFromText( 'SomeTitle' );
                $this->target = Title::newFromText( 'TestTarget' );
-               $this->user   = User::newFromName( 'UserName' );
+               $this->user = User::newFromName( 'UserName' );
 
                $this->user_comment = '<User comment about action>';
                $this->context = RequestContext::newExtraneousContext( $this->title );
@@ -61,14 +61,14 @@ class RecentChangeTest extends MediaWikiTestCase {
 
                # block/block
                $this->assertIRCComment(
-                       $this->context->msg( 'blocklogentry', 'SomeTitle' )->plain() . $sep .  $this->user_comment,
+                       $this->context->msg( 'blocklogentry', 'SomeTitle' )->plain() . $sep . $this->user_comment,
                        'block', 'block',
                        array(),
                        $this->user_comment
                );
                # block/unblock
                $this->assertIRCComment(
-                       $this->context->msg( 'unblocklogentry', 'SomeTitle' )->plain() . $sep .  $this->user_comment,
+                       $this->context->msg( 'unblocklogentry', 'SomeTitle' )->plain() . $sep . $this->user_comment,
                        'block', 'unblock',
                        array(),
                        $this->user_comment
@@ -83,7 +83,7 @@ class RecentChangeTest extends MediaWikiTestCase {
 
                # delete/delete
                $this->assertIRCComment(
-                       $this->context->msg( 'deletedarticle', 'SomeTitle' )->plain() . $sep .  $this->user_comment,
+                       $this->context->msg( 'deletedarticle', 'SomeTitle' )->plain() . $sep . $this->user_comment,
                        'delete', 'delete',
                        array(),
                        $this->user_comment
@@ -91,7 +91,7 @@ class RecentChangeTest extends MediaWikiTestCase {
 
                # delete/restore
                $this->assertIRCComment(
-                       $this->context->msg( 'undeletedarticle', 'SomeTitle' )->plain() . $sep .  $this->user_comment,
+                       $this->context->msg( 'undeletedarticle', 'SomeTitle' )->plain() . $sep . $this->user_comment,
                        'delete', 'restore',
                        array(),
                        $this->user_comment
@@ -129,14 +129,14 @@ class RecentChangeTest extends MediaWikiTestCase {
         */
        function testIrcMsgForLogTypeMove() {
                $move_params = array(
-                       '4::target'  => $this->target->getPrefixedText(),
+                       '4::target' => $this->target->getPrefixedText(),
                        '5::noredir' => 0,
                );
                $sep = $this->context->msg( 'colon-separator' )->text();
 
                # move/move
                $this->assertIRCComment(
-                       $this->context->msg( '1movedto2', 'SomeTitle', 'TestTarget' )->plain() . $sep .  $this->user_comment,
+                       $this->context->msg( '1movedto2', 'SomeTitle', 'TestTarget' )->plain() . $sep . $this->user_comment,
                        'move', 'move',
                        $move_params,
                        $this->user_comment
@@ -144,7 +144,7 @@ class RecentChangeTest extends MediaWikiTestCase {
 
                # move/move_redir
                $this->assertIRCComment(
-                       $this->context->msg( '1movedto2_redir', 'SomeTitle', 'TestTarget' )->plain() . $sep .  $this->user_comment,
+                       $this->context->msg( '1movedto2_redir', 'SomeTitle', 'TestTarget' )->plain() . $sep . $this->user_comment,
                        'move', 'move_redir',
                        $move_params,
                        $this->user_comment
@@ -160,9 +160,9 @@ class RecentChangeTest extends MediaWikiTestCase {
                        $this->context->msg( 'patrol-log-line', 'revision 777', '[[SomeTitle]]', '' )->plain(),
                        'patrol', 'patrol',
                        array(
-                               '4::curid'  => '777',
+                               '4::curid' => '777',
                                '5::previd' => '666',
-                               '6::auto'   => 0,
+                               '6::auto' => 0,
                        )
                );
        }
@@ -178,7 +178,7 @@ class RecentChangeTest extends MediaWikiTestCase {
 
                # protect/protect
                $this->assertIRCComment(
-                       $this->context->msg( 'protectedarticle', 'SomeTitle ' . $protectParams[0] )->plain() . $sep .  $this->user_comment,
+                       $this->context->msg( 'protectedarticle', 'SomeTitle ' . $protectParams[0] )->plain() . $sep . $this->user_comment,
                        'protect', 'protect',
                        $protectParams,
                        $this->user_comment
@@ -186,7 +186,7 @@ class RecentChangeTest extends MediaWikiTestCase {
 
                # protect/unprotect
                $this->assertIRCComment(
-                       $this->context->msg( 'unprotectedarticle', 'SomeTitle' )->plain() . $sep .  $this->user_comment,
+                       $this->context->msg( 'unprotectedarticle', 'SomeTitle' )->plain() . $sep . $this->user_comment,
                        'protect', 'unprotect',
                        array(),
                        $this->user_comment
@@ -194,7 +194,7 @@ class RecentChangeTest extends MediaWikiTestCase {
 
                # protect/modify
                $this->assertIRCComment(
-                       $this->context->msg( 'modifiedarticleprotection', 'SomeTitle ' . $protectParams[0] )->plain() . $sep .  $this->user_comment,
+                       $this->context->msg( 'modifiedarticleprotection', 'SomeTitle ' . $protectParams[0] )->plain() . $sep . $this->user_comment,
                        'protect', 'modify',
                        $protectParams,
                        $this->user_comment
@@ -209,7 +209,7 @@ class RecentChangeTest extends MediaWikiTestCase {
 
                # upload/upload
                $this->assertIRCComment(
-                       $this->context->msg( 'uploadedimage', 'SomeTitle' )->plain() . $sep .  $this->user_comment,
+                       $this->context->msg( 'uploadedimage', 'SomeTitle' )->plain() . $sep . $this->user_comment,
                        'upload', 'upload',
                        array(),
                        $this->user_comment
@@ -217,7 +217,7 @@ class RecentChangeTest extends MediaWikiTestCase {
 
                # upload/overwrite
                $this->assertIRCComment(
-                       $this->context->msg( 'overwroteimage', 'SomeTitle' )->plain() . $sep .  $this->user_comment,
+                       $this->context->msg( 'overwroteimage', 'SomeTitle' )->plain() . $sep . $this->user_comment,
                        'upload', 'overwrite',
                        array(),
                        $this->user_comment
@@ -229,7 +229,7 @@ class RecentChangeTest extends MediaWikiTestCase {
         * raw edit summary from RecentChange object
         * --
         */
-/*
+       /*
        function testIrcMsgForBlankingAES() {
                // $this->context->msg( 'autosumm-blank', .. );
        }
@@ -245,8 +245,7 @@ class RecentChangeTest extends MediaWikiTestCase {
        function testIrcMsgForUndoAES() {
                // $this->context->msg( 'undo-summary', .. );
        }
-
-*/
+       */
 
        /**
         * @param $expected String Expected IRC text without colors codes
index 893d260..60618b1 100644 (file)
@@ -84,7 +84,7 @@ class ResourceLoaderTest extends MediaWikiTestCase {
 
 /* Stubs */
 
-class ResourceLoaderTestModule extends ResourceLoaderModule { }
+class ResourceLoaderTestModule extends ResourceLoaderModule {}
 
 /* Hooks */
 global $wgHooks;
index 1301bf3..e8d8db0 100644 (file)
@@ -21,21 +21,21 @@ class RevisionStorageTest extends MediaWikiTestCase {
                parent::__construct( $name, $data, $dataName );
 
                $this->tablesUsed = array_merge( $this->tablesUsed,
-                                                array( 'page',
-                                                     'revision',
-                                                     'text',
-
-                                                     'recentchanges',
-                                                     'logging',
-
-                                                     'page_props',
-                                                     'pagelinks',
-                                                     'categorylinks',
-                                                     'langlinks',
-                                                     'externallinks',
-                                                     'imagelinks',
-                                                     'templatelinks',
-                                                     'iwlinks' ) );
+                       array( 'page',
+                               'revision',
+                               'text',
+
+                               'recentchanges',
+                               'logging',
+
+                               'page_props',
+                               'pagelinks',
+                               'categorylinks',
+                               'langlinks',
+                               'externallinks',
+                               'imagelinks',
+                               'templatelinks',
+                               'iwlinks' ) );
        }
 
        public function setUp() {
@@ -43,11 +43,11 @@ class RevisionStorageTest extends MediaWikiTestCase {
 
                parent::setUp();
 
-               $wgExtraNamespaces[ 12312 ] = 'Dummy';
-               $wgExtraNamespaces[ 12313 ] = 'Dummy_talk';
+               $wgExtraNamespaces[12312] = 'Dummy';
+               $wgExtraNamespaces[12313] = 'Dummy_talk';
 
-               $wgNamespaceContentModels[ 12312 ] = 'DUMMY';
-               $wgContentHandlers[ 'DUMMY' ] = 'DummyContentHandlerForTesting';
+               $wgNamespaceContentModels[12312] = 'DUMMY';
+               $wgContentHandlers['DUMMY'] = 'DummyContentHandlerForTesting';
 
                MWNamespace::getCanonicalNamespaces( true ); # reset namespace cache
                $wgContLang->resetNamespaces(); # reset namespace cache
@@ -61,22 +61,32 @@ class RevisionStorageTest extends MediaWikiTestCase {
 
                parent::tearDown();
 
-               unset( $wgExtraNamespaces[ 12312 ] );
-               unset( $wgExtraNamespaces[ 12313 ] );
+               unset( $wgExtraNamespaces[12312] );
+               unset( $wgExtraNamespaces[12313] );
 
-               unset( $wgNamespaceContentModels[ 12312 ] );
-               unset( $wgContentHandlers[ 'DUMMY' ] );
+               unset( $wgNamespaceContentModels[12312] );
+               unset( $wgContentHandlers['DUMMY'] );
 
                MWNamespace::getCanonicalNamespaces( true ); # reset namespace cache
                $wgContLang->resetNamespaces(); # reset namespace cache
        }
 
        protected function makeRevision( $props = null ) {
-               if ( $props === null ) $props = array();
+               if ( $props === null ) {
+                       $props = array();
+               }
 
-               if ( !isset( $props['content'] ) && !isset( $props['text'] ) ) $props['text'] = 'Lorem Ipsum';
-               if ( !isset( $props['comment'] ) ) $props['comment'] = 'just a test';
-               if ( !isset( $props['page'] ) ) $props['page'] = $this->the_page->getId();
+               if ( !isset( $props['content'] ) && !isset( $props['text'] ) ) {
+                       $props['text'] = 'Lorem Ipsum';
+               }
+
+               if ( !isset( $props['comment'] ) ) {
+                       $props['comment'] = 'just a test';
+               }
+
+               if ( !isset( $props['page'] ) ) {
+                       $props['page'] = $this->the_page->getId();
+               }
 
                $rev = new Revision( $props );
 
@@ -89,8 +99,8 @@ class RevisionStorageTest extends MediaWikiTestCase {
        protected function createPage( $page, $text, $model = null ) {
                if ( is_string( $page ) ) {
                        if ( !preg_match( '/:/', $page ) &&
-                               ( $model === null || $model === CONTENT_MODEL_WIKITEXT ) ) {
-
+                               ( $model === null || $model === CONTENT_MODEL_WIKITEXT )
+                       ) {
                                $ns = $this->getDefaultWikitextNS();
                                $page = MWNamespace::getCanonicalName( $ns ) . ':' . $page;
                        }
@@ -207,11 +217,11 @@ class RevisionStorageTest extends MediaWikiTestCase {
                #note: order is unspecified
                $rows = array();
                while ( ( $row = $res->fetchObject() ) ) {
-                       $rows[ $row->rev_id ]= $row;
+                       $rows[$row->rev_id] = $row;
                }
 
                $row = $res->fetchObject();
-               $this->assertEquals( 1, count($rows), 'expected exactly one revision' );
+               $this->assertEquals( 1, count( $rows ), 'expected exactly one revision' );
                $this->assertArrayHasKey( $id2, $rows, 'missing revision with id ' . $id2 );
        }
 
@@ -223,16 +233,16 @@ class RevisionStorageTest extends MediaWikiTestCase {
 
                $fields = Revision::selectFields();
 
-               $this->assertTrue( in_array( 'rev_id', $fields ), 'missing rev_id in list of fields');
-               $this->assertTrue( in_array( 'rev_page', $fields ), 'missing rev_page in list of fields');
-               $this->assertTrue( in_array( 'rev_timestamp', $fields ), 'missing rev_timestamp in list of fields');
-               $this->assertTrue( in_array( 'rev_user', $fields ), 'missing rev_user in list of fields');
+               $this->assertTrue( in_array( 'rev_id', $fields ), 'missing rev_id in list of fields' );
+               $this->assertTrue( in_array( 'rev_page', $fields ), 'missing rev_page in list of fields' );
+               $this->assertTrue( in_array( 'rev_timestamp', $fields ), 'missing rev_timestamp in list of fields' );
+               $this->assertTrue( in_array( 'rev_user', $fields ), 'missing rev_user in list of fields' );
 
                if ( $wgContentHandlerUseDB ) {
                        $this->assertTrue( in_array( 'rev_content_model', $fields ),
-                                                               'missing rev_content_model in list of fields');
+                               'missing rev_content_model in list of fields' );
                        $this->assertTrue( in_array( 'rev_content_format', $fields ),
-                                                               'missing rev_content_format in list of fields');
+                               'missing rev_content_format in list of fields' );
                }
        }
 
@@ -265,7 +275,7 @@ class RevisionStorageTest extends MediaWikiTestCase {
         */
        public function testGetContent_failure() {
                $rev = new Revision( array(
-                       'page'       =>  $this->the_page->getId(),
+                       'page' => $this->the_page->getId(),
                        'content_model' => $this->the_page->getContentModel(),
                        'text_id' => 123456789, // not in the test DB
                ) );
@@ -322,7 +332,7 @@ class RevisionStorageTest extends MediaWikiTestCase {
                }
 
                $orig = $this->makeRevision( array( 'text' => 'hello hello.',
-                                                                                       'content_model' => CONTENT_MODEL_JAVASCRIPT ) );
+                       'content_model' => CONTENT_MODEL_JAVASCRIPT ) );
                $rev = Revision::newFromId( $orig->getId() );
 
                $this->assertEquals( CONTENT_MODEL_JAVASCRIPT, $rev->getContentModel() );
@@ -338,9 +348,11 @@ class RevisionStorageTest extends MediaWikiTestCase {
                        $this->markTestSkipped( '$wgContentHandlerUseDB is disabled' );
                }
 
-               $orig = $this->makeRevision( array( 'text' => 'hello hello.',
-                                                                                       'content_model' => CONTENT_MODEL_JAVASCRIPT,
-                                                                                       'content_format' => CONTENT_FORMAT_JAVASCRIPT ) );
+               $orig = $this->makeRevision( array(
+                       'text' => 'hello hello.',
+                       'content_model' => CONTENT_MODEL_JAVASCRIPT,
+                       'content_format' => CONTENT_FORMAT_JAVASCRIPT
+               ) );
                $rev = Revision::newFromId( $orig->getId() );
 
                $this->assertEquals( CONTENT_FORMAT_JAVASCRIPT, $rev->getContentFormat() );
@@ -382,7 +394,7 @@ class RevisionStorageTest extends MediaWikiTestCase {
                $this->assertNull( $rev1->getPrevious() );
 
                $page->doEditContent( ContentHandler::makeContent( 'Bla bla', $page->getTitle(), CONTENT_MODEL_WIKITEXT ),
-                                                               'second rev testGetPrevious' );
+                       'second rev testGetPrevious' );
                $rev2 = $page->getRevision();
 
                $this->assertNotNull( $rev2->getPrevious() );
@@ -399,7 +411,7 @@ class RevisionStorageTest extends MediaWikiTestCase {
                $this->assertNull( $rev1->getNext() );
 
                $page->doEditContent( ContentHandler::makeContent( 'Bla bla', $page->getTitle(), CONTENT_MODEL_WIKITEXT ),
-                                                               'second rev testGetNext' );
+                       'second rev testGetNext' );
                $rev2 = $page->getRevision();
 
                $this->assertNotNull( $rev1->getNext() );
@@ -417,9 +429,9 @@ class RevisionStorageTest extends MediaWikiTestCase {
                $rev = Revision::newNullRevision( $dbw, $page->getId(), 'a null revision', false );
 
                $this->assertNotEquals( $orig->getId(), $rev->getId(),
-                                                               'new null revision shold have a different id from the original revision' );
+                       'new null revision shold have a different id from the original revision' );
                $this->assertEquals( $orig->getTextId(), $rev->getTextId(),
-                                                               'new null revision shold have the same text id as the original revision' );
+                       'new null revision shold have the same text id as the original revision' );
                $this->assertEquals( 'some testing text', $rev->getContent()->getNativeData() );
        }
 
@@ -525,7 +537,7 @@ class RevisionStorageTest extends MediaWikiTestCase {
                $revisions[4]->insertOn( $dbw );
 
                // test it ---------------------------------
-               $since = $revisions[ $sinceIdx ]->getTimestamp();
+               $since = $revisions[$sinceIdx]->getTimestamp();
 
                $wasLast = Revision::userWasLastToEdit( $dbw, $page->getId(), $userA->getId(), $since );
 
index d0cdfc6..3948e34 100644 (file)
@@ -46,13 +46,13 @@ class RevisionTest_ContentHandlerUseDB extends RevisionStorageTest {
        public function testSelectFields() {
                $fields = Revision::selectFields();
 
-               $this->assertTrue( in_array( 'rev_id', $fields ), 'missing rev_id in list of fields');
-               $this->assertTrue( in_array( 'rev_page', $fields ), 'missing rev_page in list of fields');
-               $this->assertTrue( in_array( 'rev_timestamp', $fields ), 'missing rev_timestamp in list of fields');
-               $this->assertTrue( in_array( 'rev_user', $fields ), 'missing rev_user in list of fields');
+               $this->assertTrue( in_array( 'rev_id', $fields ), 'missing rev_id in list of fields' );
+               $this->assertTrue( in_array( 'rev_page', $fields ), 'missing rev_page in list of fields' );
+               $this->assertTrue( in_array( 'rev_timestamp', $fields ), 'missing rev_timestamp in list of fields' );
+               $this->assertTrue( in_array( 'rev_user', $fields ), 'missing rev_user in list of fields' );
 
-               $this->assertFalse( in_array( 'rev_content_model', $fields ), 'missing rev_content_model in list of fields');
-               $this->assertFalse( in_array( 'rev_content_format', $fields ), 'missing rev_content_format in list of fields');
+               $this->assertFalse( in_array( 'rev_content_model', $fields ), 'missing rev_content_model in list of fields' );
+               $this->assertFalse( in_array( 'rev_content_format', $fields ), 'missing rev_content_format in list of fields' );
        }
 
        /**
@@ -61,7 +61,7 @@ class RevisionTest_ContentHandlerUseDB extends RevisionStorageTest {
        public function testGetContentModel() {
                try {
                        $this->makeRevision( array( 'text' => 'hello hello.',
-                                                   'content_model' => CONTENT_MODEL_JAVASCRIPT ) );
+                               'content_model' => CONTENT_MODEL_JAVASCRIPT ) );
 
                        $this->fail( "Creating JavaScript content on a wikitext page should fail with "
                                . "\$wgContentHandlerUseDB disabled" );
@@ -82,8 +82,8 @@ class RevisionTest_ContentHandlerUseDB extends RevisionStorageTest {
                        //       used for this though.
 
                        $this->makeRevision( array( 'text' => 'hello hello.',
-                                                   'content_model' => CONTENT_MODEL_JAVASCRIPT,
-                                                   'content_format' => 'text/javascript' ) );
+                               'content_model' => CONTENT_MODEL_JAVASCRIPT,
+                               'content_format' => 'text/javascript' ) );
 
                        $this->fail( "Creating JavaScript content on a wikitext page should fail with "
                                . "\$wgContentHandlerUseDB disabled" );
index 197bb06..db0245b 100644 (file)
@@ -168,13 +168,13 @@ class RevisionTest extends MediaWikiTestCase {
 
                $rev = new Revision(
                        array(
-                               'id'         => 42,
-                               'page'       => 23,
-                               'title'      => $title,
+                               'id' => 42,
+                               'page' => 23,
+                               'title' => $title,
 
-                               'content'    => $content,
-                               'length'     => $content->getSize(),
-                               'comment'    => "testing",
+                               'content' => $content,
+                               'length' => $content->getSize(),
+                               'comment' => "testing",
                                'minor_edit' => false,
 
                                'content_format' => $format,
@@ -189,7 +189,7 @@ class RevisionTest extends MediaWikiTestCase {
                return array(
                        array( 'hello world', 'Help:Hello', null, null, CONTENT_MODEL_WIKITEXT ),
                        array( 'hello world', 'User:hello/there.css', null, null, CONTENT_MODEL_CSS ),
-                       array( serialize('hello world'), 'Dummy:Hello', null, null, "testing" ),
+                       array( serialize( 'hello world' ), 'Dummy:Hello', null, null, "testing" ),
                );
        }
 
@@ -209,7 +209,7 @@ class RevisionTest extends MediaWikiTestCase {
                        array( 'hello world', 'Help:Hello', null, null, CONTENT_FORMAT_WIKITEXT ),
                        array( 'hello world', 'Help:Hello', CONTENT_MODEL_CSS, null, CONTENT_FORMAT_CSS ),
                        array( 'hello world', 'User:hello/there.css', null, null, CONTENT_FORMAT_CSS ),
-                       array( serialize('hello world'), 'Dummy:Hello', null, null, "testing" ),
+                       array( serialize( 'hello world' ), 'Dummy:Hello', null, null, "testing" ),
                );
        }
 
@@ -228,7 +228,7 @@ class RevisionTest extends MediaWikiTestCase {
                return array(
                        array( 'hello world', 'Help:Hello', null, null, 'WikitextContentHandler' ),
                        array( 'hello world', 'User:hello/there.css', null, null, 'CssContentHandler' ),
-                       array( serialize('hello world'), 'Dummy:Hello', null, null, 'DummyContentHandlerForTesting' ),
+                       array( serialize( 'hello world' ), 'Dummy:Hello', null, null, 'DummyContentHandlerForTesting' ),
                );
        }
 
@@ -246,8 +246,8 @@ class RevisionTest extends MediaWikiTestCase {
                //NOTE: we expect the help namespace to always contain wikitext
                return array(
                        array( 'hello world', 'Help:Hello', null, null, Revision::FOR_PUBLIC, 'hello world' ),
-                       array( serialize('hello world'), 'Hello', "testing", null, Revision::FOR_PUBLIC, serialize('hello world') ),
-                       array( serialize('hello world'), 'Dummy:Hello', null, null, Revision::FOR_PUBLIC, serialize('hello world') ),
+                       array( serialize( 'hello world' ), 'Hello', "testing", null, Revision::FOR_PUBLIC, serialize( 'hello world' ) ),
+                       array( serialize( 'hello world' ), 'Dummy:Hello', null, null, Revision::FOR_PUBLIC, serialize( 'hello world' ) ),
                );
        }
 
@@ -266,8 +266,8 @@ class RevisionTest extends MediaWikiTestCase {
                //NOTE: we expect the help namespace to always contain wikitext
                return array(
                        array( 'hello world', 'Help:Hello', null, null, Revision::FOR_PUBLIC, 'hello world' ),
-                       array( serialize('hello world'), 'Hello', "testing", null, Revision::FOR_PUBLIC, null ),
-                       array( serialize('hello world'), 'Dummy:Hello', null, null, Revision::FOR_PUBLIC, null ),
+                       array( serialize( 'hello world' ), 'Hello', "testing", null, Revision::FOR_PUBLIC, null ),
+                       array( serialize( 'hello world' ), 'Dummy:Hello', null, null, Revision::FOR_PUBLIC, null ),
                );
        }
 
@@ -296,7 +296,7 @@ class RevisionTest extends MediaWikiTestCase {
        }
 
 
-       public function dataGetSize( ) {
+       public function dataGetSize() {
                return array(
                        array( "hello world.", CONTENT_MODEL_WIKITEXT, 12 ),
                        array( serialize( "hello world." ), "testing", 12 ),
@@ -313,7 +313,7 @@ class RevisionTest extends MediaWikiTestCase {
                $this->assertEquals( $expected_size, $rev->getSize() );
        }
 
-       public function dataGetSha1( ) {
+       public function dataGetSha1() {
                return array(
                        array( "hello world.", CONTENT_MODEL_WIKITEXT, Revision::base36Sha1( "hello world." ) ),
                        array( serialize( "hello world." ), "testing", Revision::base36Sha1( serialize( "hello world." ) ) ),
@@ -334,9 +334,9 @@ class RevisionTest extends MediaWikiTestCase {
                $this->hideDeprecated( "Revision::getText" );
 
                $rev = new Revision( array(
-                                         'text' => 'hello world.',
-                                         'content_model' => CONTENT_MODEL_JAVASCRIPT
-                                    ));
+                       'text' => 'hello world.',
+                       'content_model' => CONTENT_MODEL_JAVASCRIPT
+               );
 
                $this->assertNotNull( $rev->getText(), 'no content text' );
                $this->assertNotNull( $rev->getContent(), 'no content object available' );
@@ -350,8 +350,8 @@ class RevisionTest extends MediaWikiTestCase {
                $title = Title::newFromText( 'RevisionTest_testConstructWithContent' );
 
                $rev = new Revision( array(
-                                         'content' => ContentHandler::makeContent( 'hello world.', $title, CONTENT_MODEL_JAVASCRIPT ),
-                                    ));
+                       'content' => ContentHandler::makeContent( 'hello world.', $title, CONTENT_MODEL_JAVASCRIPT ),
+               );
 
                $this->assertNotNull( $rev->getText(), 'no content text' );
                $this->assertNotNull( $rev->getContent(), 'no content object available' );
@@ -364,18 +364,18 @@ class RevisionTest extends MediaWikiTestCase {
         *
         * @group Database
         */
-       function testGetContentClone( ) {
+       function testGetContentClone() {
                $content = new RevisionTestModifyableContent( "foo" );
 
                $rev = new Revision(
                        array(
-                               'id'         => 42,
-                               'page'       => 23,
-                               'title'      => Title::newFromText( "testGetContentClone_dummy" ),
+                               'id' => 42,
+                               'page' => 23,
+                               'title' => Title::newFromText( "testGetContentClone_dummy" ),
 
-                               'content'    => $content,
-                               'length'     => $content->getSize(),
-                               'comment'    => "testing",
+                               'content' => $content,
+                               'length' => $content->getSize(),
+                               'comment' => "testing",
                                'minor_edit' => false,
                        )
                );
@@ -413,7 +413,7 @@ class RevisionTestModifyableContent extends TextContent {
                parent::__construct( $text, "RevisionTestModifyableContent" );
        }
 
-       public function copy( ) {
+       public function copy() {
                return new RevisionTestModifyableContent( $this->mText );
        }
 
@@ -429,7 +429,7 @@ class RevisionTestModifyableContent extends TextContent {
 
 class RevisionTestModifyableContentHandler extends TextContentHandler {
 
-       public function __construct( ) {
+       public function __construct() {
                parent::__construct( "RevisionTestModifyableContent", array( CONTENT_FORMAT_TEXT ) );
        }
 
index 1439e44..8a88191 100644 (file)
@@ -34,12 +34,12 @@ class TestSample extends MediaWikiLangTestCase {
         * http://www.phpunit.de/manual/3.4/en/other-uses-for-tests.html
         */
        function testTitleObjectStringConversion() {
-               $title = Title::newFromText("text");
-               $this->assertInstanceOf('Title', $title, "Title creation");
-               $this->assertEquals("Text", $title, "Automatic string conversion");
+               $title = Title::newFromText( "text" );
+               $this->assertInstanceOf( 'Title', $title, "Title creation" );
+               $this->assertEquals( "Text", $title, "Automatic string conversion" );
 
-               $title = Title::newFromText("text", NS_MEDIA);
-               $this->assertEquals("Media:Text", $title, "Title creation with namespace");
+               $title = Title::newFromText( "text", NS_MEDIA );
+               $this->assertEquals( "Media:Text", $title, "Title creation with namespace" );
        }
 
        /**
@@ -62,14 +62,14 @@ class TestSample extends MediaWikiLangTestCase {
         * @dataProvider provideTitles
         * See http://www.phpunit.de/manual/3.4/en/appendixes.annotations.html#appendixes.annotations.dataProvider
         */
-       public function testCreateBasicListOfTitles($titleName, $ns, $text) {
-               $title = Title::newFromText($titleName, $ns);
-               $this->assertEquals($text, "$title", "see if '$titleName' matches '$text'");
+       public function testCreateBasicListOfTitles( $titleName, $ns, $text ) {
+               $title = Title::newFromText( $titleName, $ns );
+               $this->assertEquals( $text, "$title", "see if '$titleName' matches '$text'" );
        }
 
        public function testSetUpMainPageTitleForNextTest() {
                $title = Title::newMainPage();
-               $this->assertEquals("Main Page", "$title", "Test initial creation of a title");
+               $this->assertEquals( "Main Page", "$title", "Test initial creation of a title" );
 
                return $title;
        }
index 2d039d9..9707f49 100644 (file)
@@ -74,9 +74,9 @@ class SanitizerTest extends MediaWikiTestCase {
                        # Enable HTML5 mode
                        'wgHtml5' => true,
                        'wgUseTidy' => false
-               ));
+               ) );
 
-               if( $escaped ) {
+               if ( $escaped ) {
                        $this->assertEquals( "&lt;$tag&gt;",
                                Sanitizer::removeHTMLtags( "<$tag>" )
                        );
@@ -91,8 +91,8 @@ class SanitizerTest extends MediaWikiTestCase {
         * Provide HTML5 tags
         */
        function provideHtml5Tags() {
-               $ESCAPED  = true; # We want tag to be escaped
-               $VERBATIM = false;  # We want to keep the tag
+               $ESCAPED = true; # We want tag to be escaped
+               $VERBATIM = false; # We want to keep the tag
                return array(
                        array( 'data', $VERBATIM ),
                        array( 'mark', $VERBATIM ),
@@ -104,7 +104,7 @@ class SanitizerTest extends MediaWikiTestCase {
        function testSelfClosingTag() {
                $this->setMwGlobals( array(
                        'wgUseTidy' => false
-               ));
+               ) );
 
                $this->assertEquals(
                        '<div>Hello world</div>',
@@ -211,18 +211,40 @@ class SanitizerTest extends MediaWikiTestCase {
                        array( ' ', "\\2f\\2a foo \\2a\\2f",
                                'Backslash-escaped comments must be stripped (bug 28450)' ),
                        array( '', '/* unfinished comment structure',
-                               'Remove anything after a comment-start token' ),
+                               'Remove anything after a comment-start token' ),
                        array( '', "\\2f\\2a unifinished comment'",
-                               'Remove anything after a backslash-escaped comment-start token' ),
-                       array( '/* insecure input */', 'filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src=\'asdf.png\',sizingMethod=\'scale\');'),
-                       array( '/* insecure input */', '-ms-filter: "progid:DXImageTransform.Microsoft.AlphaImageLoader(src=\'asdf.png\',sizingMethod=\'scale\')";'),
-                       array( '/* insecure input */', 'width: expression(1+1);'),
-                       array( '/* insecure input */', 'background-image: image(asdf.png);'),
-                       array( '/* insecure input */', 'background-image: -webkit-image(asdf.png);'),
-                       array( '/* insecure input */', 'background-image: -moz-image(asdf.png);'),
-                       array( '/* insecure input */', 'background-image: image-set("asdf.png" 1x, "asdf.png" 2x);'),
-                       array( '/* insecure input */', 'background-image: -webkit-image-set("asdf.png" 1x, "asdf.png" 2x);'),
-                       array( '/* insecure input */', 'background-image: -moz-image-set("asdf.png" 1x, "asdf.png" 2x);'),
+                               'Remove anything after a backslash-escaped comment-start token' ),
+                       array( '/* insecure input */', 'filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src=\'asdf.png\',sizingMethod=\'scale\');' ),
+                       array( '/* insecure input */', '-ms-filter: "progid:DXImageTransform.Microsoft.AlphaImageLoader(src=\'asdf.png\',sizingMethod=\'scale\')";' ),
+                       array( '/* insecure input */', 'width: expression(1+1);' ),
+                       array( '/* insecure input */', 'background-image: image(asdf.png);' ),
+                       array( '/* insecure input */', 'background-image: -webkit-image(asdf.png);' ),
+                       array( '/* insecure input */', 'background-image: -moz-image(asdf.png);' ),
+                       array( '/* insecure input */', 'background-image: image-set("asdf.png" 1x, "asdf.png" 2x);' ),
+                       array( '/* insecure input */', 'background-image: -webkit-image-set("asdf.png" 1x, "asdf.png" 2x);' ),
+                       array( '/* insecure input */', 'background-image: -moz-image-set("asdf.png" 1x, "asdf.png" 2x);' ),
                );
        }
+
+       /**
+        * Test for support or lack of support for specific attributes in the attribute whitelist.
+        */
+       function provideAttributeSupport() {
+               /** array( <attributes>, <expected>, <message> ) */
+               return array(
+                       array( 'div', ' role="presentation"', ' role="presentation"', 'Support for WAI-ARIA\'s role="presentation".' ),
+                       array( 'div', ' role="main"', '', "Other WAI-ARIA roles are currently not supported." ),
+               );
+       }
+
+       /**
+        * @dataProvider provideAttributeSupport
+        */
+       function testAttributeSupport( $tag, $attributes, $expected, $message ) {
+               $this->assertEquals( $expected,
+                       Sanitizer::fixTagAttributes( $attributes, $tag ),
+                       $message
+               );
+       }
+
 }
index 14d799c..fe0bc64 100644 (file)
@@ -2,17 +2,22 @@
 
 class SanitizerValidateEmailTest extends MediaWikiTestCase {
 
-       private function checkEmail( $addr, $expected = true, $msg = '') {
-               if( $msg == '' ) { $msg = "Testing $addr"; }
+       private function checkEmail( $addr, $expected = true, $msg = '' ) {
+               if ( $msg == '' ) {
+                       $msg = "Testing $addr";
+               }
+
                $this->assertEquals(
                        $expected,
                        Sanitizer::validateEmail( $addr ),
                        $msg
                );
        }
+
        private function valid( $addr, $msg = '' ) {
                $this->checkEmail( $addr, true, $msg );
        }
+
        private function invalid( $addr, $msg = '' ) {
                $this->checkEmail( $addr, false, $msg );
        }
@@ -21,41 +26,49 @@ class SanitizerValidateEmailTest extends MediaWikiTestCase {
                $this->valid( 'user@example.com' );
                $this->valid( 'user@example.museum' );
        }
+
        function testEmailWithUpperCaseCharactersAreValid() {
                $this->valid( 'USER@example.com' );
                $this->valid( 'user@EXAMPLE.COM' );
                $this->valid( 'user@Example.com' );
                $this->valid( 'USER@eXAMPLE.com' );
        }
+
        function testEmailWithAPlusInUserName() {
                $this->valid( 'user+sub@example.com' );
                $this->valid( 'user+@example.com' );
        }
+
        function testEmailDoesNotNeedATopLevelDomain() {
                $this->valid( "user@localhost" );
                $this->valid( "FooBar@localdomain" );
                $this->valid( "nobody@mycompany" );
        }
+
        function testEmailWithWhiteSpacesBeforeOrAfterAreInvalids() {
                $this->invalid( " user@host.com" );
                $this->invalid( "user@host.com " );
                $this->invalid( "\tuser@host.com" );
                $this->invalid( "user@host.com\t" );
        }
+
        function testEmailWithWhiteSpacesAreInvalids() {
                $this->invalid( "User user@host" );
                $this->invalid( "first last@mycompany" );
                $this->invalid( "firstlast@my company" );
        }
+
        // bug 26948 : comma were matched by an incorrect regexp range
        function testEmailWithCommasAreInvalids() {
                $this->invalid( "user,foo@example.org" );
                $this->invalid( "userfoo@ex,ample.org" );
        }
+
        function testEmailWithHyphens() {
                $this->valid( "user-foo@example.org" );
                $this->valid( "userfoo@ex-ample.org" );
        }
+
        function testEmailDomainCanNotBeginWithDot() {
                $this->invalid( "user@." );
                $this->invalid( "user@.localdomain" );
@@ -64,15 +77,19 @@ class SanitizerValidateEmailTest extends MediaWikiTestCase {
                $this->valid( ".@localdomain" );
                $this->invalid( ".@a............" );
        }
+
        function testEmailWithFunnyCharacters() {
                $this->valid( "\$user!ex{this}@123.com" );
        }
+
        function testEmailTopLevelDomainCanBeNumerical() {
                $this->valid( "user@example.1234" );
        }
+
        function testEmailWithoutAtSignIsInvalid() {
                $this->invalid( 'useràexample.com' );
        }
+
        function testEmailWithOneCharacterDomainIsValid() {
                $this->valid( 'user@a' );
        }
index 3989fad..3422c90 100644 (file)
@@ -11,8 +11,7 @@ class SeleniumConfigurationTest extends MediaWikiTestCase {
        /**
         * String containing the a sample selenium settings
         */
-       private $testConfig0 =
-'
+       private $testConfig0 = '
 [SeleniumSettings]
 browsers[firefox]      = "*firefox"
 browsers[iexplorer] = "*iexploreproxy"
@@ -35,20 +34,20 @@ testSuite[TestSuiteName] = "testSuitePath"
        /**
         * Array of expected browsers from $testConfig0
         */
-       private $testBrowsers0 = array( 'firefox' => '*firefox',
-                                                       'iexplorer' => '*iexploreproxy',
-                                                       'chrome' => '*chrome'
+       private $testBrowsers0 = array( 'firefox' => '*firefox',
+               'iexplorer' => '*iexploreproxy',
+               'chrome' => '*chrome'
        );
        /**
         * Array of expected selenium settings from $testConfig0
         */
        private $testSettings0 = array(
-               'host'                  => 'localhost',
-               'port'                  => 'foobarr',
-               'wikiUrl'               => 'http://localhost/deployment',
-               'username'              => 'xxxxxxx',
-               'userPassword'  => '',
-               'testBrowser'   => 'chrome',
+               'host' => 'localhost',
+               'port' => 'foobarr',
+               'wikiUrl' => 'http://localhost/deployment',
+               'username' => 'xxxxxxx',
+               'userPassword' => '',
+               'testBrowser' => 'chrome',
                'startserver' => null,
                'stopserver' => null,
                'seleniumserverexecpath' => null,
@@ -59,16 +58,15 @@ testSuite[TestSuiteName] = "testSuitePath"
         * Array of expected testSuites from $testConfig0
         */
        private $testSuites0 = array(
-               'SimpleSeleniumTestSuite'       => 'tests/selenium/SimpleSeleniumTestSuite.php',
-               'TestSuiteName'                         => 'testSuitePath'
+               'SimpleSeleniumTestSuite' => 'tests/selenium/SimpleSeleniumTestSuite.php',
+               'TestSuiteName' => 'testSuitePath'
        );
 
-
        /**
         * Another sample selenium settings file contents
         */
        private $testConfig1 =
-'
+               '
 [SeleniumSettings]
 host                           = "localhost"
 testBrowser            = "firefox"
@@ -81,12 +79,12 @@ testBrowser                 = "firefox"
         * Expected selenium settings from $testConfig1
         */
        private $testSettings1 = array(
-               'host'                  => 'localhost',
-               'port'                  => null,
-               'wikiUrl'               => null,
-               'username'              => null,
-               'userPassword'  => null,
-               'testBrowser'   => 'firefox',
+               'host' => 'localhost',
+               'port' => null,
+               'wikiUrl' => null,
+               'username' => null,
+               'userPassword' => null,
+               'testBrowser' => 'firefox',
                'startserver' => null,
                'stopserver' => null,
                'seleniumserverexecpath' => null,
@@ -126,11 +124,10 @@ testBrowser               = "firefox"
                $seleniumBrowsers = array();
                $seleniumTestSuites = array();
 
-               SeleniumConfig::getSeleniumSettings($seleniumSettings,
+               SeleniumConfig::getSeleniumSettings( $seleniumSettings,
                        $seleniumBrowsers,
                        $seleniumTestSuites,
                        "Some_fake_settings_file.ini" );
-
        }
 
        /**
@@ -143,9 +140,9 @@ testBrowser                 = "firefox"
                $seleniumTestSuites = array();
                global $wgSeleniumConfigFile;
                $wgSeleniumConfigFile = '';
-               SeleniumConfig::getSeleniumSettings($seleniumSettings,
+               SeleniumConfig::getSeleniumSettings( $seleniumSettings,
                        $seleniumBrowsers,
-                       $seleniumTestSuites);
+                       $seleniumTestSuites );
        }
 
        /**
@@ -158,17 +155,17 @@ testBrowser               = "firefox"
                global $wgSeleniumConfigFile;
                $this->writeToTempFile( $this->testConfig0 );
                $wgSeleniumConfigFile = $this->tempFileName;
-               SeleniumConfig::getSeleniumSettings($seleniumSettings,
+               SeleniumConfig::getSeleniumSettings( $seleniumSettings,
                        $seleniumBrowsers,
-                       $seleniumTestSuites);
-               $this->assertEquals($seleniumSettings, $this->testSettings0,
-               'The selenium settings should have been read from the file defined in $wgSeleniumConfigFile'
+                       $seleniumTestSuites );
+               $this->assertEquals( $seleniumSettings, $this->testSettings0,
+                       'The selenium settings should have been read from the file defined in $wgSeleniumConfigFile'
                );
-               $this->assertEquals($seleniumBrowsers, $this->testBrowsers0,
-               'The available browsers should have been read from the file defined in $wgSeleniumConfigFile'
+               $this->assertEquals( $seleniumBrowsers, $this->testBrowsers0,
+                       'The available browsers should have been read from the file defined in $wgSeleniumConfigFile'
                );
-               $this->assertEquals($seleniumTestSuites, $this->testSuites0,
-               'The test suites should have been read from the file defined in $wgSeleniumConfigFile'
+               $this->assertEquals( $seleniumTestSuites, $this->testSuites0,
+                       'The test suites should have been read from the file defined in $wgSeleniumConfigFile'
                );
        }
 
@@ -176,54 +173,50 @@ testBrowser               = "firefox"
         * @group SeleniumFramework
         * @dataProvider sampleConfigs
         */
-       public function testgetSeleniumSettings($sampleConfig, $expectedSettings, $expectedBrowsers, $expectedSuites ) {
+       public function testgetSeleniumSettings( $sampleConfig, $expectedSettings, $expectedBrowsers, $expectedSuites ) {
                $this->writeToTempFile( $sampleConfig );
                $seleniumSettings = array();
                $seleniumBrowsers = array();
                $seleniumTestSuites = null;
 
-               SeleniumConfig::getSeleniumSettings($seleniumSettings,
+               SeleniumConfig::getSeleniumSettings( $seleniumSettings,
                        $seleniumBrowsers,
                        $seleniumTestSuites,
                        $this->tempFileName );
 
-               $this->assertEquals($seleniumSettings, $expectedSettings,
-               "The selenium settings for the following test configuration was not retrieved correctly" . $sampleConfig
+               $this->assertEquals( $seleniumSettings, $expectedSettings,
+                       "The selenium settings for the following test configuration was not retrieved correctly" . $sampleConfig
                );
-               $this->assertEquals($seleniumBrowsers, $expectedBrowsers,
-               "The available browsers for the following test configuration was not retrieved correctly" . $sampleConfig
+               $this->assertEquals( $seleniumBrowsers, $expectedBrowsers,
+                       "The available browsers for the following test configuration was not retrieved correctly" . $sampleConfig
                );
-               $this->assertEquals($seleniumTestSuites, $expectedSuites,
-               "The test suites for the following test configuration was not retrieved correctly" . $sampleConfig
+               $this->assertEquals( $seleniumTestSuites, $expectedSuites,
+                       "The test suites for the following test configuration was not retrieved correctly" . $sampleConfig
                );
-
-
        }
 
        /**
         * create a temp file and write text to it.
         * @param $testToWrite the text to write to the temp file
         */
-       private function writeToTempFile($textToWrite) {
-               $this->tempFileName = tempnam(sys_get_temp_dir(), 'test_settings.');
-               $tempFile =      fopen( $this->tempFileName, "w" );
-               fwrite($tempFile, $textToWrite);
-               fclose($tempFile);
+       private function writeToTempFile( $textToWrite ) {
+               $this->tempFileName = tempnam( sys_get_temp_dir(), 'test_settings.' );
+               $tempFile = fopen( $this->tempFileName, "w" );
+               fwrite( $tempFile, $textToWrite );
+               fclose( $tempFile );
        }
 
        /**
         * Returns an array containing:
-        *      The contents of the selenium cingiguration ini file
+        *     The contents of the selenium cingiguration ini file
         *  The expected selenium configuration array that getSeleniumSettings should return
         *  The expected available browsers array that getSeleniumSettings should return
         *  The expected test suites arrya that getSeleniumSettings should return
         */
        public function sampleConfigs() {
                return array(
-                       array($this->testConfig0, $this->testSettings0, $this->testBrowsers0, $this->testSuites0 ),
-                       array($this->testConfig1, $this->testSettings1, $this->testBrowsers1, $this->testSuites1 )
+                       array( $this->testConfig0, $this->testSettings0, $this->testBrowsers0, $this->testSuites0 ),
+                       array( $this->testConfig1, $this->testSettings1, $this->testBrowsers1, $this->testSuites1 )
                );
        }
-
-
 }
index 401b322..ae003ae 100644 (file)
@@ -9,8 +9,8 @@ class StringUtilsTest extends MediaWikiTestCase {
         * @cover StringUtils::isUtf8
         * @dataProvider provideStringsForIsUtf8Check
         */
-       function testIsUtf8WithMbstring($expected, $string ) {
-               if( !function_exists( 'mb_check_encoding' ) ) {
+       function testIsUtf8WithMbstring( $expected, $string ) {
+               if ( !function_exists( 'mb_check_encoding' ) ) {
                        $this->markTestSkipped( 'Test requires the mbstring PHP extension' );
                }
                $this->assertEquals( $expected,
@@ -27,7 +27,7 @@ class StringUtilsTest extends MediaWikiTestCase {
         * @cover StringUtils::isUtf8
         * @dataProvider provideStringsForIsUtf8Check
         */
-       function testIsUtf8WithPhpFallbackImplementation($expected, $string ) {
+       function testIsUtf8WithPhpFallbackImplementation( $expected, $string ) {
                $this->assertEquals( $expected,
                        StringUtils::isUtf8( $string, /** disable mbstring: */ true ),
                        'Testing string "' . $this->escaped( $string ) . '" with pure PHP implementation'
@@ -39,11 +39,11 @@ class StringUtilsTest extends MediaWikiTestCase {
         */
        function escaped( $string ) {
                $escaped = '';
-               for($i=0; $i<strlen($string);$i++) {
+               for ( $i = 0; $i < strlen( $string ); $i++ ) {
                        $char = $string[$i];
-                       $val = ord($char);
-                       if( $val > 127 ) {
-                               $escaped .='\x' . dechex($val);
+                       $val = ord( $char );
+                       if ( $val > 127 ) {
+                               $escaped .= '\x' . dechex( $val );
                        } else {
                                $escaped .= $char;
                        }
index 07ce84b..a58702b 100644 (file)
@@ -20,14 +20,14 @@ class TimeAdjustTest extends MediaWikiLangTestCase {
                #  Collection of parameters for Language_t_Offset.
                # Format: date to be formatted, localTZoffset value, expected date
                $userAdjust_tests = array(
-                       array( 20061231235959,   0, 20061231235959 ),
-                       array( 20061231235959,   5, 20070101000459 ),
-                       array( 20061231235959,  15, 20070101001459 ),
-                       array( 20061231235959,  60, 20070101005959 ),
-                       array( 20061231235959,  90, 20070101012959 ),
+                       array( 20061231235959, 0, 20061231235959 ),
+                       array( 20061231235959, 5, 20070101000459 ),
+                       array( 20061231235959, 15, 20070101001459 ),
+                       array( 20061231235959, 60, 20070101005959 ),
+                       array( 20061231235959, 90, 20070101012959 ),
                        array( 20061231235959, 120, 20070101015959 ),
                        array( 20061231235959, 540, 20070101085959 ),
-                       array( 20061231235959,  -5, 20061231235459 ),
+                       array( 20061231235959, -5, 20061231235459 ),
                        array( 20061231235959, -30, 20061231232959 ),
                        array( 20061231235959, -60, 20061231225959 ),
                );
index de2f855..91c23ec 100644 (file)
@@ -14,6 +14,7 @@ class TimestampTest extends MediaWikiTestCase {
                        'wgLang' => Language::factory( 'en' ),
                ) );
        }
+
        /**
         * Test parsing of valid timestamps and outputing to MW format.
         * @dataProvider provideValidTimestamps
index 05f1408..e2c079a 100644 (file)
@@ -116,7 +116,7 @@ class TitlePermissionTest extends MediaWikiLangTestCase {
                $this->setTitle( NS_MAIN );
                $this->setUserPerm( "createpage" );
                $res = $this->title->getUserPermissionsErrors( 'create', $this->user );
-               $this->assertEquals( array( ), $res );
+               $this->assertEquals( array(), $res );
 
                $this->setTitle( NS_MAIN );
                $this->setUserPerm( "createtalk" );
@@ -127,7 +127,7 @@ class TitlePermissionTest extends MediaWikiLangTestCase {
                $this->setTitle( NS_TALK );
                $this->setUserPerm( "createtalk" );
                $res = $this->title->getUserPermissionsErrors( 'create', $this->user );
-               $this->assertEquals( array( ), $res );
+               $this->assertEquals( array(), $res );
 
                $this->setTitle( NS_TALK );
                $this->setUserPerm( "createpage" );
@@ -142,7 +142,7 @@ class TitlePermissionTest extends MediaWikiLangTestCase {
                $this->setTitle( NS_MAIN );
                $this->setUserPerm( "createpage" );
                $res = $this->title->getUserPermissionsErrors( 'create', $this->user );
-               $this->assertEquals( array( ), $res );
+               $this->assertEquals( array(), $res );
 
                $this->setTitle( NS_MAIN );
                $this->setUserPerm( "createtalk" );
@@ -239,7 +239,7 @@ class TitlePermissionTest extends MediaWikiLangTestCase {
                        $this->setTitle( NS_MAIN );
                        $this->setUser( 'anon' );
                        $this->setUserPerm( "move" );
-                       $this->runGroupPermissions( 'move', array(  ) );
+                       $this->runGroupPermissions( 'move', array() );
 
                        $this->setUserPerm( "" );
                        $this->runGroupPermissions( 'move', array( array( 'movenotallowed' ) ),
@@ -250,12 +250,12 @@ class TitlePermissionTest extends MediaWikiLangTestCase {
                        $this->runGroupPermissions( 'move', array( array( 'movenotallowed' ) ) );
 
                        $this->setUserPerm( "move" );
-                       $this->runGroupPermissions( 'move', array( ) );
+                       $this->runGroupPermissions( 'move', array() );
 
                        $this->setUser( 'anon' );
                        $this->setUserPerm( 'move' );
                        $res = $this->title->getUserPermissionsErrors( 'move-target', $this->user );
-                       $this->assertEquals( array( ), $res );
+                       $this->assertEquals( array(), $res );
 
                        $this->setUserPerm( '' );
                        $res = $this->title->getUserPermissionsErrors( 'move-target', $this->user );
@@ -266,7 +266,7 @@ class TitlePermissionTest extends MediaWikiLangTestCase {
                $this->setUser( $this->userName );
                $this->setUserPerm( array( "move", "move-rootuserpages" ) );
                $res = $this->title->getUserPermissionsErrors( 'move-target', $this->user );
-               $this->assertEquals( array( ), $res );
+               $this->assertEquals( array(), $res );
 
                $this->setUserPerm( "move" );
                $res = $this->title->getUserPermissionsErrors( 'move-target', $this->user );
@@ -275,25 +275,25 @@ class TitlePermissionTest extends MediaWikiLangTestCase {
                $this->setUser( 'anon' );
                $this->setUserPerm( array( "move", "move-rootuserpages" ) );
                $res = $this->title->getUserPermissionsErrors( 'move-target', $this->user );
-               $this->assertEquals( array( ), $res );
+               $this->assertEquals( array(), $res );
 
                $this->setTitle( NS_USER, "User/subpage" );
                $this->setUserPerm( array( "move", "move-rootuserpages" ) );
                $res = $this->title->getUserPermissionsErrors( 'move-target', $this->user );
-               $this->assertEquals( array( ), $res );
+               $this->assertEquals( array(), $res );
 
                $this->setUserPerm( "move" );
                $res = $this->title->getUserPermissionsErrors( 'move-target', $this->user );
-               $this->assertEquals( array( ), $res );
+               $this->assertEquals( array(), $res );
 
                $this->setUser( 'anon' );
                $check = array( 'edit' => array( array( array( 'badaccess-groups', "*, [[$prefix:Users|Users]]", 2 ) ),
-                                                                                array( array( 'badaccess-group0' ) ),
-                                                                                array( ), true ),
-                                               'protect' => array( array( array( 'badaccess-groups', "[[$prefix:Administrators|Administrators]]", 1 ), array( 'protect-cantedit' ) ),
-                                                                                       array( array( 'badaccess-group0' ), array( 'protect-cantedit' ) ),
-                                                                                       array( array( 'protect-cantedit' ) ), false ),
-                                               '' => array( array( ), array( ), array( ), true ) );
+                       array( array( 'badaccess-group0' ) ),
+                       array(), true ),
+                       'protect' => array( array( array( 'badaccess-groups', "[[$prefix:Administrators|Administrators]]", 1 ), array( 'protect-cantedit' ) ),
+                               array( array( 'badaccess-group0' ), array( 'protect-cantedit' ) ),
+                               array( array( 'protect-cantedit' ) ), false ),
+                       '' => array( array(), array(), array(), true ) );
 
                foreach ( array( "edit", "protect", "" ) as $action ) {
                        $this->setUserPerm( null );
@@ -325,7 +325,9 @@ class TitlePermissionTest extends MediaWikiLangTestCase {
        function runGroupPermissions( $action, $result, $result2 = null ) {
                global $wgGroupPermissions;
 
-               if ( $result2 === null ) $result2 = $result;
+               if ( $result2 === null ) {
+                       $result2 = $result;
+               }
 
                $wgGroupPermissions['autoconfirmed']['move'] = false;
                $wgGroupPermissions['user']['move'] = false;
@@ -355,48 +357,48 @@ class TitlePermissionTest extends MediaWikiLangTestCase {
                $this->setTitle( NS_SPECIAL );
 
                $this->assertEquals( array( array( 'badaccess-group0' ), array( 'ns-specialprotected' ) ),
-                                                        $this->title->getUserPermissionsErrors( 'bogus', $this->user ) );
+                       $this->title->getUserPermissionsErrors( 'bogus', $this->user ) );
 
                $this->setTitle( NS_MAIN );
                $this->setUserPerm( 'bogus' );
-               $this->assertEquals( array( ),
-                                                        $this->title->getUserPermissionsErrors( 'bogus', $this->user ) );
+               $this->assertEquals( array(),
+                       $this->title->getUserPermissionsErrors( 'bogus', $this->user ) );
 
                $this->setTitle( NS_MAIN );
                $this->setUserPerm( '' );
                $this->assertEquals( array( array( 'badaccess-group0' ) ),
-                                                        $this->title->getUserPermissionsErrors( 'bogus', $this->user ) );
+                       $this->title->getUserPermissionsErrors( 'bogus', $this->user ) );
 
                $wgNamespaceProtection[NS_USER] = array( 'bogus' );
 
                $this->setTitle( NS_USER );
                $this->setUserPerm( '' );
                $this->assertEquals( array( array( 'badaccess-group0' ), array( 'namespaceprotected', 'User' ) ),
-                                                        $this->title->getUserPermissionsErrors( 'bogus', $this->user ) );
+                       $this->title->getUserPermissionsErrors( 'bogus', $this->user ) );
 
                $this->setTitle( NS_MEDIAWIKI );
                $this->setUserPerm( 'bogus' );
                $this->assertEquals( array( array( 'protectedinterface' ) ),
-                                                        $this->title->getUserPermissionsErrors( 'bogus', $this->user ) );
+                       $this->title->getUserPermissionsErrors( 'bogus', $this->user ) );
 
                $this->setTitle( NS_MEDIAWIKI );
                $this->setUserPerm( 'bogus' );
                $this->assertEquals( array( array( 'protectedinterface' ) ),
-                                                        $this->title->getUserPermissionsErrors( 'bogus', $this->user ) );
+                       $this->title->getUserPermissionsErrors( 'bogus', $this->user ) );
 
                $wgNamespaceProtection = null;
 
                $this->setUserPerm( 'bogus' );
-               $this->assertEquals( array( ),
-                                                        $this->title->getUserPermissionsErrors( 'bogus', $this->user ) );
+               $this->assertEquals( array(),
+                       $this->title->getUserPermissionsErrors( 'bogus', $this->user ) );
                $this->assertEquals( true,
-                                                        $this->title->userCan( 'bogus', $this->user ) );
+                       $this->title->userCan( 'bogus', $this->user ) );
 
                $this->setUserPerm( '' );
                $this->assertEquals( array( array( 'badaccess-group0' ) ),
-                                                        $this->title->getUserPermissionsErrors( 'bogus', $this->user ) );
+                       $this->title->getUserPermissionsErrors( 'bogus', $this->user ) );
                $this->assertEquals( false,
-                                                        $this->title->userCan( 'bogus', $this->user ) );
+                       $this->title->userCan( 'bogus', $this->user ) );
        }
 
        function testCssAndJavascriptPermissions() {
@@ -412,7 +414,7 @@ class TitlePermissionTest extends MediaWikiLangTestCase {
                $this->runCSSandJSPermissions(
                        array( array( 'badaccess-group0' ), array( 'customcssprotected' ) ),
                        array( array( 'badaccess-group0' ) ),
-                       array( array( 'badaccess-group0' ),  array( 'customcssprotected' ) ) );
+                       array( array( 'badaccess-group0' ), array( 'customcssprotected' ) ) );
 
                $this->setTitle( NS_USER, $this->altUserName . '/tempo' );
                $this->runCSSandJSPermissions(
@@ -424,28 +426,28 @@ class TitlePermissionTest extends MediaWikiLangTestCase {
        function runCSSandJSPermissions( $result0, $result1, $result2 ) {
                $this->setUserPerm( '' );
                $this->assertEquals( $result0,
-                                                        $this->title->getUserPermissionsErrors( 'bogus',
-                                                                                                                                        $this->user ) );
+                       $this->title->getUserPermissionsErrors( 'bogus',
+                               $this->user ) );
 
                $this->setUserPerm( 'editusercss' );
                $this->assertEquals( $result1,
-                                                        $this->title->getUserPermissionsErrors( 'bogus',
-                                                                                                                                        $this->user ) );
+                       $this->title->getUserPermissionsErrors( 'bogus',
+                               $this->user ) );
 
                $this->setUserPerm( 'edituserjs' );
                $this->assertEquals( $result2,
-                                                        $this->title->getUserPermissionsErrors( 'bogus',
-                                                                                                                                        $this->user ) );
+                       $this->title->getUserPermissionsErrors( 'bogus',
+                               $this->user ) );
 
                $this->setUserPerm( 'editusercssjs' );
                $this->assertEquals( array( array( 'badaccess-group0' ) ),
-                                                        $this->title->getUserPermissionsErrors( 'bogus',
-                                                                                                                                        $this->user ) );
+                       $this->title->getUserPermissionsErrors( 'bogus',
+                               $this->user ) );
 
                $this->setUserPerm( array( 'edituserjs', 'editusercss' ) );
                $this->assertEquals( array( array( 'badaccess-group0' ) ),
-                                                        $this->title->getUserPermissionsErrors( 'bogus',
-                                                                                                                                        $this->user ) );
+                       $this->title->getUserPermissionsErrors( 'bogus',
+                               $this->user ) );
        }
 
        function testPageRestrictions() {
@@ -458,65 +460,65 @@ class TitlePermissionTest extends MediaWikiLangTestCase {
                $this->setUserPerm( "edit" );
                $this->title->mRestrictions = array( "bogus" => array( 'bogus', "sysop", "protect", "" ) );
 
-               $this->assertEquals( array( ),
-                                                        $this->title->getUserPermissionsErrors( 'edit',
-                                                                                                                                        $this->user ) );
+               $this->assertEquals( array(),
+                       $this->title->getUserPermissionsErrors( 'edit',
+                               $this->user ) );
 
                $this->assertEquals( true,
-                                                        $this->title->quickUserCan( 'edit', $this->user ) );
+                       $this->title->quickUserCan( 'edit', $this->user ) );
                $this->title->mRestrictions = array( "edit" => array( 'bogus', "sysop", "protect", "" ),
-                                                                                  "bogus" => array( 'bogus', "sysop", "protect", "" ) );
+                       "bogus" => array( 'bogus', "sysop", "protect", "" ) );
 
                $this->assertEquals( array( array( 'badaccess-group0' ),
-                                                                       array( 'protectedpagetext', 'bogus' ),
-                                                                       array( 'protectedpagetext', 'protect' ),
-                                                                       array( 'protectedpagetext', 'protect' ) ),
-                                                        $this->title->getUserPermissionsErrors( 'bogus',
-                                                                                                                                        $this->user ) );
+                               array( 'protectedpagetext', 'bogus' ),
+                               array( 'protectedpagetext', 'protect' ),
+                               array( 'protectedpagetext', 'protect' ) ),
+                       $this->title->getUserPermissionsErrors( 'bogus',
+                               $this->user ) );
                $this->assertEquals( array( array( 'protectedpagetext', 'bogus' ),
-                                                                       array( 'protectedpagetext', 'protect' ),
-                                                                       array( 'protectedpagetext', 'protect' ) ),
-                                                        $this->title->getUserPermissionsErrors( 'edit',
-                                                                                                                                        $this->user ) );
+                               array( 'protectedpagetext', 'protect' ),
+                               array( 'protectedpagetext', 'protect' ) ),
+                       $this->title->getUserPermissionsErrors( 'edit',
+                               $this->user ) );
                $this->setUserPerm( "" );
                $this->assertEquals( array( array( 'badaccess-group0' ),
-                                                                       array( 'protectedpagetext', 'bogus' ),
-                                                                       array( 'protectedpagetext', 'protect' ),
-                                                                       array( 'protectedpagetext', 'protect' ) ),
-                                                        $this->title->getUserPermissionsErrors( 'bogus',
-                                                                                                                                        $this->user ) );
+                               array( 'protectedpagetext', 'bogus' ),
+                               array( 'protectedpagetext', 'protect' ),
+                               array( 'protectedpagetext', 'protect' ) ),
+                       $this->title->getUserPermissionsErrors( 'bogus',
+                               $this->user ) );
                $this->assertEquals( array( array( 'badaccess-groups', "*, [[$prefix:Users|Users]]", 2 ),
-                                                                       array( 'protectedpagetext', 'bogus' ),
-                                                                       array( 'protectedpagetext', 'protect' ),
-                                                                       array( 'protectedpagetext', 'protect' ) ),
-                                                        $this->title->getUserPermissionsErrors( 'edit',
-                                                                                                                                        $this->user ) );
+                               array( 'protectedpagetext', 'bogus' ),
+                               array( 'protectedpagetext', 'protect' ),
+                               array( 'protectedpagetext', 'protect' ) ),
+                       $this->title->getUserPermissionsErrors( 'edit',
+                               $this->user ) );
                $this->setUserPerm( array( "edit", "editprotected" ) );
                $this->assertEquals( array( array( 'badaccess-group0' ),
-                                                                       array( 'protectedpagetext', 'bogus' ),
-                                                                       array( 'protectedpagetext', 'protect' ),
-                                                                       array( 'protectedpagetext', 'protect' ) ),
-                                                        $this->title->getUserPermissionsErrors( 'bogus',
-                                                                                                                                        $this->user ) );
-               $this->assertEquals( array(  ),
-                                                        $this->title->getUserPermissionsErrors( 'edit',
-                                                                                                                                        $this->user ) );
+                               array( 'protectedpagetext', 'bogus' ),
+                               array( 'protectedpagetext', 'protect' ),
+                               array( 'protectedpagetext', 'protect' ) ),
+                       $this->title->getUserPermissionsErrors( 'bogus',
+                               $this->user ) );
+               $this->assertEquals( array(),
+                       $this->title->getUserPermissionsErrors( 'edit',
+                               $this->user ) );
                $this->title->mCascadeRestriction = true;
                $this->assertEquals( false,
-                                                        $this->title->quickUserCan( 'bogus', $this->user ) );
+                       $this->title->quickUserCan( 'bogus', $this->user ) );
                $this->assertEquals( false,
-                                                        $this->title->quickUserCan( 'edit', $this->user ) );
+                       $this->title->quickUserCan( 'edit', $this->user ) );
                $this->assertEquals( array( array( 'badaccess-group0' ),
-                                                                       array( 'protectedpagetext', 'bogus' ),
-                                                                       array( 'protectedpagetext', 'protect' ),
-                                                                       array( 'protectedpagetext', 'protect' ) ),
-                                                        $this->title->getUserPermissionsErrors( 'bogus',
-                                                                                                                                        $this->user ) );
+                               array( 'protectedpagetext', 'bogus' ),
+                               array( 'protectedpagetext', 'protect' ),
+                               array( 'protectedpagetext', 'protect' ) ),
+                       $this->title->getUserPermissionsErrors( 'bogus',
+                               $this->user ) );
                $this->assertEquals( array( array( 'protectedpagetext', 'bogus' ),
-                                                                       array( 'protectedpagetext', 'protect' ),
-                                                                       array( 'protectedpagetext', 'protect' ) ),
-                                                        $this->title->getUserPermissionsErrors( 'edit',
-                                                                                                                                        $this->user ) );
+                               array( 'protectedpagetext', 'protect' ),
+                               array( 'protectedpagetext', 'protect' ) ),
+                       $this->title->getUserPermissionsErrors( 'edit',
+                               $this->user ) );
        }
 
        function testCascadingSourcesRestrictions() {
@@ -527,15 +529,15 @@ class TitlePermissionTest extends MediaWikiLangTestCase {
                $this->title->mCascadingRestrictions = array( "bogus" => array( 'bogus', "sysop", "protect", "" ) );
 
                $this->assertEquals( false,
-                                                        $this->title->userCan( 'bogus', $this->user ) );
+                       $this->title->userCan( 'bogus', $this->user ) );
                $this->assertEquals( array( array( "cascadeprotected", 2, "* [[:Bogus]]\n* [[:UnBogus]]\n" ),
-                                                                       array( "cascadeprotected", 2, "* [[:Bogus]]\n* [[:UnBogus]]\n" ) ),
-                                                        $this->title->getUserPermissionsErrors( 'bogus', $this->user ) );
+                               array( "cascadeprotected", 2, "* [[:Bogus]]\n* [[:UnBogus]]\n" ) ),
+                       $this->title->getUserPermissionsErrors( 'bogus', $this->user ) );
 
                $this->assertEquals( true,
-                                                        $this->title->userCan( 'edit', $this->user ) );
-               $this->assertEquals( array( ),
-                                                        $this->title->getUserPermissionsErrors( 'edit', $this->user ) );
+                       $this->title->userCan( 'edit', $this->user ) );
+               $this->assertEquals( array(),
+                       $this->title->getUserPermissionsErrors( 'edit', $this->user ) );
 
        }
 
@@ -549,60 +551,60 @@ class TitlePermissionTest extends MediaWikiLangTestCase {
                $this->title->mCascadeRestriction = false;
 
                $this->assertEquals( array( array( 'titleprotected', 'Useruser', 'test' ) ),
-                                                        $this->title->getUserPermissionsErrors( 'create', $this->user ) );
+                       $this->title->getUserPermissionsErrors( 'create', $this->user ) );
                $this->assertEquals( false,
-                                                        $this->title->userCan( 'create', $this->user ) );
+                       $this->title->userCan( 'create', $this->user ) );
 
                $this->title->mTitleProtection['pt_create_perm'] = 'sysop';
                $this->setUserPerm( array( 'createpage', 'protect' ) );
-               $this->assertEquals( array( ),
-                                                        $this->title->getUserPermissionsErrors( 'create', $this->user ) );
+               $this->assertEquals( array(),
+                       $this->title->getUserPermissionsErrors( 'create', $this->user ) );
                $this->assertEquals( true,
-                                                        $this->title->userCan( 'create', $this->user ) );
+                       $this->title->userCan( 'create', $this->user ) );
 
 
                $this->setUserPerm( array( 'createpage' ) );
                $this->assertEquals( array( array( 'titleprotected', 'Useruser', 'test' ) ),
-                                                        $this->title->getUserPermissionsErrors( 'create', $this->user ) );
+                       $this->title->getUserPermissionsErrors( 'create', $this->user ) );
                $this->assertEquals( false,
-                                                        $this->title->userCan( 'create', $this->user ) );
+                       $this->title->userCan( 'create', $this->user ) );
 
                $this->setTitle( NS_MEDIA, "test page" );
                $this->setUserPerm( array( "move" ) );
                $this->assertEquals( false,
-                                                        $this->title->userCan( 'move', $this->user ) );
+                       $this->title->userCan( 'move', $this->user ) );
                $this->assertEquals( array( array( 'immobile-source-namespace', 'Media' ) ),
-                                                        $this->title->getUserPermissionsErrors( 'move', $this->user ) );
+                       $this->title->getUserPermissionsErrors( 'move', $this->user ) );
 
                $this->setTitle( NS_HELP, "test page" );
-               $this->assertEquals( array( ),
-                                                        $this->title->getUserPermissionsErrors( 'move', $this->user ) );
+               $this->assertEquals( array(),
+                       $this->title->getUserPermissionsErrors( 'move', $this->user ) );
                $this->assertEquals( true,
-                                                        $this->title->userCan( 'move', $this->user ) );
+                       $this->title->userCan( 'move', $this->user ) );
 
                $this->title->mInterwiki = "no";
                $this->assertEquals( array( array( 'immobile-source-page' ) ),
-                                                        $this->title->getUserPermissionsErrors( 'move', $this->user ) );
+                       $this->title->getUserPermissionsErrors( 'move', $this->user ) );
                $this->assertEquals( false,
-                                                        $this->title->userCan( 'move', $this->user ) );
+                       $this->title->userCan( 'move', $this->user ) );
 
                $this->setTitle( NS_MEDIA, "test page" );
                $this->assertEquals( false,
-                                                        $this->title->userCan( 'move-target', $this->user ) );
+                       $this->title->userCan( 'move-target', $this->user ) );
                $this->assertEquals( array( array( 'immobile-target-namespace', 'Media' ) ),
-                                                        $this->title->getUserPermissionsErrors( 'move-target', $this->user ) );
+                       $this->title->getUserPermissionsErrors( 'move-target', $this->user ) );
 
                $this->setTitle( NS_HELP, "test page" );
-               $this->assertEquals( array( ),
-                                                        $this->title->getUserPermissionsErrors( 'move-target', $this->user ) );
+               $this->assertEquals( array(),
+                       $this->title->getUserPermissionsErrors( 'move-target', $this->user ) );
                $this->assertEquals( true,
-                                                        $this->title->userCan( 'move-target', $this->user ) );
+                       $this->title->userCan( 'move-target', $this->user ) );
 
                $this->title->mInterwiki = "no";
                $this->assertEquals( array( array( 'immobile-target-page' ) ),
-                                                        $this->title->getUserPermissionsErrors( 'move-target', $this->user ) );
+                       $this->title->getUserPermissionsErrors( 'move-target', $this->user ) );
                $this->assertEquals( false,
-                                                        $this->title->userCan( 'move-target', $this->user ) );
+                       $this->title->userCan( 'move-target', $this->user ) );
 
        }
 
@@ -616,28 +618,28 @@ class TitlePermissionTest extends MediaWikiLangTestCase {
 
                # $short
                $this->assertEquals( array( array( 'confirmedittext' ) ),
-                                                        $this->title->getUserPermissionsErrors( 'move-target', $this->user ) );
+                       $this->title->getUserPermissionsErrors( 'move-target', $this->user ) );
                $wgEmailConfirmToEdit = false;
                $this->assertEquals( true, $this->title->userCan( 'move-target', $this->user ) );
 
                # $wgEmailConfirmToEdit && !$user->isEmailConfirmed() && $action != 'createaccount'
-               $this->assertEquals( array( ),
-                                                        $this->title->getUserPermissionsErrors( 'move-target',
-                       $this->user ) );
+               $this->assertEquals( array(),
+                       $this->title->getUserPermissionsErrors( 'move-target',
+                               $this->user ) );
 
                global $wgLang;
                $prev = time();
                $now = time() + 120;
                $this->user->mBlockedby = $this->user->getId();
                $this->user->mBlock = new Block( '127.0.8.1', 0, $this->user->getId(),
-                                                                               'no reason given', $prev + 3600, 1, 0 );
+                       'no reason given', $prev + 3600, 1, 0 );
                $this->user->mBlock->mTimestamp = 0;
                $this->assertEquals( array( array( 'autoblockedtext',
-                       '[[User:Useruser|Useruser]]', 'no reason given', '127.0.0.1',
-                       'Useruser', null, 'infinite', '127.0.8.1',
-                       $wgLang->timeanddate( wfTimestamp( TS_MW, $prev ), true ) ) ),
+                               '[[User:Useruser|Useruser]]', 'no reason given', '127.0.0.1',
+                               'Useruser', null, 'infinite', '127.0.8.1',
+                               $wgLang->timeanddate( wfTimestamp( TS_MW, $prev ), true ) ) ),
                        $this->title->getUserPermissionsErrors( 'move-target',
-                       $this->user ) );
+                               $this->user ) );
 
                $this->assertEquals( false, $this->title->userCan( 'move-target', $this->user ) );
                // quickUserCan should ignore user blocks
@@ -648,9 +650,9 @@ class TitlePermissionTest extends MediaWikiLangTestCase {
                $this->user->mBlockedby = $this->user->getName();
                $this->user->mBlock = new Block( '127.0.8.1', 0, 1, 'no reason given', $now, 0, 10 );
                $this->assertEquals( array( array( 'blockedtext',
-                       '[[User:Useruser|Useruser]]', 'no reason given', '127.0.0.1',
-                       'Useruser', null, '23:00, 31 December 1969', '127.0.8.1',
-                       $wgLang->timeanddate( wfTimestamp( TS_MW, $now ), true ) ) ),
+                               '[[User:Useruser|Useruser]]', 'no reason given', '127.0.0.1',
+                               'Useruser', null, '23:00, 31 December 1969', '127.0.8.1',
+                               $wgLang->timeanddate( wfTimestamp( TS_MW, $now ), true ) ) ),
                        $this->title->getUserPermissionsErrors( 'move-target', $this->user ) );
 
                # $action != 'read' && $action != 'createaccount' && $user->isBlockedFrom( $this )
index 6399d48..3dc5e82 100644 (file)
@@ -6,7 +6,6 @@
  *        ^--- needed for language cache stuff
  */
 class TitleTest extends MediaWikiTestCase {
-
        protected function setUp() {
                parent::setUp();
 
@@ -55,10 +54,10 @@ class TitleTest extends MediaWikiTestCase {
                        array( 'Special:Version/param', 'param' ),
                );
        }
-       
+
        /**
         * Auth-less test of Title::isValidMoveOperation
-        * 
+        *
         * @group Database
         * @param string $source
         * @param string $target
@@ -78,7 +77,7 @@ class TitleTest extends MediaWikiTestCase {
                        }
                }
        }
-       
+
        /**
         * Provides test parameter values for testIsValidMoveOperation()
         */
@@ -100,13 +99,12 @@ class TitleTest extends MediaWikiTestCase {
         * @covers Title::checkReadPermission
         * @dataProvider dataWgWhitelistReadRegexp
         */
-       function testWgWhitelistReadRegexp($whitelistRegexp, $source, $action, $expected) {
-
+       function testWgWhitelistReadRegexp( $whitelistRegexp, $source, $action, $expected ) {
                // $wgWhitelistReadRegexp must be an array. Since the provided test cases
                // usually have only one regex, it is more concise to write the lonely regex
                // as a string. Thus we cast to an array() to honor $wgWhitelistReadRegexp
                // type requisite.
-               if( is_string( $whitelistRegexp ) ) {
+               if ( is_string( $whitelistRegexp ) ) {
                        $whitelistRegexp = array( $whitelistRegexp );
                }
 
@@ -126,8 +124,8 @@ class TitleTest extends MediaWikiTestCase {
                $wgWhitelistRead = array( 'some random non sense title' );
 
                global $wgWhitelistReadRegexp;
-               $oldWhitelistRegexp    = $wgWhitelistReadRegexp;
-               $wgWhitelistReadRegexp = $whitelistRegexp ;
+               $oldWhitelistRegexp = $wgWhitelistReadRegexp;
+               $wgWhitelistReadRegexp = $whitelistRegexp;
 
                // Just use $wgUser which in test is a user object for '127.0.0.1'
                global $wgUser;
@@ -141,12 +139,11 @@ class TitleTest extends MediaWikiTestCase {
                $wgWhitelistRead = $oldWhitelist;
                $wgWhitelistReadRegexp = $oldWhitelistRegexp;
 
-               if( is_bool( $expected ) ) {
+               if ( is_bool( $expected ) ) {
                        # Forge the assertion message depending on the assertion expectation
                        $allowableness = $expected
                                ? " should be allowed"
-                               : " should NOT be allowed"
-                       ;
+                               : " should NOT be allowed";
                        $this->assertEquals( $expected, $errors, "User action '$action' on [[$source]] $allowableness." );
                } else {
                        $errors = $this->flattenErrorsArray( $errors );
@@ -160,7 +157,7 @@ class TitleTest extends MediaWikiTestCase {
         * Provides test parameter values for testWgWhitelistReadRegexp()
         */
        function dataWgWhitelistReadRegexp() {
-               $ALLOWED    = true;
+               $ALLOWED = true;
                $DISALLOWED = false;
 
                return array(
@@ -202,9 +199,9 @@ class TitleTest extends MediaWikiTestCase {
                }
                return $result;
        }
-       
+
        public static function provideTestIsValidMoveOperation() {
-               return array( 
+               return array(
                        array( 'Test', 'Test', 'selfmove' ),
                        array( 'File:Test.jpg', 'Page', 'imagenocrossnamespace' )
                );
@@ -246,28 +243,28 @@ class TitleTest extends MediaWikiTestCase {
                        array( 'es', 'Help:I_need_somebody', 'es', 'zh-tw', false ),
                        array( 'zh', 'Help:I_need_somebody', 'zh', 'zh-tw', false ),
 
-                       array( 'es',    'Help:I_need_somebody',      'es', 'zh-tw', 'zh-cn' ),
-                       array( 'es',    'MediaWiki:About',           'es', 'zh-tw', 'zh-cn' ),
-                       array( 'es',    'MediaWiki:About/',          'es', 'zh-tw', 'zh-cn' ),
-                       array( 'de',    'MediaWiki:About/de',        'es', 'zh-tw', 'zh-cn' ),
-                       array( 'en',    'MediaWiki:Common.js',       'es', 'zh-tw', 'zh-cn' ),
-                       array( 'en',    'MediaWiki:Common.css',      'es', 'zh-tw', 'zh-cn' ),
-                       array( 'en',    'User:JohnDoe/Common.js',    'es', 'zh-tw', 'zh-cn' ),
-                       array( 'en',    'User:JohnDoe/Monobook.css', 'es', 'zh-tw', 'zh-cn' ),
-
-                       array( 'zh-cn', 'Help:I_need_somebody',      'zh', 'zh-tw', 'zh-cn' ),
-                       array( 'zh',    'MediaWiki:About',           'zh', 'zh-tw', 'zh-cn' ),
-                       array( 'zh',    'MediaWiki:About/',          'zh', 'zh-tw', 'zh-cn' ),
-                       array( 'de',    'MediaWiki:About/de',        'zh', 'zh-tw', 'zh-cn' ),
-                       array( 'zh-cn', 'MediaWiki:About/zh-cn',     'zh', 'zh-tw', 'zh-cn' ),
-                       array( 'zh-tw', 'MediaWiki:About/zh-tw',     'zh', 'zh-tw', 'zh-cn' ),
-                       array( 'en',    'MediaWiki:Common.js',       'zh', 'zh-tw', 'zh-cn' ),
-                       array( 'en',    'MediaWiki:Common.css',      'zh', 'zh-tw', 'zh-cn' ),
-                       array( 'en',    'User:JohnDoe/Common.js',    'zh', 'zh-tw', 'zh-cn' ),
-                       array( 'en',    'User:JohnDoe/Monobook.css', 'zh', 'zh-tw', 'zh-cn' ),
-
-                       array( 'zh-tw', 'Special:NewPages',       'es', 'zh-tw', 'zh-cn' ),
-                       array( 'zh-tw', 'Special:NewPages',       'zh', 'zh-tw', 'zh-cn' ),
+                       array( 'es', 'Help:I_need_somebody', 'es', 'zh-tw', 'zh-cn' ),
+                       array( 'es', 'MediaWiki:About', 'es', 'zh-tw', 'zh-cn' ),
+                       array( 'es', 'MediaWiki:About/', 'es', 'zh-tw', 'zh-cn' ),
+                       array( 'de', 'MediaWiki:About/de', 'es', 'zh-tw', 'zh-cn' ),
+                       array( 'en', 'MediaWiki:Common.js', 'es', 'zh-tw', 'zh-cn' ),
+                       array( 'en', 'MediaWiki:Common.css', 'es', 'zh-tw', 'zh-cn' ),
+                       array( 'en', 'User:JohnDoe/Common.js', 'es', 'zh-tw', 'zh-cn' ),
+                       array( 'en', 'User:JohnDoe/Monobook.css', 'es', 'zh-tw', 'zh-cn' ),
+
+                       array( 'zh-cn', 'Help:I_need_somebody', 'zh', 'zh-tw', 'zh-cn' ),
+                       array( 'zh', 'MediaWiki:About', 'zh', 'zh-tw', 'zh-cn' ),
+                       array( 'zh', 'MediaWiki:About/', 'zh', 'zh-tw', 'zh-cn' ),
+                       array( 'de', 'MediaWiki:About/de', 'zh', 'zh-tw', 'zh-cn' ),
+                       array( 'zh-cn', 'MediaWiki:About/zh-cn', 'zh', 'zh-tw', 'zh-cn' ),
+                       array( 'zh-tw', 'MediaWiki:About/zh-tw', 'zh', 'zh-tw', 'zh-cn' ),
+                       array( 'en', 'MediaWiki:Common.js', 'zh', 'zh-tw', 'zh-cn' ),
+                       array( 'en', 'MediaWiki:Common.css', 'zh', 'zh-tw', 'zh-cn' ),
+                       array( 'en', 'User:JohnDoe/Common.js', 'zh', 'zh-tw', 'zh-cn' ),
+                       array( 'en', 'User:JohnDoe/Monobook.css', 'zh', 'zh-tw', 'zh-cn' ),
+
+                       array( 'zh-tw', 'Special:NewPages', 'es', 'zh-tw', 'zh-cn' ),
+                       array( 'zh-tw', 'Special:NewPages', 'zh', 'zh-tw', 'zh-cn' ),
 
                );
        }
@@ -275,7 +272,7 @@ class TitleTest extends MediaWikiTestCase {
        /**
         * @dataProvider provideBaseTitleCases
         */
-       function testExtractingBaseTextFromTitle( $title, $expected, $msg='' ) {
+       function testExtractingBaseTextFromTitle( $title, $expected, $msg = '' ) {
                $title = Title::newFromText( $title );
                $this->assertEquals( $expected,
                        $title->getBaseText(),
@@ -286,15 +283,15 @@ class TitleTest extends MediaWikiTestCase {
        function provideBaseTitleCases() {
                return array(
                        # Title, expected base, optional message
-                       array('User:John_Doe/subOne/subTwo', 'John Doe/subOne' ),
-                       array('User:Foo/Bar/Baz', 'Foo/Bar' ),
+                       array( 'User:John_Doe/subOne/subTwo', 'John Doe/subOne' ),
+                       array( 'User:Foo/Bar/Baz', 'Foo/Bar' ),
                );
        }
 
        /**
         * @dataProvider provideRootTitleCases
         */
-       function testExtractingRootTextFromTitle( $title, $expected, $msg='' ) {
+       function testExtractingRootTextFromTitle( $title, $expected, $msg = '' ) {
                $title = Title::newFromText( $title );
                $this->assertEquals( $expected,
                        $title->getRootText(),
@@ -305,8 +302,8 @@ class TitleTest extends MediaWikiTestCase {
        public static function provideRootTitleCases() {
                return array(
                        # Title, expected base, optional message
-                       array('User:John_Doe/subOne/subTwo', 'John Doe' ),
-                       array('User:Foo/Bar/Baz', 'Foo' ),
+                       array( 'User:John_Doe/subOne/subTwo', 'John Doe' ),
+                       array( 'User:Foo/Bar/Baz', 'Foo' ),
                );
        }
 
@@ -314,7 +311,7 @@ class TitleTest extends MediaWikiTestCase {
         * @todo Handle $wgNamespacesWithSubpages cases
         * @dataProvider provideSubpageTitleCases
         */
-       function testExtractingSubpageTextFromTitle( $title, $expected, $msg='' ) {
+       function testExtractingSubpageTextFromTitle( $title, $expected, $msg = '' ) {
                $title = Title::newFromText( $title );
                $this->assertEquals( $expected,
                        $title->getSubpageText(),
@@ -325,9 +322,8 @@ class TitleTest extends MediaWikiTestCase {
        function provideSubpageTitleCases() {
                return array(
                        # Title, expected base, optional message
-                       array('User:John_Doe/subOne/subTwo', 'subTwo' ),
-                       array('User:John_Doe/subOne', 'subOne' ),
+                       array( 'User:John_Doe/subOne/subTwo', 'subTwo' ),
+                       array( 'User:John_Doe/subOne', 'subOne' ),
                );
        }
-
 }
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 a9dfca1..e777179 100644 (file)
@@ -7,7 +7,6 @@ define( 'NS_UNITTEST_TALK', 5601 );
  * @group Database
  */
 class UserTest extends MediaWikiTestCase {
-
        /**
         * @var User
         */
@@ -62,6 +61,7 @@ class UserTest extends MediaWikiTestCase {
                $this->assertContains( 'modifytest', $rights );
                $this->assertNotContains( 'nukeworld', $rights );
        }
+
        public function testRevokePermissions() {
                $rights = User::getGroupPermissions( array( 'unittesters', 'formertesters' ) );
                $this->assertNotContains( 'runtest', $rights );
@@ -122,15 +122,15 @@ class UserTest extends MediaWikiTestCase {
                        array( '', false, 'Empty string' ),
                        array( ' ', false, 'Blank space' ),
                        array( 'abcd', false, 'Starts with small letter' ),
-                       array( 'Ab/cd', false,  'Contains slash' ),
-                       array( 'Ab cd' , true, 'Whitespace' ),
-                       array( '192.168.1.1', false,  'IP' ),
+                       array( 'Ab/cd', false, 'Contains slash' ),
+                       array( 'Ab cd', true, 'Whitespace' ),
+                       array( '192.168.1.1', false, 'IP' ),
                        array( 'User:Abcd', false, 'Reserved Namespace' ),
-                       array( '12abcd232' , true  , 'Starts with Numbers' ),
-                       array( '?abcd' , true,  'Start with ? mark' ),
+                       array( '12abcd232', true, 'Starts with Numbers' ),
+                       array( '?abcd', true, 'Start with ? mark' ),
                        array( '#abcd', false, 'Start with #' ),
-                       array( 'Abcdകഖഗഘ', true,  ' Mixed scripts' ),
-                       array( 'ജോസ്‌തോമസ്',  false, 'ZWNJ- Format control character' ),
+                       array( 'Abcdകഖഗഘ', true, ' Mixed scripts' ),
+                       array( 'ജോസ്‌തോമസ്', false, 'ZWNJ- Format control character' ),
                        array( 'Ab cd', false, ' Ideographic space' ),
                );
        }
@@ -174,7 +174,7 @@ class UserTest extends MediaWikiTestCase {
 
                // let the user have a few (3) edits
                $page = WikiPage::factory( Title::newFromText( 'Help:UserTest_EditCount' ) );
-               for( $i = 0; $i < 3; $i++ ) {
+               for ( $i = 0; $i < 3; $i++ ) {
                        $page->doEdit( (string)$i, 'test', 0, false, $user );
                }
 
index 153ff78..46f8025 100644 (file)
@@ -212,9 +212,9 @@ class WebRequestTest extends MediaWikiTestCase {
        /**
         * @dataProvider provideLanguageData
         */
-       function testAcceptLang($acceptLanguageHeader, $expectedLanguages, $description) {
+       function testAcceptLang( $acceptLanguageHeader, $expectedLanguages, $description ) {
                $_SERVER = array( 'HTTP_ACCEPT_LANGUAGE' => $acceptLanguageHeader );
                $request = new WebRequest();
-               $this->assertSame( $request->getAcceptLang(), $expectedLanguages, $description);
+               $this->assertSame( $request->getAcceptLang(), $expectedLanguages, $description );
        }
 }
index 46e0f9d..2501be3 100644 (file)
@@ -1,10 +1,10 @@
 <?php
 /**
-* @group ContentHandler
-* @group Database
-* ^--- important, causes temporary tables to be used instead of the real database
-* @group medium
-**/
+ * @group ContentHandler
+ * @group Database
+ * ^--- important, causes temporary tables to be used instead of the real database
+ * @group medium
+ **/
 
 class WikiPageTest extends MediaWikiLangTestCase {
 
@@ -13,23 +13,23 @@ class WikiPageTest extends MediaWikiLangTestCase {
        function  __construct( $name = null, array $data = array(), $dataName = '' ) {
                parent::__construct( $name, $data, $dataName );
 
-               $this->tablesUsed = array_merge (
+               $this->tablesUsed = array_merge(
                        $this->tablesUsed,
                        array( 'page',
-                                       'revision',
-                                       'text',
+                               'revision',
+                               'text',
 
-                                       'recentchanges',
-                                       'logging',
+                               'recentchanges',
+                               'logging',
 
-                                       'page_props',
-                                       'pagelinks',
-                                       'categorylinks',
-                                       'langlinks',
-                                       'externallinks',
-                                       'imagelinks',
-                                       'templatelinks',
-                                       'iwlinks' ) );
+                               'page_props',
+                               'pagelinks',
+                               'categorylinks',
+                               'langlinks',
+                               'externallinks',
+                               'imagelinks',
+                               'templatelinks',
+                               'iwlinks' ) );
        }
 
        protected function setUp() {
@@ -72,7 +72,6 @@ class WikiPageTest extends MediaWikiLangTestCase {
                return $p;
        }
 
-
        /**
         * @param String|Title|WikiPage $page
         * @param String $text
@@ -96,8 +95,8 @@ class WikiPageTest extends MediaWikiLangTestCase {
                $title = $page->getTitle();
 
                $content = ContentHandler::makeContent( "[[Lorem ipsum]] dolor sit amet, consetetur sadipscing elitr, sed diam "
-                                               . " nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat.",
-                                               $title, CONTENT_MODEL_WIKITEXT );
+                               . " nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat.",
+                       $title, CONTENT_MODEL_WIKITEXT );
 
                $page->doEditContent( $content, "[[testing]] 1" );
 
@@ -124,8 +123,8 @@ class WikiPageTest extends MediaWikiLangTestCase {
 
                # ------------------------
                $content = ContentHandler::makeContent( "At vero eos et accusam et justo duo [[dolores]] et ea rebum. "
-                                                                                               . "Stet clita kasd [[gubergren]], no sea takimata sanctus est.",
-                                                                                               $title, CONTENT_MODEL_WIKITEXT );
+                               . "Stet clita kasd [[gubergren]], no sea takimata sanctus est.",
+                       $title, CONTENT_MODEL_WIKITEXT );
 
                $page->doEditContent( $content, "testing 2" );
 
@@ -155,7 +154,7 @@ class WikiPageTest extends MediaWikiLangTestCase {
                $page = $this->newPage( $title );
 
                $text = "[[Lorem ipsum]] dolor sit amet, consetetur sadipscing elitr, sed diam "
-                               . " nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat.";
+                       . " nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat.";
 
                $page->doEdit( $text, "[[testing]] 1" );
 
@@ -182,7 +181,7 @@ class WikiPageTest extends MediaWikiLangTestCase {
 
                # ------------------------
                $text = "At vero eos et accusam et justo duo [[dolores]] et ea rebum. "
-                               . "Stet clita kasd [[gubergren]], no sea takimata sanctus est.";
+                       . "Stet clita kasd [[gubergren]], no sea takimata sanctus est.";
 
                $page->doEdit( $text, "testing 2" );
 
@@ -433,104 +432,104 @@ class WikiPageTest extends MediaWikiLangTestCase {
 
                        // any
                        array( 'WikiPageTest_testIsCountable',
-                                       CONTENT_MODEL_WIKITEXT,
-                                       '',
-                                       'any',
-                                       true
+                               CONTENT_MODEL_WIKITEXT,
+                               '',
+                               'any',
+                               true
                        ),
                        array( 'WikiPageTest_testIsCountable',
-                                       CONTENT_MODEL_WIKITEXT,
-                                       'Foo',
-                                       'any',
-                                       true
+                               CONTENT_MODEL_WIKITEXT,
+                               'Foo',
+                               'any',
+                               true
                        ),
 
                        // comma
                        array( 'WikiPageTest_testIsCountable',
-                                       CONTENT_MODEL_WIKITEXT,
-                                       'Foo',
-                                       'comma',
-                                       false
+                               CONTENT_MODEL_WIKITEXT,
+                               'Foo',
+                               'comma',
+                               false
                        ),
                        array( 'WikiPageTest_testIsCountable',
-                                       CONTENT_MODEL_WIKITEXT,
-                                       'Foo, bar',
-                                       'comma',
-                                       true
+                               CONTENT_MODEL_WIKITEXT,
+                               'Foo, bar',
+                               'comma',
+                               true
                        ),
 
                        // link
                        array( 'WikiPageTest_testIsCountable',
-                                       CONTENT_MODEL_WIKITEXT,
-                                       'Foo',
-                                       'link',
-                                       false
+                               CONTENT_MODEL_WIKITEXT,
+                               'Foo',
+                               'link',
+                               false
                        ),
                        array( 'WikiPageTest_testIsCountable',
-                                       CONTENT_MODEL_WIKITEXT,
-                                       'Foo [[bar]]',
-                                       'link',
-                                       true
+                               CONTENT_MODEL_WIKITEXT,
+                               'Foo [[bar]]',
+                               'link',
+                               true
                        ),
 
                        // redirects
                        array( 'WikiPageTest_testIsCountable',
-                                       CONTENT_MODEL_WIKITEXT,
-                                       '#REDIRECT [[bar]]',
-                                       'any',
-                                       false
+                               CONTENT_MODEL_WIKITEXT,
+                               '#REDIRECT [[bar]]',
+                               'any',
+                               false
                        ),
                        array( 'WikiPageTest_testIsCountable',
-                                       CONTENT_MODEL_WIKITEXT,
-                                       '#REDIRECT [[bar]]',
-                                       'comma',
-                                       false
+                               CONTENT_MODEL_WIKITEXT,
+                               '#REDIRECT [[bar]]',
+                               'comma',
+                               false
                        ),
                        array( 'WikiPageTest_testIsCountable',
-                                       CONTENT_MODEL_WIKITEXT,
-                                       '#REDIRECT [[bar]]',
-                                       'link',
-                                       false
+                               CONTENT_MODEL_WIKITEXT,
+                               '#REDIRECT [[bar]]',
+                               'link',
+                               false
                        ),
 
                        // not a content namespace
                        array( 'Talk:WikiPageTest_testIsCountable',
-                                       CONTENT_MODEL_WIKITEXT,
-                                       'Foo',
-                                       'any',
-                                       false
+                               CONTENT_MODEL_WIKITEXT,
+                               'Foo',
+                               'any',
+                               false
                        ),
                        array( 'Talk:WikiPageTest_testIsCountable',
-                                       CONTENT_MODEL_WIKITEXT,
-                                       'Foo, bar',
-                                       'comma',
-                                       false
+                               CONTENT_MODEL_WIKITEXT,
+                               'Foo, bar',
+                               'comma',
+                               false
                        ),
                        array( 'Talk:WikiPageTest_testIsCountable',
-                                       CONTENT_MODEL_WIKITEXT,
-                                       'Foo [[bar]]',
-                                       'link',
-                                       false
+                               CONTENT_MODEL_WIKITEXT,
+                               'Foo [[bar]]',
+                               'link',
+                               false
                        ),
 
                        // not a content namespace, different model
                        array( 'MediaWiki:WikiPageTest_testIsCountable.js',
-                                       null,
-                                       'Foo',
-                                       'any',
-                                       false
+                               null,
+                               'Foo',
+                               'any',
+                               false
                        ),
                        array( 'MediaWiki:WikiPageTest_testIsCountable.js',
-                                       null,
-                                       'Foo, bar',
-                                       'comma',
-                                       false
+                               null,
+                               'Foo, bar',
+                               'comma',
+                               false
                        ),
                        array( 'MediaWiki:WikiPageTest_testIsCountable.js',
-                                       null,
-                                       'Foo [[bar]]',
-                                       'link',
-                                       false
+                               null,
+                               'Foo [[bar]]',
+                               'link',
+                               false
                        ),
                );
        }
@@ -553,7 +552,7 @@ class WikiPageTest extends MediaWikiLangTestCase {
 
                $page = $this->createPage( $title, $text, $model );
                $hasLinks = wfGetDB( DB_SLAVE )->selectField( 'pagelinks', 1,
-                                       array( 'pl_from' => $page->getId() ), __METHOD__ );
+                       array( 'pl_from' => $page->getId() ), __METHOD__ );
 
                $editInfo = $page->prepareContentForEdit( $page->getContent() );
 
@@ -561,15 +560,15 @@ class WikiPageTest extends MediaWikiLangTestCase {
                $w = $page->isCountable( $editInfo );
 
                $this->assertEquals( $expected, $v, "isCountable( null ) returned unexpected value " . var_export( $v, true )
-                                                                                       . " instead of " . var_export( $expected, true ) . " in mode `$mode` for text \"$text\"" );
+                       . " instead of " . var_export( $expected, true ) . " in mode `$mode` for text \"$text\"" );
 
                $this->assertEquals( $expected, $w, "isCountable( \$editInfo ) returned unexpected value " . var_export( $v, true )
-                                                                                       . " instead of " . var_export( $expected, true ) . " in mode `$mode` for text \"$text\"" );
+                       . " instead of " . var_export( $expected, true ) . " in mode `$mode` for text \"$text\"" );
        }
 
        public static function provideGetParserOutput() {
                return array(
-                       array( CONTENT_MODEL_WIKITEXT, "hello ''world''\n", "<p>hello <i>world</i></p>"),
+                       array( CONTENT_MODEL_WIKITEXT, "hello ''world''\n", "<p>hello <i>world</i></p>" ),
                        // @todo: more...?
                );
        }
@@ -591,9 +590,9 @@ class WikiPageTest extends MediaWikiLangTestCase {
                return $po;
        }
 
-       public function testGetParserOutput_nonexisting( ) {
+       public function testGetParserOutput_nonexisting() {
                static $count = 0;
-               $count ++;
+               $count++;
 
                $page = new WikiPage( new Title( "WikiPageTest_testGetParserOutput_nonexisting_$count" ) );
 
@@ -603,7 +602,7 @@ class WikiPageTest extends MediaWikiLangTestCase {
                $this->assertFalse( $po, "getParserOutput() shall return false for non-existing pages." );
        }
 
-       public function testGetParserOutput_badrev( ) {
+       public function testGetParserOutput_badrev() {
                $page = $this->createPage( 'WikiPageTest_testGetParserOutput', "dummy", CONTENT_MODEL_WIKITEXT );
 
                $opt = new ParserOptions();
@@ -633,46 +632,46 @@ more stuff
                //NOTE: assume the Help namespace to contain wikitext
                return array(
                        array( 'Help:WikiPageTest_testReplaceSection',
-                                       CONTENT_MODEL_WIKITEXT,
-                                       WikiPageTest::$sections,
-                                       "0",
-                                       "No more",
-                                       null,
-                                       trim( preg_replace( '/^Intro/sm', 'No more', WikiPageTest::$sections ) )
+                               CONTENT_MODEL_WIKITEXT,
+                               WikiPageTest::$sections,
+                               "0",
+                               "No more",
+                               null,
+                               trim( preg_replace( '/^Intro/sm', 'No more', WikiPageTest::$sections ) )
                        ),
                        array( 'Help:WikiPageTest_testReplaceSection',
-                                       CONTENT_MODEL_WIKITEXT,
-                                       WikiPageTest::$sections,
-                                       "",
-                                       "No more",
-                                       null,
-                                       "No more"
+                               CONTENT_MODEL_WIKITEXT,
+                               WikiPageTest::$sections,
+                               "",
+                               "No more",
+                               null,
+                               "No more"
                        ),
                        array( 'Help:WikiPageTest_testReplaceSection',
-                                       CONTENT_MODEL_WIKITEXT,
-                                       WikiPageTest::$sections,
-                                       "2",
-                                       "== TEST ==\nmore fun",
-                                       null,
-                                       trim( preg_replace( '/^== test ==.*== foo ==/sm',
-                                                                               "== TEST ==\nmore fun\n\n== foo ==",
-                                                                               WikiPageTest::$sections ) )
+                               CONTENT_MODEL_WIKITEXT,
+                               WikiPageTest::$sections,
+                               "2",
+                               "== TEST ==\nmore fun",
+                               null,
+                               trim( preg_replace( '/^== test ==.*== foo ==/sm',
+                                       "== TEST ==\nmore fun\n\n== foo ==",
+                                       WikiPageTest::$sections ) )
                        ),
                        array( 'Help:WikiPageTest_testReplaceSection',
-                                       CONTENT_MODEL_WIKITEXT,
-                                       WikiPageTest::$sections,
-                                       "8",
-                                       "No more",
-                                       null,
-                                       trim( WikiPageTest::$sections )
+                               CONTENT_MODEL_WIKITEXT,
+                               WikiPageTest::$sections,
+                               "8",
+                               "No more",
+                               null,
+                               trim( WikiPageTest::$sections )
                        ),
                        array( 'Help:WikiPageTest_testReplaceSection',
-                                       CONTENT_MODEL_WIKITEXT,
-                                       WikiPageTest::$sections,
-                                       "new",
-                                       "No more",
-                                       "New",
-                                       trim( WikiPageTest::$sections ) . "\n\n== New ==\n\nNo more"
+                               CONTENT_MODEL_WIKITEXT,
+                               WikiPageTest::$sections,
+                               "new",
+                               "No more",
+                               "New",
+                               trim( WikiPageTest::$sections ) . "\n\n== New ==\n\nNo more"
                        ),
                );
        }
@@ -704,71 +703,71 @@ more stuff
 
        /* @todo FIXME: fix this!
        public function testGetUndoText() {
-               $this->checkHasDiff3();
+       $this->checkHasDiff3();
 
-               $text = "one";
-               $page = $this->createPage( "WikiPageTest_testGetUndoText", $text );
-               $rev1 = $page->getRevision();
+       $text = "one";
+       $page = $this->createPage( "WikiPageTest_testGetUndoText", $text );
+       $rev1 = $page->getRevision();
 
-               $text .= "\n\ntwo";
-               $page->doEditContent( ContentHandler::makeContent( $text, $page->getTitle() ), "adding section two");
-               $rev2 = $page->getRevision();
+       $text .= "\n\ntwo";
+       $page->doEditContent( ContentHandler::makeContent( $text, $page->getTitle() ), "adding section two");
+       $rev2 = $page->getRevision();
 
-               $text .= "\n\nthree";
-               $page->doEditContent( ContentHandler::makeContent( $text, $page->getTitle() ), "adding section three");
-               $rev3 = $page->getRevision();
+       $text .= "\n\nthree";
+       $page->doEditContent( ContentHandler::makeContent( $text, $page->getTitle() ), "adding section three");
+       $rev3 = $page->getRevision();
 
-               $text .= "\n\nfour";
-               $page->doEditContent( ContentHandler::makeContent( $text, $page->getTitle() ), "adding section four");
-               $rev4 = $page->getRevision();
+       $text .= "\n\nfour";
+       $page->doEditContent( ContentHandler::makeContent( $text, $page->getTitle() ), "adding section four");
+       $rev4 = $page->getRevision();
 
-               $text .= "\n\nfive";
-               $page->doEditContent( ContentHandler::makeContent( $text, $page->getTitle() ), "adding section five");
-               $rev5 = $page->getRevision();
+       $text .= "\n\nfive";
+       $page->doEditContent( ContentHandler::makeContent( $text, $page->getTitle() ), "adding section five");
+       $rev5 = $page->getRevision();
 
-               $text .= "\n\nsix";
-               $page->doEditContent( ContentHandler::makeContent( $text, $page->getTitle() ), "adding section six");
-               $rev6 = $page->getRevision();
+       $text .= "\n\nsix";
+       $page->doEditContent( ContentHandler::makeContent( $text, $page->getTitle() ), "adding section six");
+       $rev6 = $page->getRevision();
 
-               $undo6 = $page->getUndoText( $rev6 );
-               if ( $undo6 === false ) $this->fail( "getUndoText failed for rev6" );
-               $this->assertEquals( "one\n\ntwo\n\nthree\n\nfour\n\nfive", $undo6 );
+       $undo6 = $page->getUndoText( $rev6 );
+       if ( $undo6 === false ) $this->fail( "getUndoText failed for rev6" );
+       $this->assertEquals( "one\n\ntwo\n\nthree\n\nfour\n\nfive", $undo6 );
 
-               $undo3 = $page->getUndoText( $rev4, $rev2 );
-               if ( $undo3 === false ) $this->fail( "getUndoText failed for rev4..rev2" );
-               $this->assertEquals( "one\n\ntwo\n\nfive", $undo3 );
+       $undo3 = $page->getUndoText( $rev4, $rev2 );
+       if ( $undo3 === false ) $this->fail( "getUndoText failed for rev4..rev2" );
+       $this->assertEquals( "one\n\ntwo\n\nfive", $undo3 );
 
-               $undo2 = $page->getUndoText( $rev2 );
-               if ( $undo2 === false ) $this->fail( "getUndoText failed for rev2" );
-               $this->assertEquals( "one\n\nfive", $undo2 );
+       $undo2 = $page->getUndoText( $rev2 );
+       if ( $undo2 === false ) $this->fail( "getUndoText failed for rev2" );
+       $this->assertEquals( "one\n\nfive", $undo2 );
        }
-       */
+        */
 
        /**
         * @todo FIXME: this is a better rollback test than the one below, but it keeps failing in jenkins for some reason.
         */
        public function broken_testDoRollback() {
                $admin = new User();
-               $admin->setName("Admin");
+               $admin->setName( "Admin" );
 
                $text = "one";
                $page = $this->newPage( "WikiPageTest_testDoRollback" );
                $page->doEditContent( ContentHandler::makeContent( $text, $page->getTitle() ),
-                                                               "section one", EDIT_NEW, false, $admin );
+                       "section one", EDIT_NEW, false, $admin );
 
                $user1 = new User();
                $user1->setName( "127.0.1.11" );
                $text .= "\n\ntwo";
                $page = new WikiPage( $page->getTitle() );
                $page->doEditContent( ContentHandler::makeContent( $text, $page->getTitle() ),
-                                                               "adding section two", 0, false, $user1 );
+                       "adding section two", 0, false, $user1 );
 
                $user2 = new User();
                $user2->setName( "127.0.2.13" );
                $text .= "\n\nthree";
                $page = new WikiPage( $page->getTitle() );
                $page->doEditContent( ContentHandler::makeContent( $text, $page->getTitle() ),
-                                                               "adding section three", 0, false, $user2 );
+                       "adding section three", 0, false, $user2 );
 
                # we are having issues with doRollback spuriously failing. apparently the last revision somehow goes missing
                # or not committed under some circumstances. so, make sure the last revision has the right user name.
@@ -796,7 +795,7 @@ more stuff
 
                $page = new WikiPage( $page->getTitle() );
                $this->assertEquals( $rev2->getSha1(), $page->getRevision()->getSha1(),
-                                                               "rollback did not revert to the correct revision" );
+                       "rollback did not revert to the correct revision" );
                $this->assertEquals( "one\n\ntwo", $page->getContent()->getNativeData() );
        }
 
@@ -805,12 +804,12 @@ more stuff
         */
        public function testDoRollback() {
                $admin = new User();
-               $admin->setName("Admin");
+               $admin->setName( "Admin" );
 
                $text = "one";
                $page = $this->newPage( "WikiPageTest_testDoRollback" );
                $page->doEditContent( ContentHandler::makeContent( $text, $page->getTitle(), CONTENT_MODEL_WIKITEXT ),
-                                                               "section one", EDIT_NEW, false, $admin );
+                       "section one", EDIT_NEW, false, $admin );
                $rev1 = $page->getRevision();
 
                $user1 = new User();
@@ -818,7 +817,7 @@ more stuff
                $text .= "\n\ntwo";
                $page = new WikiPage( $page->getTitle() );
                $page->doEditContent( ContentHandler::makeContent( $text, $page->getTitle(), CONTENT_MODEL_WIKITEXT ),
-                                                               "adding section two", 0, false, $user1 );
+                       "adding section two", 0, false, $user1 );
 
                # now, try the rollback
                $admin->addGroup( "sysop" ); #XXX: make the test user a sysop...
@@ -831,11 +830,11 @@ more stuff
 
                $page = new WikiPage( $page->getTitle() );
                $this->assertEquals( $rev1->getSha1(), $page->getRevision()->getSha1(),
-                                                       "rollback did not revert to the correct revision" );
+                       "rollback did not revert to the correct revision" );
                $this->assertEquals( "one", $page->getContent()->getNativeData() );
        }
 
-       public static function provideGetAutosummary( ) {
+       public static function provideGetAutosummary() {
                return array(
                        array(
                                'Hello there, world!',
@@ -887,10 +886,10 @@ more stuff
                $summary = $page->getAutosummary( $old, $new, $flags );
 
                $this->assertTrue( (bool)preg_match( $expected, $summary ),
-                                                       "Autosummary didn't match expected pattern $expected: $summary" );
+                       "Autosummary didn't match expected pattern $expected: $summary" );
        }
 
-       public static function provideGetAutoDeleteReason( ) {
+       public static function provideGetAutoDeleteReason() {
                return array(
                        array(
                                array(),
@@ -927,10 +926,10 @@ more stuff
                        array(
                                array(
                                        array( "first edit: "
-                                                . "Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam "
-                                                . " nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. "
-                                                . "At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea "
-                                                . "takimata sanctus est Lorem ipsum dolor sit amet.'", null ),
+                                               . "Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam "
+                                               . " nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. "
+                                               . "At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea "
+                                               . "takimata sanctus est Lorem ipsum dolor sit amet.'", null ),
                                ),
                                '/first edit:.*\.\.\."/',
                                false
@@ -962,8 +961,11 @@ more stuff
                foreach ( $edits as $edit ) {
                        $user = new User();
 
-                       if ( !empty( $edit[1] ) ) $user->setName( $edit[1] );
-                       else $user = $wgUser;
+                       if ( !empty( $edit[1] ) ) {
+                               $user->setName( $edit[1] );
+                       } else {
+                               $user = $wgUser;
+                       }
 
                        $content = ContentHandler::makeContent( $edit[0], $page->getTitle(), $page->getContentModel() );
 
@@ -974,12 +976,15 @@ more stuff
 
                $reason = $page->getAutoDeleteReason( $hasHistory );
 
-               if ( is_bool( $expectedResult ) || is_null( $expectedResult ) ) $this->assertEquals( $expectedResult, $reason );
-               else $this->assertTrue( (bool)preg_match( $expectedResult, $reason ),
-                                                               "Autosummary didn't match expected pattern $expectedResult: $reason" );
+               if ( is_bool( $expectedResult ) || is_null( $expectedResult ) ) {
+                       $this->assertEquals( $expectedResult, $reason );
+               } else {
+                       $this->assertTrue( (bool)preg_match( $expectedResult, $reason ),
+                               "Autosummary didn't match expected pattern $expectedResult: $reason" );
+               }
 
                $this->assertEquals( $expectedHistory, $hasHistory,
-                                                       "expected \$hasHistory to be " . var_export( $expectedHistory, true ) );
+                       "expected \$hasHistory to be " . var_export( $expectedHistory, true ) );
 
                $page->doDeleteArticle( "done" );
        }
@@ -987,10 +992,10 @@ more stuff
        public static function providePreSaveTransform() {
                return array(
                        array( 'hello this is ~~~',
-                                       "hello this is [[Special:Contributions/127.0.0.1|127.0.0.1]]",
+                               "hello this is [[Special:Contributions/127.0.0.1|127.0.0.1]]",
                        ),
                        array( 'hello \'\'this\'\' is <nowiki>~~~</nowiki>',
-                                       'hello \'\'this\'\' is <nowiki>~~~</nowiki>',
+                               'hello \'\'this\'\' is <nowiki>~~~</nowiki>',
                        ),
                );
        }
@@ -1001,7 +1006,7 @@ more stuff
        public function testPreSaveTransform( $text, $expected ) {
                $this->hideDeprecated( 'WikiPage::preSaveTransform' );
                $user = new User();
-               $user->setName("127.0.0.1");
+               $user->setName( "127.0.0.1" );
 
                //NOTE: assume Help namespace to contain wikitext
                $page = $this->newPage( "Help:WikiPageTest_testPreloadTransform" );
index 7c9cbe3..d7227b4 100644 (file)
@@ -9,9 +9,10 @@ class XmlSelectTest extends MediaWikiTestCase {
                $this->setMwGlobals( array(
                        'wgHtml5' => true,
                        'wgWellFormedXml' => true,
-               ));
+               ) );
                $this->select = new XmlSelect();
        }
+
        protected function tearDown() {
                parent::tearDown();
                $this->select = null;
@@ -49,14 +50,14 @@ class XmlSelectTest extends MediaWikiTestCase {
                         * See http://en.wikipedia.org/wiki/Gray_code
                         */
                        #      $name   $id    $default
-                       array( false , false, false,  '<select></select>' ),
-                       array( false , false, 'foo',  '<select></select>' ),
-                       array( false , 'id' , 'foo',  '<select id="id"></select>' ),
-                       array( false , 'id' , false,  '<select id="id"></select>' ),
-                       array( 'name', 'id' , false,  '<select name="name" id="id"></select>' ),
-                       array( 'name', 'id' , 'foo',  '<select name="name" id="id"></select>' ),
-                       array( 'name', false, 'foo',  '<select name="name"></select>' ),
-                       array( 'name', false, false,  '<select name="name"></select>' ),
+                       array( false, false, false, '<select></select>' ),
+                       array( false, false, 'foo', '<select></select>' ),
+                       array( false, 'id', 'foo', '<select id="id"></select>' ),
+                       array( false, 'id', false, '<select id="id"></select>' ),
+                       array( 'name', 'id', false, '<select name="name" id="id"></select>' ),
+                       array( 'name', 'id', 'foo', '<select name="name" id="id"></select>' ),
+                       array( 'name', false, 'foo', '<select name="name"></select>' ),
+                       array( 'name', false, false, '<select name="name"></select>' ),
                );
        }
 
@@ -65,18 +66,22 @@ class XmlSelectTest extends MediaWikiTestCase {
                $this->select->addOption( 'foo' );
                $this->assertEquals( '<select><option value="foo">foo</option></select>', $this->select->getHTML() );
        }
+
        public function testAddOptionWithDefault() {
                $this->select->addOption( 'foo', true );
                $this->assertEquals( '<select><option value="1">foo</option></select>', $this->select->getHTML() );
        }
+
        public function testAddOptionWithFalse() {
                $this->select->addOption( 'foo', false );
                $this->assertEquals( '<select><option value="foo">foo</option></select>', $this->select->getHTML() );
        }
+
        public function testAddOptionWithValueZero() {
                $this->select->addOption( 'foo', 0 );
                $this->assertEquals( '<select><option value="0">foo</option></select>', $this->select->getHTML() );
        }
+
        # End XmlSelect::addOption() similar to Xml::option
 
        public function testSetDefault() {
@@ -85,9 +90,9 @@ class XmlSelectTest extends MediaWikiTestCase {
                $this->select->addOption( 'bar1' );
                $this->select->addOption( 'foo2' );
                $this->assertEquals(
-'<select><option value="foo1">foo1</option>' . "\n" .
-'<option value="bar1" selected="">bar1</option>' . "\n" .
-'<option value="foo2">foo2</option></select>', $this->select->getHTML() );
+                       '<select><option value="foo1">foo1</option>' . "\n" .
+                               '<option value="bar1" selected="">bar1</option>' . "\n" .
+                               '<option value="foo2">foo2</option></select>', $this->select->getHTML() );
        }
 
        /**
@@ -101,9 +106,9 @@ class XmlSelectTest extends MediaWikiTestCase {
                $this->select->addOption( 'foo2' );
                $this->select->setDefault( 'bar1' ); # setting default after adding options
                $this->assertEquals(
-'<select><option value="foo1">foo1</option>' . "\n" .
-'<option value="bar1" selected="">bar1</option>' . "\n" .
-'<option value="foo2">foo2</option></select>', $this->select->getHTML() );
+                       '<select><option value="foo1">foo1</option>' . "\n" .
+                               '<option value="bar1" selected="">bar1</option>' . "\n" .
+                               '<option value="foo2">foo2</option></select>', $this->select->getHTML() );
        }
 
        public function testGetAttributes() {
@@ -135,7 +140,7 @@ class XmlSelectTest extends MediaWikiTestCase {
                # verify string / integer
                $this->assertEquals(
                        $this->select->getAttribute( '1911' ),
-                       'razor' 
+                       'razor'
                );
                $this->assertEquals(
                        $this->select->getAttribute( 'dummy' ),
index b54731b..f482328 100644 (file)
@@ -11,20 +11,20 @@ class XmlTest extends MediaWikiTestCase {
                $langObj->setNamespaces( array(
                        -2 => 'Media',
                        -1 => 'Special',
-                       0  => '',
-                       1  => 'Talk',
-                       2  => 'User',
-                       3  => 'User_talk',
-                       4  => 'MyWiki',
-                       5  => 'MyWiki_Talk',
-                       6  => 'File',
-                       7  => 'File_talk',
-                       8  => 'MediaWiki',
-                       9  => 'MediaWiki_talk',
-                       10  => 'Template',
-                       11  => 'Template_talk',
-                       100  => 'Custom',
-                       101  => 'Custom_talk',
+                       0 => '',
+                       1 => 'Talk',
+                       2 => 'User',
+                       3 => 'User_talk',
+                       4 => 'MyWiki',
+                       5 => 'MyWiki_Talk',
+                       6 => 'File',
+                       7 => 'File_talk',
+                       8 => 'MediaWiki',
+                       9 => 'MediaWiki_talk',
+                       10 => 'Template',
+                       11 => 'Template_talk',
+                       100 => 'Custom',
+                       101 => 'Custom_talk',
                ) );
 
                $this->setMwGlobals( array(
@@ -35,7 +35,7 @@ class XmlTest extends MediaWikiTestCase {
        }
 
        public function testExpandAttributes() {
-               $this->assertNull( Xml::expandAttributes(null),
+               $this->assertNull( Xml::expandAttributes( null ),
                        'Converting a null list of attributes'
                );
                $this->assertEquals( '', Xml::expandAttributes( array() ),
@@ -44,8 +44,8 @@ class XmlTest extends MediaWikiTestCase {
        }
 
        public function testExpandAttributesException() {
-               $this->setExpectedException('MWException');
-               Xml::expandAttributes('string');
+               $this->setExpectedException( 'MWException' );
+               Xml::expandAttributes( 'string' );
        }
 
        function testElementOpen() {
@@ -71,6 +71,7 @@ class XmlTest extends MediaWikiTestCase {
                        'Input with a value of 0 (bug 23797)'
                );
        }
+
        function testElementEscaping() {
                $this->assertEquals(
                        '<element>hello &lt;there&gt; you &amp; you</element>',
@@ -105,53 +106,57 @@ class XmlTest extends MediaWikiTestCase {
                $this->assertEquals( '</element>', Xml::closeElement( 'element' ), 'closeElement() shortcut' );
        }
 
-       public function testDateMenu( ) {
-               $curYear   = intval(gmdate('Y'));
-               $prevYear  = $curYear - 1;
+       public function testDateMenu() {
+               $curYear = intval( gmdate( 'Y' ) );
+               $prevYear = $curYear - 1;
 
-               $curMonth  = intval(gmdate('n'));
+               $curMonth = intval( gmdate( 'n' ) );
                $prevMonth = $curMonth - 1;
-               if( $prevMonth == 0 ) { $prevMonth = 12; }
+               if ( $prevMonth == 0 ) {
+                       $prevMonth = 12;
+               }
                $nextMonth = $curMonth + 1;
-               if( $nextMonth == 13 ) { $nextMonth = 1; }
+               if ( $nextMonth == 13 ) {
+                       $nextMonth = 1;
+               }
 
                $this->assertEquals(
                        '<label for="year">From year (and earlier):</label> <input id="year" maxlength="4" size="7" type="number" value="2011" name="year" /> <label for="month">From month (and earlier):</label> <select id="month" name="month" class="mw-month-selector"><option value="-1">all</option>' . "\n" .
-'<option value="1">January</option>' . "\n" .
-'<option value="2" selected="">February</option>' . "\n" .
-'<option value="3">March</option>' . "\n" .
-'<option value="4">April</option>' . "\n" .
-'<option value="5">May</option>' . "\n" .
-'<option value="6">June</option>' . "\n" .
-'<option value="7">July</option>' . "\n" .
-'<option value="8">August</option>' . "\n" .
-'<option value="9">September</option>' . "\n" .
-'<option value="10">October</option>' . "\n" .
-'<option value="11">November</option>' . "\n" .
-'<option value="12">December</option></select>',
+                               '<option value="1">January</option>' . "\n" .
+                               '<option value="2" selected="">February</option>' . "\n" .
+                               '<option value="3">March</option>' . "\n" .
+                               '<option value="4">April</option>' . "\n" .
+                               '<option value="5">May</option>' . "\n" .
+                               '<option value="6">June</option>' . "\n" .
+                               '<option value="7">July</option>' . "\n" .
+                               '<option value="8">August</option>' . "\n" .
+                               '<option value="9">September</option>' . "\n" .
+                               '<option value="10">October</option>' . "\n" .
+                               '<option value="11">November</option>' . "\n" .
+                               '<option value="12">December</option></select>',
                        Xml::dateMenu( 2011, 02 ),
                        "Date menu for february 2011"
                );
                $this->assertEquals(
                        '<label for="year">From year (and earlier):</label> <input id="year" maxlength="4" size="7" type="number" value="2011" name="year" /> <label for="month">From month (and earlier):</label> <select id="month" name="month" class="mw-month-selector"><option value="-1">all</option>' . "\n" .
-'<option value="1">January</option>' . "\n" .
-'<option value="2">February</option>' . "\n" .
-'<option value="3">March</option>' . "\n" .
-'<option value="4">April</option>' . "\n" .
-'<option value="5">May</option>' . "\n" .
-'<option value="6">June</option>' . "\n" .
-'<option value="7">July</option>' . "\n" .
-'<option value="8">August</option>' . "\n" .
-'<option value="9">September</option>' . "\n" .
-'<option value="10">October</option>' . "\n" .
-'<option value="11">November</option>' . "\n" .
-'<option value="12">December</option></select>',
-                       Xml::dateMenu( 2011, -1),
+                               '<option value="1">January</option>' . "\n" .
+                               '<option value="2">February</option>' . "\n" .
+                               '<option value="3">March</option>' . "\n" .
+                               '<option value="4">April</option>' . "\n" .
+                               '<option value="5">May</option>' . "\n" .
+                               '<option value="6">June</option>' . "\n" .
+                               '<option value="7">July</option>' . "\n" .
+                               '<option value="8">August</option>' . "\n" .
+                               '<option value="9">September</option>' . "\n" .
+                               '<option value="10">October</option>' . "\n" .
+                               '<option value="11">November</option>' . "\n" .
+                               '<option value="12">December</option></select>',
+                       Xml::dateMenu( 2011, -1 ),
                        "Date menu with negative month for 'All'"
                );
                $this->assertEquals(
                        Xml::dateMenu( $curYear, $curMonth ),
-                       Xml::dateMenu( ''      , $curMonth ),
+                       Xml::dateMenu( '', $curMonth ),
                        "Date menu year is the current one when not specified"
                );
 
@@ -164,18 +169,18 @@ class XmlTest extends MediaWikiTestCase {
 
                $this->assertEquals(
                        '<label for="year">From year (and earlier):</label> <input id="year" maxlength="4" size="7" type="number" name="year" /> <label for="month">From month (and earlier):</label> <select id="month" name="month" class="mw-month-selector"><option value="-1">all</option>' . "\n" .
-'<option value="1">January</option>' . "\n" .
-'<option value="2">February</option>' . "\n" .
-'<option value="3">March</option>' . "\n" .
-'<option value="4">April</option>' . "\n" .
-'<option value="5">May</option>' . "\n" .
-'<option value="6">June</option>' . "\n" .
-'<option value="7">July</option>' . "\n" .
-'<option value="8">August</option>' . "\n" .
-'<option value="9">September</option>' . "\n" .
-'<option value="10">October</option>' . "\n" .
-'<option value="11">November</option>' . "\n" .
-'<option value="12">December</option></select>',
+                               '<option value="1">January</option>' . "\n" .
+                               '<option value="2">February</option>' . "\n" .
+                               '<option value="3">March</option>' . "\n" .
+                               '<option value="4">April</option>' . "\n" .
+                               '<option value="5">May</option>' . "\n" .
+                               '<option value="6">June</option>' . "\n" .
+                               '<option value="7">July</option>' . "\n" .
+                               '<option value="8">August</option>' . "\n" .
+                               '<option value="9">September</option>' . "\n" .
+                               '<option value="10">October</option>' . "\n" .
+                               '<option value="11">November</option>' . "\n" .
+                               '<option value="12">December</option></select>',
                        Xml::dateMenu( '', '' ),
                        "Date menu with neither year or month"
                );
@@ -210,6 +215,7 @@ class XmlTest extends MediaWikiTestCase {
                        'label() with no attribs'
                );
        }
+
        function testLabelAttributeCanOnlyBeClassOrTitle() {
                $this->assertEquals(
                        '<label for="id">name</label>',
@@ -229,10 +235,10 @@ class XmlTest extends MediaWikiTestCase {
                $this->assertEquals(
                        '<label for="id" class="nice" title="nice tooltip">name</label>',
                        Xml::label( 'name', 'id', array(
-                               'generated' => true,
-                               'class' => 'nice',
-                               'title' => 'nice tooltip',
-                               'anotherattr' => 'value',
+                                       'generated' => true,
+                                       'class' => 'nice',
+                                       'title' => 'nice tooltip',
+                                       'anotherattr' => 'value',
                                )
                        ),
                        'label() skip all attributes but "class" and "title"'
index 9a03d5c..3fea57a 100644 (file)
@@ -29,12 +29,12 @@ class ZipDirectoryReaderTest extends MediaWikiTestCase {
        }
 
        function testMultiDisk0() {
-               $this->readZipAssertError( 'split.zip', 'zip-unsupported', 
+               $this->readZipAssertError( 'split.zip', 'zip-unsupported',
                        'Split zip error' );
        }
 
        function testNoSignature() {
-               $this->readZipAssertError( 'nosig.zip', 'zip-wrong-format', 
+               $this->readZipAssertError( 'nosig.zip', 'zip-wrong-format',
                        'No signature should give "wrong format" error' );
        }
 
@@ -58,7 +58,7 @@ class ZipDirectoryReaderTest extends MediaWikiTestCase {
        }
 
        function testWrongCDStart() {
-               $this->readZipAssertError( 'wrong-cd-start-disk.zip', 'zip-unsupported', 
+               $this->readZipAssertError( 'wrong-cd-start-disk.zip', 'zip-unsupported',
                        'Wrong CD start disk error' );
        }
 
index 60f6537..f37e279 100644 (file)
@@ -142,7 +142,7 @@ class ApiCreateAccountTest extends ApiTestCase {
         */
        function testInvalidEmail() {
                global $wgEnableEmail;
-               if( !$wgEnableEmail ) {
+               if ( !$wgEnableEmail ) {
                        $this->markTestSkipped( 'email is not enabled, so createaccount does not check it' );
                }
                $this->doApiRequest( array(
index dd4d598..8f6b935 100644 (file)
@@ -45,7 +45,7 @@ class ApiBlockTest extends ApiTestCase {
                        $this->markTestIncomplete( "The user UTApiBlockee does not exist" );
                }
 
-               if( !isset( $data[0]['query']['pages'] ) ) {
+               if ( !isset( $data[0]['query']['pages'] ) ) {
                        $this->markTestIncomplete( "No block token found" );
                }
 
@@ -59,7 +59,7 @@ class ApiBlockTest extends ApiTestCase {
                        'reason' => 'Some reason',
                        'token' => $pageinfo['blocktoken'] ), null, false, self::$users['sysop']->user );
 
-               $block = Block::newFromTarget('UTApiBlockee');
+               $block = Block::newFromTarget( 'UTApiBlockee' );
 
                $this->assertTrue( !is_null( $block ), 'Block is valid' );
 
@@ -99,7 +99,7 @@ class ApiBlockTest extends ApiTestCase {
                                'action' => $action,
                                'user' => 'UTApiBlockee',
                                'reason' => 'Some reason',
-                               ),
+                       ),
                        null,
                        false,
                        self::$users['sysop']->user
@@ -111,7 +111,7 @@ class ApiBlockTest extends ApiTestCase {
         */
        function provideBlockUnblockAction() {
                return array(
-                       array( 'block'   ),
+                       array( 'block' ),
                        array( 'unblock' ),
                );
        }
index eaab300..da5eb33 100644 (file)
@@ -43,14 +43,15 @@ class ApiEditPageTest extends ApiTestCase {
                parent::teardown();
        }
 
-       function testEdit( ) {
+       function testEdit() {
                $name = 'Help:ApiEditPageTest_testEdit'; // assume Help namespace to default to wikitext
 
                // -- test new page --------------------------------------------
                $apiResult = $this->doApiRequestWithToken( array(
-                               'action' => 'edit',
-                               'title' => $name,
-                               'text' => 'some text', ) );
+                       'action' => 'edit',
+                       'title' => $name,
+                       'text' => 'some text',
+               ) );
                $apiResult = $apiResult[0];
 
                // Validate API result data
@@ -65,9 +66,10 @@ class ApiEditPageTest extends ApiTestCase {
 
                // -- test existing page, no change ----------------------------
                $data = $this->doApiRequestWithToken( array(
-                               'action' => 'edit',
-                               'title' => $name,
-                               'text' => 'some text', ) );
+                       'action' => 'edit',
+                       'title' => $name,
+                       'text' => 'some text',
+               ) );
 
                $this->assertEquals( 'Success', $data[0]['edit']['result'] );
 
@@ -76,9 +78,10 @@ class ApiEditPageTest extends ApiTestCase {
 
                // -- test existing page, with change --------------------------
                $data = $this->doApiRequestWithToken( array(
-                               'action' => 'edit',
-                               'title' => $name,
-                               'text' => 'different text' ) );
+                       'action' => 'edit',
+                       'title' => $name,
+                       'text' => 'different text'
+               ) );
 
                $this->assertEquals( 'Success', $data[0]['edit']['result'] );
 
@@ -94,7 +97,7 @@ class ApiEditPageTest extends ApiTestCase {
                );
        }
 
-       function testNonTextEdit( ) {
+       function testNonTextEdit() {
                $name = 'Dummy:ApiEditPageTest_testNonTextEdit';
                $data = serialize( 'some bla bla text' );
 
@@ -158,13 +161,13 @@ class ApiEditPageTest extends ApiTestCase {
                if ( $text !== null ) {
                        if ( $text === '' ) {
                                // can't create an empty page, so create it with some content
-                               list( $re,, ) = $this->doApiRequestWithToken( array(
+                               list( $re, , ) = $this->doApiRequestWithToken( array(
                                        'action' => 'edit',
                                        'title' => $name,
                                        'text' => '(dummy)', ) );
                        }
 
-                       list( $re,, ) = $this->doApiRequestWithToken( array(
+                       list( $re, , ) = $this->doApiRequestWithToken( array(
                                'action' => 'edit',
                                'title' => $name,
                                'text' => $text, ) );
@@ -173,7 +176,7 @@ class ApiEditPageTest extends ApiTestCase {
                }
 
                // -- try append/prepend --------------------------------------------
-               list( $re,, ) = $this->doApiRequestWithToken( array(
+               list( $re, , ) = $this->doApiRequestWithToken( array(
                        'action' => 'edit',
                        'title' => $name,
                        $op . 'text' => $append, ) );
@@ -221,12 +224,12 @@ class ApiEditPageTest extends ApiTestCase {
 
                // try to save edit, expect conflict
                try {
-                       list( $re,, ) = $this->doApiRequestWithToken( array(
+                       list( $re, , ) = $this->doApiRequestWithToken( array(
                                'action' => 'edit',
                                'title' => $name,
                                'text' => 'nix bar!',
                                'basetimestamp' => $baseTime,
-                               ), null, self::$users['sysop']->user );
+                       ), null, self::$users['sysop']->user );
 
                        $this->fail( 'edit conflict expected' );
                } catch ( UsageException $ex ) {
@@ -264,7 +267,7 @@ class ApiEditPageTest extends ApiTestCase {
                $this->forceRevisionDate( $rpage, '20120101020202' );
 
                // try to save edit; should work, because we follow the redirect
-               list( $re,, ) = $this->doApiRequestWithToken( array(
+               list( $re, , ) = $this->doApiRequestWithToken( array(
                        'action' => 'edit',
                        'title' => $rname,
                        'text' => 'nix bar!',
@@ -277,7 +280,7 @@ class ApiEditPageTest extends ApiTestCase {
 
                // try again, without following the redirect. Should fail.
                try {
-                       list( $re,, ) = $this->doApiRequestWithToken( array(
+                       list( $re, , ) = $this->doApiRequestWithToken( array(
                                'action' => 'edit',
                                'title' => $rname,
                                'text' => 'nix bar!',
@@ -326,7 +329,7 @@ class ApiEditPageTest extends ApiTestCase {
                $this->forceRevisionDate( $rpage, '20120101020202' );
 
                // try to save edit; should work, following the redirect.
-               list( $re,, ) = $this->doApiRequestWithToken( array(
+               list( $re, , ) = $this->doApiRequestWithToken( array(
                        'action' => 'edit',
                        'title' => $rname,
                        'text' => 'nix bar!',
index e5a8717..4a23eea 100644 (file)
@@ -28,20 +28,20 @@ class ApiGeneratorTest extends MediaWikiTestCase {
        ) {
                $generators = $this->getApiQuery()->getGenerators();
                $this->assertArrayHasKey( $moduleName, $generators,
-                       "API module '$moduleName' of class '$moduleClass' (an ApiQueryGeneratorBase subclass) must be listed in ApiQuery::\$mQueryGenerators or added to \$wgAPIGeneratorModules."
+                       "API module '$moduleName' of class '$moduleClass' (an ApiQueryGeneratorBase subclass) must be listed in ApiQuery::\$mQueryGenerators or added to \$wgAPIGeneratorModules."
                );
        }
 
        /**
         * Returns API modules which are subclassing ApiQueryGeneratorBase.
         * Case format is:
-        *      (moduleName, moduleClass)
+        *     (moduleName, moduleClass)
         */
        public function provideApiquerygeneratorbaseChilds() {
                $cases = array();
-               $modules = $this->getApiQuery()->getModules();
-               foreach( $modules as $moduleName => $moduleClass ) {
-                       if( !is_subclass_of( $moduleClass, 'ApiQueryGeneratorBase' ) ) {
+               $modules = $this->getApiQuery()->getModuleManager()->getNamesWithClasses();
+               foreach ( $modules as $moduleName => $moduleClass ) {
+                       if ( !is_subclass_of( $moduleClass, 'ApiQueryGeneratorBase' ) ) {
                                continue;
                        }
                        $cases[] = array( $moduleName, $moduleClass );
@@ -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."
                );
@@ -71,7 +71,7 @@ class ApiGeneratorTest extends MediaWikiTestCase {
        public function provideListedApiqueryGenerators() {
                $cases = array();
                $generators = $this->getApiQuery()->getGenerators();
-               foreach( $generators as $generatorName => $generatorClass ) {
+               foreach ( $generators as $generatorName => $generatorClass ) {
                        $cases[] = array( $generatorName, $generatorClass );
                }
                return $cases;
index 93ff24a..a42e5aa 100644 (file)
@@ -21,7 +21,7 @@ class ApiParseTest extends ApiTestCase {
                                'page' => $somePage ) );
 
                        $this->fail( "API did not return an error when parsing a nonexistent page" );
-               } catch(UsageException $ex){
+               } catch ( UsageException $ex ) {
                        $this->assertEquals( 'missingtitle', $ex->getCodeString(),
                                "Parse request for nonexistent page must give 'missingtitle' error: " . var_export( $ex->getMessageArray(), true ) );
                }
index 3ab77fd..a7f9229 100644 (file)
@@ -33,7 +33,7 @@ class ApiPurgeTest extends ApiTestCase {
                        "Purge request for three articles should give back three results received: " . var_export( $data[0]['purge'], true ) );
 
                $pages = array( 'UTPage' => 'purged', $somePage => 'missing', '%5D' => 'invalid' );
-               foreach( $data[0]['purge'] as $v ) {
+               foreach ( $data[0]['purge'] as $v ) {
                        $this->assertArrayHasKey( $pages[$v['title']], $v );
                }
        }
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 2f2f5f9..2277028 100644 (file)
@@ -12,7 +12,7 @@ class ApiTest extends ApiTestCase {
 
                $this->assertEquals(
                        null, $mock->requireOnlyOneParameter( array( "filename" => "foo.txt",
-                               "enablechunks" => false ), "filename", "enablechunks" ) );
+                       "enablechunks" => false ), "filename", "enablechunks" ) );
        }
 
        /**
@@ -23,7 +23,7 @@ class ApiTest extends ApiTestCase {
 
                $this->assertEquals(
                        null, $mock->requireOnlyOneParameter( array( "filename" => "foo.txt",
-                               "enablechunks" => 0 ), "filename", "enablechunks" ) );
+                       "enablechunks" => 0 ), "filename", "enablechunks" ) );
        }
 
        /**
@@ -34,7 +34,7 @@ class ApiTest extends ApiTestCase {
 
                $this->assertEquals(
                        null, $mock->requireOnlyOneParameter( array( "filename" => "foo.txt",
-                               "enablechunks" => true ), "filename", "enablechunks" ) );
+                       "enablechunks" => true ), "filename", "enablechunks" ) );
        }
 
        /**
@@ -92,12 +92,14 @@ class ApiTest extends ApiTestCase {
 
                $token = $result["login"]["token"];
 
-               $ret = $this->doApiRequest( array(
-                       "action" => "login",
-                       "lgtoken" => $token,
-                       "lgname" => $user->username,
-                       "lgpassword" => "badnowayinhell",
-                       ), $ret[2]
+               $ret = $this->doApiRequest(
+                       array(
+                               "action" => "login",
+                               "lgtoken" => $token,
+                               "lgname" => $user->username,
+                               "lgpassword" => "badnowayinhell",
+                       ),
+                       $ret[2]
                );
 
                $result = $ret[0];
@@ -119,9 +121,9 @@ class ApiTest extends ApiTestCase {
                $user->user->logOut();
 
                $ret = $this->doApiRequest( array(
-                       "action" => "login",
-                       "lgname" => $user->username,
-                       "lgpassword" => $user->password,
+                               "action" => "login",
+                               "lgname" => $user->username,
+                               "lgpassword" => $user->password,
                        )
                );
 
@@ -133,12 +135,14 @@ class ApiTest extends ApiTestCase {
                $this->assertEquals( "NeedToken", $a );
                $token = $result["login"]["token"];
 
-               $ret = $this->doApiRequest( array(
-                       "action" => "login",
-                       "lgtoken" => $token,
-                       "lgname" => $user->username,
-                       "lgpassword" => $user->password,
-                       ), $ret[2]
+               $ret = $this->doApiRequest(
+                       array(
+                               "action" => "login",
+                               "lgtoken" => $token,
+                               "lgname" => $user->username,
+                               "lgpassword" => $user->password,
+                       ),
+                       $ret[2]
                );
 
                $result = $ret[0];
@@ -153,7 +157,7 @@ class ApiTest extends ApiTestCase {
         * @group Broken
         */
        function testApiGotCookie() {
-               $this->markTestIncomplete( "The server can't do external HTTP requests, and the internal one won't give cookies"  );
+               $this->markTestIncomplete( "The server can't do external HTTP requests, and the internal one won't give cookies" );
 
                global $wgServer, $wgScriptPath;
 
@@ -165,8 +169,11 @@ class ApiTest extends ApiTestCase {
                $req = MWHttpRequest::factory( self::$apiUrl . "?action=login&format=xml",
                        array( "method" => "POST",
                                "postData" => array(
-                               "lgname" => $user->username,
-                               "lgpassword" => $user->password ) ) );
+                                       "lgname" => $user->username,
+                                       "lgpassword" => $user->password
+                               )
+                       )
+               );
                $req->execute();
 
                libxml_use_internal_errors( true );
index fcd581a..552fbfb 100644 (file)
@@ -1,4 +1,4 @@
-<?php 
+<?php
 
 abstract class ApiTestCase extends MediaWikiLangTestCase {
        protected static $apiUrl;
@@ -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;
@@ -129,12 +145,15 @@ abstract class ApiTestCase extends MediaWikiLangTestCase {
 
                $token = $data[0]['login']['token'];
 
-               $data = $this->doApiRequest( array(
-                       'action' => 'login',
-                       'lgtoken' => $token,
-                       'lgname' => self::$users['sysop']->username,
-                       'lgpassword' => self::$users['sysop']->password
-                       ), $data[2] );
+               $data = $this->doApiRequest(
+                       array(
+                               'action' => 'login',
+                               'lgtoken' => $token,
+                               'lgname' => self::$users['sysop']->username,
+                               'lgpassword' => self::$users['sysop']->password,
+                       ),
+                       $data[2]
+               );
 
                return $data;
        }
@@ -161,7 +180,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;
@@ -183,10 +204,11 @@ class UserWrapper {
 }
 
 class MockApi extends ApiBase {
-       public function execute() { }
-       public function getVersion() { }
+       public function execute() {}
+
+       public function getVersion() {}
 
-       public function __construct() { }
+       public function __construct() {}
 
        public function getAllowedParams() {
                return array(
index 458bea4..8028491 100644 (file)
@@ -47,7 +47,7 @@ abstract class ApiTestCaseUpload extends ApiTestCase {
                        // see if it now doesn't exist; reload
                        $title = Title::newFromText( $title->getText(), NS_FILE );
                }
-               return ! ( $title && $title instanceof Title && $title->exists() );
+               return !( $title && $title instanceof Title && $title->exists() );
        }
 
        /**
@@ -84,7 +84,7 @@ abstract class ApiTestCaseUpload extends ApiTestCase {
                $tmpName = tempnam( wfTempDir(), "" );
                if ( !file_exists( $filePath ) ) {
                        throw new Exception( "$filePath doesn't exist!" );
-               };
+               }
 
                if ( !copy( $filePath, $tmpName ) ) {
                        throw new Exception( "couldn't copy $filePath to $tmpName" );
@@ -96,19 +96,19 @@ abstract class ApiTestCaseUpload extends ApiTestCase {
                        throw new Exception( "couldn't stat $tmpName" );
                }
 
-               $_FILES[ $fieldName ] = array(
-                       'name'          => $fileName,
-                       'type'          => $type,
-                       'tmp_name'      => $tmpName,
-                       'size'          => $size,
-                       'error'         => null
+               $_FILES[$fieldName] = array(
+                       'name' => $fileName,
+                       'type' => $type,
+                       'tmp_name' => $tmpName,
+                       'size' => $size,
+                       'error' => null
                );
 
                return true;
 
        }
 
-       function fakeUploadChunk(  $fieldName, $fileName, $type, & $chunkData ) {
+       function fakeUploadChunk( $fieldName, $fileName, $type, & $chunkData ) {
                $tmpName = tempnam( wfTempDir(), "" );
                // copy the chunk data to temp location:
                if ( !file_put_contents( $tmpName, $chunkData ) ) {
@@ -121,19 +121,19 @@ abstract class ApiTestCaseUpload extends ApiTestCase {
                        throw new Exception( "couldn't stat $tmpName" );
                }
 
-               $_FILES[ $fieldName ] = array(
-                       'name'          => $fileName,
-                       'type'          => $type,
-                       'tmp_name'      => $tmpName,
-                       'size'          => $size,
-                       'error'         => null
+               $_FILES[$fieldName] = array(
+                       'name' => $fileName,
+                       'type' => $type,
+                       'tmp_name' => $tmpName,
+                       'size' => $size,
+                       'error' => null
                );
        }
 
        function clearTempUpload() {
-               if( isset( $_FILES['file']['tmp_name'] ) ) {
+               if ( isset( $_FILES['file']['tmp_name'] ) ) {
                        $tmp = $_FILES['file']['tmp_name'];
-                       if( file_exists( $tmp ) ) {
+                       if ( file_exists( $tmp ) ) {
                                unlink( $tmp );
                        }
                }
index 642fed0..0d98b04 100644 (file)
@@ -107,8 +107,7 @@ class ApiUploadTest extends ApiTestCaseUpload {
                try {
                        $randomImageGenerator = new RandomImageGenerator();
                        $filePaths = $randomImageGenerator->writeImages( 1, $extension, wfTempDir() );
-               }
-               catch ( Exception $e ) {
+               } catch ( Exception $e ) {
                        $this->markTestIncomplete( $e->getMessage() );
                }
 
@@ -120,7 +119,7 @@ class ApiUploadTest extends ApiTestCaseUpload {
                $this->deleteFileByContent( $filePath );
 
 
-               if ($this->fakeUploadFile( 'file', $fileName, $mimeType, $filePath ) ) {
+               if ( !$this->fakeUploadFile( 'file', $fileName, $mimeType, $filePath ) ) {
                        $this->markTestIncomplete( "Couldn't upload file!\n" );
                }
 
@@ -129,7 +128,7 @@ class ApiUploadTest extends ApiTestCaseUpload {
                        'filename' => $fileName,
                        'file' => 'dummy content',
                        'comment' => 'dummy comment',
-                       'text'  => "This is the page text for $fileName",
+                       'text' => "This is the page text for $fileName",
                );
 
                $exception = false;
@@ -162,7 +161,7 @@ class ApiUploadTest extends ApiTestCaseUpload {
 
                $this->deleteFileByFileName( $fileName );
 
-               if ($this->fakeUploadFile( 'file', $fileName, $mimeType, $filePath ) ) {
+               if ( !$this->fakeUploadFile( 'file', $fileName, $mimeType, $filePath ) ) {
                        $this->markTestIncomplete( "Couldn't upload file!\n" );
                }
 
@@ -171,7 +170,7 @@ class ApiUploadTest extends ApiTestCaseUpload {
                        'filename' => $fileName,
                        'file' => 'dummy content',
                        'comment' => 'dummy comment',
-                       'text'  => "This is the page text for $fileName",
+                       'text' => "This is the page text for $fileName",
                );
 
                $exception = false;
@@ -199,8 +198,7 @@ class ApiUploadTest extends ApiTestCaseUpload {
                try {
                        $randomImageGenerator = new RandomImageGenerator();
                        $filePaths = $randomImageGenerator->writeImages( 2, $extension, wfTempDir() );
-               }
-               catch ( Exception $e ) {
+               } catch ( Exception $e ) {
                        $this->markTestIncomplete( $e->getMessage() );
                }
 
@@ -216,12 +214,12 @@ class ApiUploadTest extends ApiTestCaseUpload {
                        'filename' => $fileName,
                        'file' => 'dummy content',
                        'comment' => 'dummy comment',
-                       'text'  => "This is the page text for $fileName",
+                       'text' => "This is the page text for $fileName",
                );
 
                // first upload .... should succeed
 
-               if ($this->fakeUploadFile( 'file', $fileName, $mimeType, $filePaths[0] ) ) {
+               if ( !$this->fakeUploadFile( 'file', $fileName, $mimeType, $filePaths[0] ) ) {
                        $this->markTestIncomplete( "Couldn't upload file!\n" );
                }
 
@@ -238,7 +236,7 @@ class ApiUploadTest extends ApiTestCaseUpload {
 
                // second upload with the same name (but different content)
 
-               if ($this->fakeUploadFile( 'file', $fileName, $mimeType, $filePaths[1] ) ) {
+               if ( !$this->fakeUploadFile( 'file', $fileName, $mimeType, $filePaths[1] ) ) {
                        $this->markTestIncomplete( "Couldn't upload file!\n" );
                }
 
@@ -272,8 +270,7 @@ class ApiUploadTest extends ApiTestCaseUpload {
                try {
                        $randomImageGenerator = new RandomImageGenerator();
                        $filePaths = $randomImageGenerator->writeImages( 1, $extension, wfTempDir() );
-               }
-               catch ( Exception $e ) {
+               } catch ( Exception $e ) {
                        $this->markTestIncomplete( $e->getMessage() );
                }
 
@@ -292,10 +289,10 @@ class ApiUploadTest extends ApiTestCaseUpload {
                        'filename' => $fileNames[0],
                        'file' => 'dummy content',
                        'comment' => 'dummy comment',
-                       'text'  => "This is the page text for " . $fileNames[0],
+                       'text' => "This is the page text for " . $fileNames[0],
                );
 
-               if ($this->fakeUploadFile( 'file', $fileNames[0], $mimeType, $filePaths[0] ) ) {
+               if ( !$this->fakeUploadFile( 'file', $fileNames[0], $mimeType, $filePaths[0] ) ) {
                        $this->markTestIncomplete( "Couldn't upload file!\n" );
                }
 
@@ -313,7 +310,7 @@ class ApiUploadTest extends ApiTestCaseUpload {
 
                // second upload with the same content (but different name)
 
-               if ($this->fakeUploadFile( 'file', $fileNames[1], $mimeType, $filePaths[0] ) ) {
+               if ( !$this->fakeUploadFile( 'file', $fileNames[1], $mimeType, $filePaths[0] ) ) {
                        $this->markTestIncomplete( "Couldn't upload file!\n" );
                }
 
@@ -322,7 +319,7 @@ class ApiUploadTest extends ApiTestCaseUpload {
                        'filename' => $fileNames[1],
                        'file' => 'dummy content',
                        'comment' => 'dummy comment',
-                       'text'  => "This is the page text for " . $fileNames[1],
+                       'text' => "This is the page text for " . $fileNames[1],
                );
 
                $exception = false;
@@ -349,8 +346,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';
@@ -358,8 +356,7 @@ class ApiUploadTest extends ApiTestCaseUpload {
                try {
                        $randomImageGenerator = new RandomImageGenerator();
                        $filePaths = $randomImageGenerator->writeImages( 1, $extension, wfTempDir() );
-               }
-               catch ( Exception $e ) {
+               } catch ( Exception $e ) {
                        $this->markTestIncomplete( $e->getMessage() );
                }
 
@@ -370,17 +367,17 @@ class ApiUploadTest extends ApiTestCaseUpload {
                $this->deleteFileByFileName( $fileName );
                $this->deleteFileByContent( $filePath );
 
-               if ($this->fakeUploadFile( 'file', $fileName, $mimeType, $filePath ) ) {
+               if ( !$this->fakeUploadFile( 'file', $fileName, $mimeType, $filePath ) ) {
                        $this->markTestIncomplete( "Couldn't upload file!\n" );
                }
 
                $params = array(
                        'action' => 'upload',
-                       'stash' => 1,
+                       'stash' => 1,
                        'filename' => $fileName,
                        'file' => 'dummy content',
                        'comment' => 'dummy comment',
-                       'text'  => "This is the page text for $fileName",
+                       'text' => "This is the page text for $fileName",
                );
 
                $exception = false;
@@ -408,7 +405,7 @@ class ApiUploadTest extends ApiTestCaseUpload {
                        'filekey' => $filekey,
                        'filename' => $fileName,
                        'comment' => 'dummy comment',
-                       'text'  => "This is the page text for $fileName, altered",
+                       'text' => "This is the page text for $fileName, altered",
                );
 
                $this->clearFakeUploads();
@@ -427,15 +424,15 @@ class ApiUploadTest extends ApiTestCaseUpload {
                $this->deleteFileByFilename( $fileName );
                unlink( $filePath );
        }
-       
-       
+
        /**
         * @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 )
@@ -444,11 +441,10 @@ class ApiUploadTest extends ApiTestCaseUpload {
                $filePath = wfTempDir() . '/Oberaargletscher_from_Oberaar.jpg';
                try {
                        // Only download if the file is not avaliable in the temp location:
-                       if( !is_file( $filePath ) ){
-                               copy($url, $filePath); 
+                       if ( !is_file( $filePath ) ) {
+                               copy( $url, $filePath );
                        }
-               }
-               catch ( Exception $e ) {
+               } catch ( Exception $e ) {
                        $this->markTestIncomplete( $e->getMessage() );
                }
 
@@ -461,29 +457,29 @@ class ApiUploadTest extends ApiTestCaseUpload {
                // Base upload params: 
                $params = array(
                        'action' => 'upload',
-                       'stash' => 1,
+                       'stash' => 1,
                        'filename' => $fileName,
                        'filesize' => $fileSize,
                        'offset' => 0,
                );
-               
+
                // Upload chunks
                $chunkSessionKey = false;
                $resultOffset = 0;
                // Open the file: 
-               $handle = @fopen ($filePath, "r");
-               if( $handle === false ){
+               $handle = @fopen( $filePath, "r" );
+               if ( $handle === false ) {
                        $this->markTestIncomplete( "could not open file: $filePath" );
                }
-               while (!feof ($handle)) {
+               while ( !feof( $handle ) ) {
                        // Get the current chunk
                        $chunkData = @fread( $handle, $chunkSize );
 
                        // Upload the current chunk into the $_FILE object:
                        $this->fakeUploadChunk( 'chunk', 'blob', $mimeType, $chunkData );
-                       
+
                        // Check for chunkSessionKey
-                       if( !$chunkSessionKey ){
+                       if ( !$chunkSessionKey ) {
                                // Upload fist chunk ( and get the session key )
                                try {
                                        list( $result, $request, $session ) = $this->doApiRequestWithToken( $params, $session,
@@ -495,7 +491,7 @@ class ApiUploadTest extends ApiTestCaseUpload {
                                $this->assertTrue( isset( $result['upload'] ) );
                                $this->assertTrue( isset( $result['upload']['filekey'] ) );
                                // If we don't get a session key mark test incomplete. 
-                               if( ! isset( $result['upload']['filekey'] ) ){
+                               if ( !isset( $result['upload']['filekey'] ) ) {
                                        $this->markTestIncomplete( "no filekey provided" );
                                }
                                $chunkSessionKey = $result['upload']['filekey'];
@@ -521,9 +517,9 @@ class ApiUploadTest extends ApiTestCaseUpload {
                        // Make sure we got a valid chunk continue: 
                        $this->assertTrue( isset( $result['upload'] ) );
                        $this->assertTrue( isset( $result['upload']['filekey'] ) );
-                       
+
                        // Check if we were on the last chunk: 
-                       if( $params['offset'] + $chunkSize >=  $fileSize ){
+                       if ( $params['offset'] + $chunkSize >= $fileSize ) {
                                $this->assertEquals( 'Success', $result['upload']['result'] );
                                break;
                        } else {
@@ -531,11 +527,11 @@ class ApiUploadTest extends ApiTestCaseUpload {
                                // update $resultOffset
                                $resultOffset = $result['upload']['offset'];
                        }
-               } 
-               fclose ($handle); 
-        
+               }
+               fclose( $handle );
+
                // Check that we got a valid file result:
-               wfDebug( __METHOD__ . " hohoh filesize {$fileSize} info {$result['upload']['imageinfo']['size']}\n\n");
+               wfDebug( __METHOD__ . " hohoh filesize {$fileSize} info {$result['upload']['imageinfo']['size']}\n\n" );
                $this->assertEquals( $fileSize, $result['upload']['imageinfo']['size'] );
                $this->assertEquals( $mimeType, $result['upload']['imageinfo']['mime'] );
                $this->assertTrue( isset( $result['upload']['filekey'] ) );
@@ -547,7 +543,7 @@ class ApiUploadTest extends ApiTestCaseUpload {
                        'filekey' => $filekey,
                        'filename' => $fileName,
                        'comment' => 'dummy comment',
-                       'text'  => "This is the page text for $fileName, altered",
+                       'text' => "This is the page text for $fileName, altered",
                );
                $this->clearFakeUploads();
                $exception = false;
index 4fecec0..aefd939 100644 (file)
@@ -147,8 +147,8 @@ class ApiWatchTest extends ApiTestCase {
 
                        $this->assertArrayHasKey( 'rollback', $data[0] );
                        $this->assertArrayHasKey( 'title', $data[0]['rollback'] );
-               } catch( UsageException $ue ) {
-                       if( $ue->getCodeString() == 'onlyauthor' ) {
+               } catch ( UsageException $ue ) {
+                       if ( $ue->getCodeString() == 'onlyauthor' ) {
                                $this->markTestIncomplete( "Only one author to 'Help:UTPage', cannot test rollback" );
                        } else {
                                $this->fail( "Received error '" . $ue->getCodeString() . "'" );
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 ) {
index 8b6a384..3040758 100644 (file)
 class RandomImageGenerator {
 
        private $dictionaryFile;
-       private $minWidth     = 400 ;
-       private $maxWidth     = 800 ;
-       private $minHeight    = 400 ;
-       private $maxHeight    = 800 ;
-       private $shapesToDraw =   5 ;
+       private $minWidth = 400;
+       private $maxWidth = 800;
+       private $minHeight = 400;
+       private $maxHeight = 800;
+       private $shapesToDraw = 5;
 
        /**
         * Orientations: 0th row, 0th column, EXIF orientation code, rotation 2x2 matrix that is opposite of orientation
@@ -76,11 +76,13 @@ class RandomImageGenerator {
 
                // find the dictionary file, to generate random names
                if ( !isset( $this->dictionaryFile ) ) {
-                       foreach ( array(
+                       foreach (
+                               array(
                                        '/usr/share/dict/words',
                                        '/usr/dict/words',
-                                       __DIR__ . '/words.txt' )
-                                       as $dictionaryFile ) {
+                                       __DIR__ . '/words.txt'
+                               ) as $dictionaryFile
+                       ) {
                                if ( is_file( $dictionaryFile ) and is_readable( $dictionaryFile ) ) {
                                        $this->dictionaryFile = $dictionaryFile;
                                        break;
@@ -103,7 +105,7 @@ class RandomImageGenerator {
        function writeImages( $number, $format = 'jpg', $dir = null ) {
                $filenames = $this->getRandomFilenames( $number, $format, $dir );
                $imageWriteMethod = $this->getImageWriteMethod( $format );
-               foreach( $filenames as $filename ) {
+               foreach ( $filenames as $filename ) {
                        $this->{$imageWriteMethod}( $this->getImageSpec(), $format, $filename );
                }
                return $filenames;
@@ -144,7 +146,7 @@ class RandomImageGenerator {
                        $dir = getcwd();
                }
                $filenames = array();
-               foreach( $this->getRandomWordPairs( $number ) as $pair ) {
+               foreach ( $this->getRandomWordPairs( $number ) as $pair ) {
                        $basename = $pair[0] . '_' . $pair[1];
                        if ( !is_null( $extension ) ) {
                                $basename .= '.' . $extension;
@@ -181,17 +183,17 @@ class RandomImageGenerator {
                        }
                        $originX = mt_rand( -1 * $radius, $spec['width'] + $radius );
                        $originY = mt_rand( -1 * $radius, $spec['height'] + $radius );
-                       $angle = mt_rand( 0, ( 3.141592/2 ) * $radius ) / $radius;
+                       $angle = mt_rand( 0, ( 3.141592 / 2 ) * $radius ) / $radius;
                        $legDeltaX = round( $radius * sin( $angle ) );
                        $legDeltaY = round( $radius * cos( $angle ) );
 
                        $draw = array();
                        $draw['fill'] = $this->getRandomColor();
                        $draw['shape'] = array(
-                               array( 'x' => $originX,                 'y' => $originY - $radius ),
-                               array( 'x' => $originX + $legDeltaX,    'y' => $originY + $legDeltaY ),
-                               array( 'x' => $originX - $legDeltaX,    'y' => $originY + $legDeltaY ),
-                               array( 'x' => $originX,                 'y' => $originY - $radius )
+                               array( 'x' => $originX, 'y' => $originY - $radius ),
+                               array( 'x' => $originX + $legDeltaX, 'y' => $originY + $legDeltaY ),
+                               array( 'x' => $originX - $legDeltaX, 'y' => $originY + $legDeltaY ),
+                               array( 'x' => $originX, 'y' => $originY - $radius )
                        );
                        $draws[] = $draw;
 
@@ -235,12 +237,13 @@ class RandomImageGenerator {
                        $shape = $g->addChild( 'polygon' );
                        $shape->addAttribute( 'fill', $drawSpec['fill'] );
                        $shape->addAttribute( 'points', self::shapePointsToString( $drawSpec['shape'] ) );
-               };
-               if ( ! $fh = fopen( $filename, 'w' ) ) {
+               }
+
+               if ( !$fh = fopen( $filename, 'w' ) ) {
                        throw new Exception( "couldn't open $filename for writing" );
                }
                fwrite( $fh, $svg->asXML() );
-               if ( !fclose($fh) ) {
+               if ( !fclose( $fh ) ) {
                        throw new Exception( "couldn't close $filename" );
                }
        }
@@ -262,7 +265,7 @@ class RandomImageGenerator {
                 */
                $orientation = self::$orientations[0]; // default is normal orientation
                if ( $format == 'jpg' ) {
-                       $orientation = self::$orientations[ array_rand( self::$orientations ) ];
+                       $orientation = self::$orientations[array_rand( self::$orientations )];
                        $spec = self::rotateImageSpec( $spec, $orientation['counterRotation'] );
                }
 
@@ -321,12 +324,12 @@ class RandomImageGenerator {
                $tSpec['height'] = abs( $dims['y'] );
                $tSpec['fill'] = $spec['fill'];
                $tSpec['draws'] = array();
-               foreach( $spec['draws'] as $draw ) {
+               foreach ( $spec['draws'] as $draw ) {
                        $tDraw = array(
                                'fill' => $draw['fill'],
                                'shape' => array()
                        );
-                       foreach( $draw['shape'] as $point ) {
+                       foreach ( $draw['shape'] as $point ) {
                                $tPoint = self::matrixMultiply2x2( $matrix, $point['x'], $point['y'] );
                                $tPoint['x'] += $correctionX;
                                $tPoint['y'] += $correctionY;
@@ -357,7 +360,7 @@ class RandomImageGenerator {
         *
         * Sample command line:
         *  $ convert -size 100x60 xc:rgb(90,87,45) \
-        *       -draw 'fill rgb(12,34,56)   polygon 41,39 44,57 50,57 41,39' \
+        *      -draw 'fill rgb(12,34,56)   polygon 41,39 44,57 50,57 41,39' \
         *   -draw 'fill rgb(99,123,231) circle 59,39 56,57' \
         *   -draw 'fill rgb(240,12,32)  circle 50,21 50,3'  filename.png
         *
@@ -370,7 +373,7 @@ class RandomImageGenerator {
                $args = array();
                $args[] = "-size " . wfEscapeShellArg( $spec['width'] . 'x' . $spec['height'] );
                $args[] = wfEscapeShellArg( "xc:" . $spec['fill'] );
-               foreach( $spec['draws'] as $draw ) {
+               foreach ( $spec['draws'] as $draw ) {
                        $fill = $draw['fill'];
                        $polygon = self::shapePointsToString( $draw['shape'] );
                        $drawCommand = "fill $fill  polygon $polygon";
@@ -391,10 +394,10 @@ class RandomImageGenerator {
         */
        public function getRandomColor() {
                $components = array();
-               for ($i = 0; $i <= 2; $i++ ) {
+               for ( $i = 0; $i <= 2; $i++ ) {
                        $components[] = mt_rand( 0, 255 );
                }
-               return 'rgb(' . join(', ', $components) . ')';
+               return 'rgb(' . join( ', ', $components ) . ')';
        }
 
        /**
@@ -408,13 +411,12 @@ class RandomImageGenerator {
                // construct pairs of words
                $pairs = array();
                $count = count( $lines );
-               for( $i = 0; $i < $count; $i += 2 )  {
-                       $pairs[] = array( $lines[$i], $lines[$i+1] );
+               for ( $i = 0; $i < $count; $i += 2 ) {
+                       $pairs[] = array( $lines[$i], $lines[$i + 1] );
                }
                return $pairs;
        }
 
-
        /**
         * Return N random lines from a file
         *
@@ -438,17 +440,17 @@ class RandomImageGenerator {
                 */
                $fh = fopen( $filepath, "r" );
                if ( !$fh ) {
-                        throw new Exception( "couldn't open $filepath" );
+                       throw new Exception( "couldn't open $filepath" );
                }
                $line_number = 0;
                $max_index = $number_desired - 1;
-               while( !feof( $fh ) ) {
+               while ( !feof( $fh ) ) {
                        $line = fgets( $fh );
                        if ( $line !== false ) {
                                $line_number++;
                                $line = trim( $line );
                                if ( mt_rand( 0, $line_number ) <= $max_index ) {
-                                       $lines[ mt_rand( 0, $max_index ) ] = $line;
+                                       $lines[mt_rand( 0, $max_index )] = $line;
                                }
                        }
                }
index a0b7b02..153f2cf 100644 (file)
@@ -5,7 +5,7 @@ abstract class ApiFormatTestBase extends ApiTestCase {
                $data = parent::doApiRequest( $params, $data, true );
 
                $module = $data[3];
-               
+
                $printer = $module->createPrinterByName( $format );
                $printer->setUnescapeAmps( false );
 
@@ -14,7 +14,7 @@ abstract class ApiFormatTestBase extends ApiTestCase {
                ob_start();
                $printer->execute();
                $out = ob_get_clean();
-               
+
                $printer->closePrinter();
 
                return $out;
index a054283..cba8312 100644 (file)
@@ -10,7 +10,7 @@ $IP = dirname( dirname( dirname( dirname( __DIR__ ) ) ) );
 
 // Start up MediaWiki in command-line mode
 require_once( "$IP/maintenance/Maintenance.php" );
-require(  __DIR__ . "/RandomImageGenerator.php" );
+require( __DIR__ . "/RandomImageGenerator.php" );
 
 class GenerateRandomImages extends Maintenance {
 
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..a5ca256
--- /dev/null
@@ -0,0 +1,391 @@
+<?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..7f5fe91
--- /dev/null
@@ -0,0 +1,39 @@
+<?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..7fb5307
--- /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 52cdc78..ee3db3e 100644 (file)
@@ -15,7 +15,7 @@ class GenderCacheTest extends MediaWikiLangTestCase {
 
        function addDBData() {
                $user = User::newFromName( 'UTMale' );
-               if( $user->getID() == 0 ) {
+               if ( $user->getID() == 0 ) {
                        $user->addToDatabase();
                        $user->setPassword( 'UTMalePassword' );
                }
@@ -24,7 +24,7 @@ class GenderCacheTest extends MediaWikiLangTestCase {
                $user->saveSettings();
 
                $user = User::newFromName( 'UTFemale' );
-               if( $user->getID() == 0 ) {
+               if ( $user->getID() == 0 ) {
                        $user->addToDatabase();
                        $user->setPassword( 'UTFemalePassword' );
                }
@@ -33,7 +33,7 @@ class GenderCacheTest extends MediaWikiLangTestCase {
                $user->saveSettings();
 
                $user = User::newFromName( 'UTDefaultGender' );
-               if( $user->getID() == 0 ) {
+               if ( $user->getID() == 0 ) {
                        $user->addToDatabase();
                        $user->setPassword( 'UTDefaultGenderPassword' );
                }
index 1c081b8..c7e75d9 100644 (file)
@@ -24,7 +24,7 @@ class ProcessCacheLRUTest extends MediaWikiTestCase {
         */
        function fillCache( &$cache, $numEntries ) {
                // Fill cache with three values
-               for( $i=1; $i<=$numEntries; $i++) {
+               for ( $i = 1; $i <= $numEntries; $i++ ) {
                        $cache->set( "cache-key-$i", "prop-$i", "value-$i" );
                }
        }
@@ -36,10 +36,10 @@ class ProcessCacheLRUTest extends MediaWikiTestCase {
        function getExpectedCache( $cacheMaxEntries, $entryToFill ) {
                $expected = array();
 
-               if( $entryToFill === 0 ) {
+               if ( $entryToFill === 0 ) {
                        # The cache is empty!
                        return array();
-               } elseif( $entryToFill <= $cacheMaxEntries ) {
+               } elseif ( $entryToFill <= $cacheMaxEntries ) {
                        # Cache is not fully filled
                        $firstKey = 1;
                } else {
@@ -47,9 +47,9 @@ class ProcessCacheLRUTest extends MediaWikiTestCase {
                        $firstKey = 1 + $entryToFill - $cacheMaxEntries;
                }
 
-               $lastKey  = $entryToFill;
+               $lastKey = $entryToFill;
 
-               for( $i=$firstKey; $i<=$lastKey; $i++ ) {
+               for ( $i = $firstKey; $i <= $lastKey; $i++ ) {
                        $expected["cache-key-$i"] = array( "prop-$i" => "value-$i" );
                }
                return $expected;
@@ -61,7 +61,7 @@ class ProcessCacheLRUTest extends MediaWikiTestCase {
        function testPhpUnitArrayEquality() {
                $one = array( 'A' => 1, 'B' => 2 );
                $two = array( 'B' => 2, 'A' => 1 );
-               $this->assertEquals( $one, $two );  // ==
+               $this->assertEquals( $one, $two ); // ==
                $this->assertNotSame( $one, $two ); // ===
        }
 
@@ -118,7 +118,7 @@ class ProcessCacheLRUTest extends MediaWikiTestCase {
         */
        function testFillingCache( $cacheMaxEntries, $entryToFill, $msg = '' ) {
                $cache = new ProcessCacheLRUTestable( $cacheMaxEntries );
-               $this->fillCache( $cache, $entryToFill);
+               $this->fillCache( $cache, $entryToFill );
 
                $this->assertSame(
                        $this->getExpectedCache( $cacheMaxEntries, $entryToFill ),
@@ -134,12 +134,11 @@ class ProcessCacheLRUTest extends MediaWikiTestCase {
        public static function provideCacheFilling() {
                // ($cacheMaxEntries, $entryToFill, $msg='')
                return array(
-                       array( 1,  0 ),
-                       array( 1,  1 ),
-                       array( 1,  2 ), # overflow
+                       array( 1, 0 ),
+                       array( 1, 1 ),
+                       array( 1, 2 ), # overflow
                        array( 5, 33 ), # overflow
                );
-
        }
 
        /**
@@ -167,7 +166,7 @@ class ProcessCacheLRUTest extends MediaWikiTestCase {
 
        function testRecentlyAccessedKeyStickIn() {
                $cache = new ProcessCacheLRUTestable( 2 );
-               $cache->set( 'first' , 'prop1', 'value1' );
+               $cache->set( 'first', 'prop1', 'value1' );
                $cache->set( 'second', 'prop2', 'value2' );
 
                // Get first
@@ -233,6 +232,7 @@ class ProcessCacheLRUTestable extends ProcessCacheLRU {
        public function getCache() {
                return $this->cache;
        }
+
        public function getEntriesCount() {
                return count( $this->cache );
        }
index e12c8c7..19ceadd 100644 (file)
@@ -145,7 +145,7 @@ class ContentHandlerTest extends MediaWikiTestCase {
                $this->assertEquals( $expected->getCode(), $lang->getCode() );
        }
 
-       public function testGetContentText_Null( ) {
+       public function testGetContentText_Null() {
                global $wgContentHandlerTextFallback;
 
                $content = null;
@@ -163,7 +163,7 @@ class ContentHandlerTest extends MediaWikiTestCase {
                $this->assertEquals( '', $text );
        }
 
-       public function testGetContentText_TextContent( ) {
+       public function testGetContentText_TextContent() {
                global $wgContentHandlerTextFallback;
 
                $content = new WikitextContent( "hello world" );
@@ -181,7 +181,7 @@ class ContentHandlerTest extends MediaWikiTestCase {
                $this->assertEquals( $content->getNativeData(), $text );
        }
 
-       public function testGetContentText_NonTextContent( ) {
+       public function testGetContentText_NonTextContent() {
                global $wgContentHandlerTextFallback;
 
                $content = new DummyContentForTesting( "hello world" );
@@ -213,15 +213,15 @@ class ContentHandlerTest extends MediaWikiTestCase {
                return array(
                        array( 'hallo', 'Help:Test', null, null, CONTENT_MODEL_WIKITEXT, 'hallo', false ),
                        array( 'hallo', 'MediaWiki:Test.js', null, null, CONTENT_MODEL_JAVASCRIPT, 'hallo', false ),
-                       array( serialize('hallo'), 'Dummy:Test', null, null, "testing", 'hallo', false ),
+                       array( serialize( 'hallo' ), 'Dummy:Test', null, null, "testing", 'hallo', false ),
 
                        array( 'hallo', 'Help:Test', null, CONTENT_FORMAT_WIKITEXT, CONTENT_MODEL_WIKITEXT, 'hallo', false ),
                        array( 'hallo', 'MediaWiki:Test.js', null, CONTENT_FORMAT_JAVASCRIPT, CONTENT_MODEL_JAVASCRIPT, 'hallo', false ),
-                       array( serialize('hallo'), 'Dummy:Test', null, "testing", "testing", 'hallo', false ),
+                       array( serialize( 'hallo' ), 'Dummy:Test', null, "testing", "testing", 'hallo', false ),
 
                        array( 'hallo', 'Help:Test', CONTENT_MODEL_CSS, null, CONTENT_MODEL_CSS, 'hallo', false ),
                        array( 'hallo', 'MediaWiki:Test.js', CONTENT_MODEL_CSS, null, CONTENT_MODEL_CSS, 'hallo', false ),
-                       array( serialize('hallo'), 'Dummy:Test', CONTENT_MODEL_CSS, null, CONTENT_MODEL_CSS, serialize('hallo'), false ),
+                       array( serialize( 'hallo' ), 'Dummy:Test', CONTENT_MODEL_CSS, null, CONTENT_MODEL_CSS, serialize( 'hallo' ), false ),
 
                        array( 'hallo', 'Help:Test', CONTENT_MODEL_WIKITEXT, "testing", null, null, true ),
                        array( 'hallo', 'MediaWiki:Test.js', CONTENT_MODEL_CSS, "testing", null, null, true ),
@@ -245,10 +245,14 @@ class ContentHandlerTest extends MediaWikiTestCase {
                        $this->assertEquals( $expectedModelId, $content->getModel(), 'bad model id' );
                        $this->assertEquals( $expectedNativeData, $content->getNativeData(), 'bads native data' );
                } catch ( MWException $ex ) {
-                       if ( !$shouldFail ) $this->fail( "ContentHandler::makeContent failed unexpectedly: " . $ex->getMessage() );
-                       else $this->assertTrue( true ); // dummy, so we don't get the "test did not perform any assertions" message.
+                       if ( !$shouldFail ) {
+                               $this->fail( "ContentHandler::makeContent failed unexpectedly: " . $ex->getMessage() );
+                       }
+                       else {
+                               // dummy, so we don't get the "test did not perform any assertions" message.
+                               $this->assertTrue( true );
+                       }
                }
-
        }
 
        /*
@@ -292,7 +296,7 @@ class DummyContentHandlerForTesting extends ContentHandler {
         * @return String serialized form of the content
         */
        public function serializeContent( Content $content, $format = null ) {
-          return $content->serialize();
+               return $content->serialize();
        }
 
        /**
index b08a468..8f53dd3 100644 (file)
@@ -62,7 +62,7 @@ class CssContentTest extends MediaWikiTestCase {
                $this->assertEquals( CONTENT_MODEL_CSS, $content->getContentHandler()->getModelID() );
        }
 
-       public static function dataEquals( ) {
+       public static function dataEquals() {
                return array(
                        array( new CssContent( 'hallo' ), null, false ),
                        array( new CssContent( 'hallo' ), new CssContent( 'hallo' ), true ),
index 18df53f..2d693fe 100644 (file)
@@ -39,16 +39,16 @@ class JavaScriptContentTest extends TextContentTest {
        public static function dataGetSection() {
                return array(
                        array( WikitextContentTest::$sections,
-                              '0',
-                              null
+                               '0',
+                               null
                        ),
                        array( WikitextContentTest::$sections,
-                              '2',
-                              null
+                               '2',
+                               null
                        ),
                        array( WikitextContentTest::$sections,
-                              '8',
-                              null
+                               '8',
+                               null
                        ),
                );
        }
@@ -57,39 +57,39 @@ class JavaScriptContentTest extends TextContentTest {
        public static function dataReplaceSection() {
                return array(
                        array( WikitextContentTest::$sections,
-                              '0',
-                              'No more',
-                              null,
-                              null
+                               '0',
+                               'No more',
+                               null,
+                               null
                        ),
                        array( WikitextContentTest::$sections,
-                              '',
-                              'No more',
-                              null,
-                              null
+                               '',
+                               'No more',
+                               null,
+                               null
                        ),
                        array( WikitextContentTest::$sections,
-                              '2',
-                              "== TEST ==\nmore fun",
-                              null,
-                              null
+                               '2',
+                               "== TEST ==\nmore fun",
+                               null,
+                               null
                        ),
                        array( WikitextContentTest::$sections,
-                              '8',
-                              'No more',
-                              null,
-                              null
+                               '8',
+                               'No more',
+                               null,
+                               null
                        ),
                        array( WikitextContentTest::$sections,
-                              'new',
-                              'No more',
-                              'New',
-                              null
+                               'new',
+                               'No more',
+                               'New',
+                               null
                        ),
                );
        }
 
-       public function testAddSectionHeader( ) {
+       public function testAddSectionHeader() {
                $content = $this->newContent( 'hello world' );
                $c = $content->addSectionHeader( 'test' );
 
@@ -114,10 +114,10 @@ class JavaScriptContentTest extends TextContentTest {
        public static function dataPreloadTransform() {
                return array(
                        array( 'hello this is ~~~',
-                              'hello this is ~~~',
+                               'hello this is ~~~',
                        ),
                        array( 'hello \'\'this\'\' is <noinclude>foo</noinclude><includeonly>bar</includeonly>',
-                              'hello \'\'this\'\' is <noinclude>foo</noinclude><includeonly>bar</includeonly>',
+                               'hello \'\'this\'\' is <noinclude>foo</noinclude><includeonly>bar</includeonly>',
                        ),
                );
        }
@@ -125,13 +125,13 @@ class JavaScriptContentTest extends TextContentTest {
        public static function dataGetRedirectTarget() {
                return array(
                        array( '#REDIRECT [[Test]]',
-                              null,
+                               null,
                        ),
                        array( '#REDIRECT Test',
-                              null,
+                               null,
                        ),
                        array( '* #REDIRECT [[Test]]',
-                              null,
+                               null,
                        ),
                );
        }
@@ -159,59 +159,59 @@ class JavaScriptContentTest extends TextContentTest {
        public static function dataIsCountable() {
                return array(
                        array( '',
-                              null,
-                              'any',
-                              true
+                               null,
+                               'any',
+                               true
                        ),
                        array( 'Foo',
-                              null,
-                              'any',
-                              true
+                               null,
+                               'any',
+                               true
                        ),
                        array( 'Foo',
-                              null,
-                              'comma',
-                              false
+                               null,
+                               'comma',
+                               false
                        ),
                        array( 'Foo, bar',
-                              null,
-                              'comma',
-                              false
+                               null,
+                               'comma',
+                               false
                        ),
                        array( 'Foo',
-                              null,
-                              'link',
-                              false
+                               null,
+                               'link',
+                               false
                        ),
                        array( 'Foo [[bar]]',
-                              null,
-                              'link',
-                              false
+                               null,
+                               'link',
+                               false
                        ),
                        array( 'Foo',
-                              true,
-                              'link',
-                              false
+                               true,
+                               'link',
+                               false
                        ),
                        array( 'Foo [[bar]]',
-                              false,
-                              'link',
-                              false
+                               false,
+                               'link',
+                               false
                        ),
                        array( '#REDIRECT [[bar]]',
-                              true,
-                              'any',
-                              true
+                               true,
+                               'any',
+                               true
                        ),
                        array( '#REDIRECT [[bar]]',
-                              true,
-                              'comma',
-                              false
+                               true,
+                               'comma',
+                               false
                        ),
                        array( '#REDIRECT [[bar]]',
-                              true,
-                              'link',
-                              false
+                               true,
+                               'link',
+                               false
                        ),
                );
        }
@@ -219,28 +219,28 @@ class JavaScriptContentTest extends TextContentTest {
        public static function dataGetTextForSummary() {
                return array(
                        array( "hello\nworld.",
-                              16,
-                              'hello world.',
+                               16,
+                               'hello world.',
                        ),
                        array( 'hello world.',
-                              8,
-                              'hello...',
+                               8,
+                               'hello...',
                        ),
                        array( '[[hello world]].',
-                              8,
-                              '[[hel...',
+                               8,
+                               '[[hel...',
                        ),
                );
        }
 
-       public function testMatchMagicWord( ) {
+       public function testMatchMagicWord() {
                $mw = MagicWord::get( "staticredirect" );
 
                $content = $this->newContent( "#REDIRECT [[FOO]]\n__STATICREDIRECT__" );
                $this->assertFalse( $content->matchMagicWord( $mw ), "should not have matched magic word, since it's not wikitext" );
        }
 
-       public function testUpdateRedirect( ) {
+       public function testUpdateRedirect() {
                $target = Title::newFromText( "testUpdateRedirect_target" );
 
                $content = $this->newContent( "#REDIRECT [[Someplace]]" );
@@ -261,7 +261,7 @@ class JavaScriptContentTest extends TextContentTest {
                $this->assertEquals( CONTENT_MODEL_JAVASCRIPT, $content->getContentHandler()->getModelID() );
        }
 
-       public static function dataEquals( ) {
+       public static function dataEquals() {
                return array(
                        array( new JavaScriptContent( "hallo" ), null, false ),
                        array( new JavaScriptContent( "hallo" ), new JavaScriptContent( "hallo" ), true ),
index ca387a2..382f71a 100644 (file)
@@ -22,6 +22,7 @@ class TextContentTest extends MediaWikiLangTestCase {
                                CONTENT_MODEL_CSS,
                                CONTENT_MODEL_JAVASCRIPT,
                        ),
+                       'wgUseTidy' => false,
                        'wgAlwaysUseTidy' => false,
                ) );
 
@@ -142,7 +143,7 @@ class TextContentTest extends MediaWikiLangTestCase {
         */
        public function testGetRedirectTarget( $text, $expected ) {
                $content = $this->newContent( $text );
-               $t = $content->getRedirectTarget( );
+               $t = $content->getRedirectTarget();
 
                if ( is_null( $expected ) ) {
                        $this->assertNull( $t, "text should not have generated a redirect target: $text" );
@@ -157,7 +158,7 @@ class TextContentTest extends MediaWikiLangTestCase {
        public function testIsRedirect( $text, $expected ) {
                $content = $this->newContent( $text );
 
-               $this->assertEquals( !is_null($expected), $content->isRedirect() );
+               $this->assertEquals( !is_null( $expected ), $content->isRedirect() );
        }
 
        /**
@@ -183,29 +184,28 @@ class TextContentTest extends MediaWikiLangTestCase {
        public static function dataIsCountable() {
                return array(
                        array( '',
-                              null,
-                              'any',
-                              true
+                               null,
+                               'any',
+                               true
                        ),
                        array( 'Foo',
-                              null,
-                              'any',
-                              true
+                               null,
+                               'any',
+                               true
                        ),
                        array( 'Foo',
-                              null,
-                              'comma',
-                              false
+                               null,
+                               'comma',
+                               false
                        ),
                        array( 'Foo, bar',
-                              null,
-                              'comma',
-                              false
+                               null,
+                               'comma',
+                               false
                        ),
                );
        }
 
-
        /**
         * @dataProvider dataIsCountable
         * @group Database
@@ -222,22 +222,22 @@ class TextContentTest extends MediaWikiLangTestCase {
                $wgArticleCountMethod = $old;
 
                $this->assertEquals( $expected, $v, 'isCountable() returned unexpected value ' . var_export( $v, true )
-                                                   . ' instead of ' . var_export( $expected, true ) . " in mode `$mode` for text \"$text\"" );
+                       . ' instead of ' . var_export( $expected, true ) . " in mode `$mode` for text \"$text\"" );
        }
 
        public static function dataGetTextForSummary() {
                return array(
                        array( "hello\nworld.",
-                              16,
-                              'hello world.',
+                               16,
+                               'hello world.',
                        ),
                        array( 'hello world.',
-                              8,
-                              'hello...',
+                               8,
+                               'hello...',
                        ),
                        array( '[[hello world]].',
-                              8,
-                              '[[hel...',
+                               8,
+                               '[[hel...',
                        ),
                );
        }
@@ -251,8 +251,7 @@ class TextContentTest extends MediaWikiLangTestCase {
                $this->assertEquals( $expected, $content->getTextForSummary( $maxlength ) );
        }
 
-
-       public function testGetTextForSearchIndex( ) {
+       public function testGetTextForSearchIndex() {
                $content = $this->newContent( 'hello world.' );
 
                $this->assertEquals( 'hello world.', $content->getTextForSearchIndex() );
@@ -266,19 +265,19 @@ class TextContentTest extends MediaWikiLangTestCase {
                $this->assertEquals( 'hello world.', $copy->getNativeData() );
        }
 
-       public function testGetSize( ) {
+       public function testGetSize() {
                $content = $this->newContent( 'hello world.' );
 
                $this->assertEquals( 12, $content->getSize() );
        }
 
-       public function testGetNativeData( ) {
+       public function testGetNativeData() {
                $content = $this->newContent( 'hello world.' );
 
                $this->assertEquals( 'hello world.', $content->getNativeData() );
        }
 
-       public function testGetWikitextForTransclusion( ) {
+       public function testGetWikitextForTransclusion() {
                $content = $this->newContent( 'hello world.' );
 
                $this->assertEquals( 'hello world.', $content->getWikitextForTransclusion() );
@@ -296,7 +295,7 @@ class TextContentTest extends MediaWikiLangTestCase {
                $this->assertEquals( CONTENT_MODEL_TEXT, $content->getContentHandler()->getModelID() );
        }
 
-       public static function dataIsEmpty( ) {
+       public static function dataIsEmpty() {
                return array(
                        array( '', true ),
                        array( '  ', false ),
@@ -314,7 +313,7 @@ class TextContentTest extends MediaWikiLangTestCase {
                $this->assertEquals( $empty, $content->isEmpty() );
        }
 
-       public static function dataEquals( ) {
+       public static function dataEquals() {
                return array(
                        array( new TextContent( "hallo" ), null, false ),
                        array( new TextContent( "hallo" ), new TextContent( "hallo" ), true ),
@@ -333,13 +332,13 @@ class TextContentTest extends MediaWikiLangTestCase {
 
        public static function dataGetDeletionUpdates() {
                return array(
-                       array("TextContentTest_testGetSecondaryDataUpdates_1",
+                       array( "TextContentTest_testGetSecondaryDataUpdates_1",
                                CONTENT_MODEL_TEXT, "hello ''world''\n",
-                               array( )
+                               array()
                        ),
-                       array("TextContentTest_testGetSecondaryDataUpdates_2",
+                       array( "TextContentTest_testGetSecondaryDataUpdates_2",
                                CONTENT_MODEL_TEXT, "hello [[world test 21344]]\n",
-                               array( )
+                               array()
                        ),
                        // TODO: more...?
                );
@@ -362,7 +361,7 @@ class TextContentTest extends MediaWikiLangTestCase {
                // make updates accessible by class name
                foreach ( $updates as $update ) {
                        $class = get_class( $update );
-                       $updates[ $class ] = $update;
+                       $updates[$class] = $update;
                }
 
                if ( !$expectedStuff ) {
@@ -373,7 +372,7 @@ class TextContentTest extends MediaWikiLangTestCase {
                foreach ( $expectedStuff as $class => $fieldValues ) {
                        $this->assertArrayHasKey( $class, $updates, "missing an update of type $class" );
 
-                       $update = $updates[ $class ];
+                       $update = $updates[$class];
 
                        foreach ( $fieldValues as $field => $value ) {
                                $v = $update->$field; #if the field doesn't exist, just crash and burn
index 8121099..0f6a968 100644 (file)
@@ -16,7 +16,7 @@ class WikitextContentHandlerTest extends MediaWikiLangTestCase {
                $this->handler = ContentHandler::getForModelID( CONTENT_MODEL_WIKITEXT );
        }
 
-       public function testSerializeContent( ) {
+       public function testSerializeContent() {
                $content = new WikitextContent( 'hello world' );
 
                $this->assertEquals( 'hello world', $this->handler->serializeContent( $content ) );
@@ -30,7 +30,7 @@ class WikitextContentHandlerTest extends MediaWikiLangTestCase {
                }
        }
 
-       public function testUnserializeContent( ) {
+       public function testUnserializeContent() {
                $content = $this->handler->unserializeContent( 'hello world' );
                $this->assertEquals( 'hello world', $content->getNativeData() );
 
@@ -52,7 +52,7 @@ class WikitextContentHandlerTest extends MediaWikiLangTestCase {
                $this->assertEquals( '', $content->getNativeData() );
        }
 
-       public static function dataIsSupportedFormat( ) {
+       public static function dataIsSupportedFormat() {
                return array(
                        array( null, true ),
                        array( CONTENT_FORMAT_WIKITEXT, true ),
@@ -67,21 +67,22 @@ class WikitextContentHandlerTest extends MediaWikiLangTestCase {
                $this->assertEquals( $supported, $this->handler->isSupportedFormat( $format ) );
        }
 
-       public static function dataMerge3( ) {
+       public static function dataMerge3() {
                return array(
-                       array( "first paragraph
+                       array(
+                               "first paragraph
 
                                        second paragraph\n",
 
-                                       "FIRST paragraph
+                               "FIRST paragraph
 
                                        second paragraph\n",
 
-                                       "first paragraph
+                               "first paragraph
 
                                        SECOND paragraph\n",
 
-                                       "FIRST paragraph
+                               "FIRST paragraph
 
                                        SECOND paragraph\n",
                        ),
@@ -89,13 +90,12 @@ class WikitextContentHandlerTest extends MediaWikiLangTestCase {
                        array( "first paragraph
                                        second paragraph\n",
 
-                                  "Bla bla\n",
+                               "Bla bla\n",
 
-                                  "Blubberdibla\n",
+                               "Blubberdibla\n",
 
-                                  false,
+                               false,
                        ),
-
                );
        }
 
@@ -115,7 +115,7 @@ class WikitextContentHandlerTest extends MediaWikiLangTestCase {
                $this->assertEquals( $expected, $merged ? $merged->getNativeData() : $merged );
        }
 
-       public static function dataGetAutosummary( ) {
+       public static function dataGetAutosummary() {
                return array(
                        array(
                                'Hello there, world!',
index 7cf473e..c9eecf7 100644 (file)
@@ -7,10 +7,7 @@
  *        ^--- needed, because we do need the database to test link updates
  */
 class WikitextContentTest extends TextContentTest {
-
-       static $sections =
-
-"Intro
+       static $sections = "Intro
 
 == stuff ==
 hello world
@@ -102,17 +99,17 @@ more stuff
        public static function dataGetSection() {
                return array(
                        array( WikitextContentTest::$sections,
-                                       "0",
-                                       "Intro"
+                               "0",
+                               "Intro"
                        ),
                        array( WikitextContentTest::$sections,
-                                       "2",
-"== test ==
+                               "2",
+                               "== test ==
 just a test"
                        ),
                        array( WikitextContentTest::$sections,
-                                       "8",
-                                       false
+                               "8",
+                               false
                        ),
                );
        }
@@ -136,34 +133,34 @@ just a test"
        public static function dataReplaceSection() {
                return array(
                        array( WikitextContentTest::$sections,
-                              "0",
-                              "No more",
-                              null,
-                              trim( preg_replace( '/^Intro/sm', 'No more', WikitextContentTest::$sections ) )
+                               "0",
+                               "No more",
+                               null,
+                               trim( preg_replace( '/^Intro/sm', 'No more', WikitextContentTest::$sections ) )
                        ),
                        array( WikitextContentTest::$sections,
-                              "",
-                              "No more",
-                              null,
-                              "No more"
+                               "",
+                               "No more",
+                               null,
+                               "No more"
                        ),
                        array( WikitextContentTest::$sections,
-                              "2",
-                              "== TEST ==\nmore fun",
-                              null,
-                              trim( preg_replace( '/^== test ==.*== foo ==/sm', "== TEST ==\nmore fun\n\n== foo ==", WikitextContentTest::$sections ) )
+                               "2",
+                               "== TEST ==\nmore fun",
+                               null,
+                               trim( preg_replace( '/^== test ==.*== foo ==/sm', "== TEST ==\nmore fun\n\n== foo ==", WikitextContentTest::$sections ) )
                        ),
                        array( WikitextContentTest::$sections,
-                              "8",
-                              "No more",
-                              null,
-                              WikitextContentTest::$sections
+                               "8",
+                               "No more",
+                               null,
+                               WikitextContentTest::$sections
                        ),
                        array( WikitextContentTest::$sections,
-                              "new",
-                              "No more",
-                              "New",
-                              trim( WikitextContentTest::$sections ) . "\n\n\n== New ==\n\nNo more"
+                               "new",
+                               "No more",
+                               "New",
+                               trim( WikitextContentTest::$sections ) . "\n\n\n== New ==\n\nNo more"
                        ),
                );
        }
@@ -178,7 +175,7 @@ just a test"
                $this->assertEquals( $expected, is_null( $c ) ? null : $c->getNativeData() );
        }
 
-       public function testAddSectionHeader( ) {
+       public function testAddSectionHeader() {
                $content = $this->newContent( 'hello world' );
                $content = $content->addSectionHeader( 'test' );
 
@@ -188,10 +185,10 @@ just a test"
        public static function dataPreSaveTransform() {
                return array(
                        array( 'hello this is ~~~',
-                              "hello this is [[Special:Contributions/127.0.0.1|127.0.0.1]]",
+                               "hello this is [[Special:Contributions/127.0.0.1|127.0.0.1]]",
                        ),
                        array( 'hello \'\'this\'\' is <nowiki>~~~</nowiki>',
-                              'hello \'\'this\'\' is <nowiki>~~~</nowiki>',
+                               'hello \'\'this\'\' is <nowiki>~~~</nowiki>',
                        ),
                        array( // rtrim
                                " Foo \n ",
@@ -203,10 +200,10 @@ just a test"
        public static function dataPreloadTransform() {
                return array(
                        array( 'hello this is ~~~',
-                              "hello this is ~~~",
+                               "hello this is ~~~",
                        ),
                        array( 'hello \'\'this\'\' is <noinclude>foo</noinclude><includeonly>bar</includeonly>',
-                              'hello \'\'this\'\' is bar',
+                               'hello \'\'this\'\' is bar',
                        ),
                );
        }
@@ -214,13 +211,13 @@ just a test"
        public static function dataGetRedirectTarget() {
                return array(
                        array( '#REDIRECT [[Test]]',
-                              'Test',
+                               'Test',
                        ),
                        array( '#REDIRECT Test',
-                              null,
+                               null,
                        ),
                        array( '* #REDIRECT [[Test]]',
-                              null,
+                               null,
                        ),
                );
        }
@@ -265,64 +262,64 @@ just a test"
        public static function dataIsCountable() {
                return array(
                        array( '',
-                              null,
-                              'any',
-                              true
+                               null,
+                               'any',
+                               true
                        ),
                        array( 'Foo',
-                              null,
-                              'any',
-                              true
+                               null,
+                               'any',
+                               true
                        ),
                        array( 'Foo',
-                              null,
-                              'comma',
-                              false
+                               null,
+                               'comma',
+                               false
                        ),
                        array( 'Foo, bar',
-                              null,
-                              'comma',
-                              true
+                               null,
+                               'comma',
+                               true
                        ),
                        array( 'Foo',
-                              null,
-                              'link',
-                              false
+                               null,
+                               'link',
+                               false
                        ),
                        array( 'Foo [[bar]]',
-                              null,
-                              'link',
-                              true
+                               null,
+                               'link',
+                               true
                        ),
                        array( 'Foo',
-                              true,
-                              'link',
-                              true
+                               true,
+                               'link',
+                               true
                        ),
                        array( 'Foo [[bar]]',
-                              false,
-                              'link',
-                              false
+                               false,
+                               'link',
+                               false
                        ),
                        array( '#REDIRECT [[bar]]',
-                              true,
-                              'any',
-                              false
+                               true,
+                               'any',
+                               false
                        ),
                        array( '#REDIRECT [[bar]]',
-                              true,
-                              'comma',
-                              false
+                               true,
+                               'comma',
+                               false
                        ),
                        array( '#REDIRECT [[bar]]',
-                              true,
-                              'link',
-                              false
+                               true,
+                               'link',
+                               false
                        ),
                );
        }
 
-       public function testMatchMagicWord( ) {
+       public function testMatchMagicWord() {
                $mw = MagicWord::get( "staticredirect" );
 
                $content = $this->newContent( "#REDIRECT [[FOO]]\n__STATICREDIRECT__" );
@@ -332,7 +329,7 @@ just a test"
                $this->assertFalse( $content->matchMagicWord( $mw ), "should not have matched magic word" );
        }
 
-       public function testUpdateRedirect( ) {
+       public function testUpdateRedirect() {
                $target = Title::newFromText( "testUpdateRedirect_target" );
 
                // test with non-redirect page
@@ -363,7 +360,7 @@ just a test"
                $this->assertEquals( CONTENT_MODEL_WIKITEXT, $content->getContentHandler()->getModelID() );
        }
 
-       public static function dataEquals( ) {
+       public static function dataEquals() {
                return array(
                        array( new WikitextContent( "hallo" ), null, false ),
                        array( new WikitextContent( "hallo" ), new WikitextContent( "hallo" ), true ),
@@ -375,16 +372,15 @@ just a test"
 
        public static function dataGetDeletionUpdates() {
                return array(
-                       array("WikitextContentTest_testGetSecondaryDataUpdates_1",
+                       array( "WikitextContentTest_testGetSecondaryDataUpdates_1",
                                CONTENT_MODEL_WIKITEXT, "hello ''world''\n",
-                               array( 'LinksDeletionUpdate' => array( ) )
+                               array( 'LinksDeletionUpdate' => array() )
                        ),
-                       array("WikitextContentTest_testGetSecondaryDataUpdates_2",
+                       array( "WikitextContentTest_testGetSecondaryDataUpdates_2",
                                CONTENT_MODEL_WIKITEXT, "hello [[world test 21344]]\n",
-                               array( 'LinksDeletionUpdate' => array( ) )
+                               array( 'LinksDeletionUpdate' => array() )
                        ),
                        // @todo: more...?
                );
        }
-
 }
index 9a62abc..0979243 100644 (file)
@@ -39,8 +39,8 @@ class DatabaseSQLTest extends MediaWikiTestCase {
                                        'conds' => array( 'alias' => 'text' ),
                                ),
                                "SELECT  field,field2 AS alias  " .
-                               "FROM `unittest_table`  " .
-                               "WHERE alias = 'text'"
+                                       "FROM `unittest_table`  " .
+                                       "WHERE alias = 'text'"
                        ),
                        array(
                                array(
@@ -50,10 +50,10 @@ class DatabaseSQLTest extends MediaWikiTestCase {
                                        'options' => array( 'LIMIT' => 1, 'ORDER BY' => 'field' ),
                                ),
                                "SELECT  field,field2 AS alias  " .
-                               "FROM `unittest_table`  " .
-                               "WHERE alias = 'text'  " .
-                               "ORDER BY field " .
-                               "LIMIT 1"
+                                       "FROM `unittest_table`  " .
+                                       "WHERE alias = 'text'  " .
+                                       "ORDER BY field " .
+                                       "LIMIT 1"
                        ),
                        array(
                                array(
@@ -63,13 +63,13 @@ class DatabaseSQLTest extends MediaWikiTestCase {
                                        'options' => array( 'LIMIT' => 1, 'ORDER BY' => 'field' ),
                                        'join_conds' => array( 't2' => array(
                                                'LEFT JOIN', 'tid = t2.id'
-                                       )),
+                                       ) ),
                                ),
                                "SELECT  tid,field,field2 AS alias,t2.id  " .
-                               "FROM `unittest_table` LEFT JOIN `unittest_table2` `t2` ON ((tid = t2.id))  " .
-                               "WHERE alias = 'text'  " .
-                               "ORDER BY field " .
-                               "LIMIT 1"
+                                       "FROM `unittest_table` LEFT JOIN `unittest_table2` `t2` ON ((tid = t2.id))  " .
+                                       "WHERE alias = 'text'  " .
+                                       "ORDER BY field " .
+                                       "LIMIT 1"
                        ),
                        array(
                                array(
@@ -79,13 +79,13 @@ class DatabaseSQLTest extends MediaWikiTestCase {
                                        'options' => array( 'LIMIT' => 1, 'GROUP BY' => 'field', 'HAVING' => 'COUNT(*) > 1' ),
                                        'join_conds' => array( 't2' => array(
                                                'LEFT JOIN', 'tid = t2.id'
-                                       )),
+                                       ) ),
                                ),
                                "SELECT  tid,field,field2 AS alias,t2.id  " .
-                               "FROM `unittest_table` LEFT JOIN `unittest_table2` `t2` ON ((tid = t2.id))  " .
-                               "WHERE alias = 'text'  " .
-                               "GROUP BY field HAVING COUNT(*) > 1 " .
-                               "LIMIT 1"
+                                       "FROM `unittest_table` LEFT JOIN `unittest_table2` `t2` ON ((tid = t2.id))  " .
+                                       "WHERE alias = 'text'  " .
+                                       "GROUP BY field HAVING COUNT(*) > 1 " .
+                                       "LIMIT 1"
                        ),
                        array(
                                array(
@@ -95,13 +95,13 @@ class DatabaseSQLTest extends MediaWikiTestCase {
                                        'options' => array( 'LIMIT' => 1, 'GROUP BY' => array( 'field', 'field2' ), 'HAVING' => array( 'COUNT(*) > 1', 'field' => 1 ) ),
                                        'join_conds' => array( 't2' => array(
                                                'LEFT JOIN', 'tid = t2.id'
-                                       )),
+                                       ) ),
                                ),
                                "SELECT  tid,field,field2 AS alias,t2.id  " .
-                               "FROM `unittest_table` LEFT JOIN `unittest_table2` `t2` ON ((tid = t2.id))  " .
-                               "WHERE alias = 'text'  " .
-                               "GROUP BY field,field2 HAVING (COUNT(*) > 1) AND field = '1' " .
-                               "LIMIT 1"
+                                       "FROM `unittest_table` LEFT JOIN `unittest_table2` `t2` ON ((tid = t2.id))  " .
+                                       "WHERE alias = 'text'  " .
+                                       "GROUP BY field,field2 HAVING (COUNT(*) > 1) AND field = '1' " .
+                                       "LIMIT 1"
                        ),
                );
        }
index 3e71603..7b84d47 100644 (file)
@@ -3,7 +3,7 @@
 class MockDatabaseSqlite extends DatabaseSqliteStandalone {
        var $lastQuery;
 
-       function __construct( ) {
+       function __construct() {
                parent::__construct( ':memory:' );
        }
 
@@ -48,8 +48,8 @@ class DatabaseSqliteTest extends MediaWikiTestCase {
        private function assertResultIs( $expected, $res ) {
                $this->assertNotNull( $res );
                $i = 0;
-               foreach( $res as $row ) {
-                       foreach( $expected[$i] as $key => $value ) {
+               foreach ( $res as $row ) {
+                       foreach ( $expected[$i] as $key => $value ) {
                                $this->assertTrue( isset( $row->$key ) );
                                $this->assertEquals( $value, $row->$key );
                        }
@@ -108,38 +108,38 @@ class DatabaseSqliteTest extends MediaWikiTestCase {
                $this->assertEquals( 'foo', $this->replaceVars( 'foo' ), "Don't break anything accidentally" );
 
                $this->assertEquals( "CREATE TABLE /**/foo (foo_key INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, "
-                       . "foo_bar TEXT, foo_name TEXT NOT NULL DEFAULT '', foo_int INTEGER, foo_int2 INTEGER );",
+                               . "foo_bar TEXT, foo_name TEXT NOT NULL DEFAULT '', foo_int INTEGER, foo_int2 INTEGER );",
                        $this->replaceVars( "CREATE TABLE /**/foo (foo_key int unsigned NOT NULL PRIMARY KEY AUTO_INCREMENT,
                        foo_bar char(13), foo_name varchar(255) binary NOT NULL DEFAULT '', foo_int tinyint ( 8 ), foo_int2 int(16) ) ENGINE=MyISAM;" )
-                       );
+               );
 
                $this->assertEquals( "CREATE TABLE foo ( foo1 REAL, foo2 REAL, foo3 REAL );",
                        $this->replaceVars( "CREATE TABLE foo ( foo1 FLOAT, foo2 DOUBLE( 1,10), foo3 DOUBLE PRECISION );" )
-                       );
+               );
 
                $this->assertEquals( "CREATE TABLE foo ( foo_binary1 BLOB, foo_binary2 BLOB );",
                        $this->replaceVars( "CREATE TABLE foo ( foo_binary1 binary(16), foo_binary2 varbinary(32) );" )
-                       );
+               );
 
                $this->assertEquals( "CREATE TABLE text ( text_foo TEXT );",
                        $this->replaceVars( "CREATE TABLE text ( text_foo tinytext );" ),
                        'Table name changed'
-                       );
+               );
 
                $this->assertEquals( "CREATE TABLE foo ( foobar INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL );",
-                       $this->replaceVars("CREATE TABLE foo ( foobar INT PRIMARY KEY NOT NULL AUTO_INCREMENT );" )
-                       );
+                       $this->replaceVars( "CREATE TABLE foo ( foobar INT PRIMARY KEY NOT NULL AUTO_INCREMENT );" )
+               );
                $this->assertEquals( "CREATE TABLE foo ( foobar INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL );",
-                       $this->replaceVars("CREATE TABLE foo ( foobar INT PRIMARY KEY AUTO_INCREMENT NOT NULL );" )
-                       );
+                       $this->replaceVars( "CREATE TABLE foo ( foobar INT PRIMARY KEY AUTO_INCREMENT NOT NULL );" )
+               );
 
                $this->assertEquals( "CREATE TABLE enums( enum1 TEXT, myenum TEXT)",
                        $this->replaceVars( "CREATE TABLE enums( enum1 ENUM('A', 'B'), myenum ENUM ('X', 'Y'))" )
-                       );
+               );
 
                $this->assertEquals( "ALTER TABLE foo ADD COLUMN foo_bar INTEGER DEFAULT 42",
                        $this->replaceVars( "ALTER TABLE foo\nADD COLUMN foo_bar int(10) unsigned DEFAULT 42" )
-                       );
+               );
        }
 
        public function testTableName() {
@@ -381,9 +381,9 @@ class DatabaseSqliteTest extends MediaWikiTestCase {
 
        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
+               $db = new DatabaseSqliteStandalone( ':memory:' );
+               $res = $db->query( 'SELECT "a" LIKE "A" AS a' );
+               $row = $res->fetchRow();
+               $this->assertFalse( (bool)$row['a'] );
        }
 }
index 8c992c7..65c80d1 100644 (file)
@@ -206,7 +206,7 @@ class DatabaseTest extends MediaWikiTestCase {
 
        private function dropFunctions() {
                $this->db->query( 'DROP FUNCTION IF EXISTS mw_test_function'
-                       . ( $this->db->getType() == 'postgres'  ? '()' : '' )
+                               . ( $this->db->getType() == 'postgres' ? '()' : '' )
                );
        }
 }
index bd2c388..9026cb9 100644 (file)
@@ -7,7 +7,7 @@ class MWDebugTest extends MediaWikiTestCase {
                parent::setUp();
                // Make sure MWDebug class is enabled
                static $MWDebugEnabled = false;
-               if( !$MWDebugEnabled ) {
+               if ( !$MWDebugEnabled ) {
                        MWDebug::init();
                        $MWDebugEnabled = true;
                }
@@ -23,10 +23,11 @@ class MWDebugTest extends MediaWikiTestCase {
 
        function testAddLog() {
                MWDebug::log( 'logging a string' );
-               $this->assertEquals( array( array(
-                       'msg' => 'logging a string',
-                       'type' => 'log',
-                       'caller' => __METHOD__ ,
+               $this->assertEquals(
+                       array( array(
+                               'msg' => 'logging a string',
+                               'type' => 'log',
+                               'caller' => __METHOD__,
                        ) ),
                        MWDebug::getLog()
                );
@@ -34,10 +35,11 @@ class MWDebugTest extends MediaWikiTestCase {
 
        function testAddWarning() {
                MWDebug::warning( 'Warning message' );
-               $this->assertEquals( array( array(
-                       'msg' => 'Warning message',
-                       'type' => 'warn',
-                       'caller' => 'MWDebugTest::testAddWarning',
+               $this->assertEquals(
+                       array( array(
+                               'msg' => 'Warning message',
+                               'type' => 'warn',
+                               'caller' => 'MWDebugTest::testAddWarning',
                        ) ),
                        MWDebug::getLog()
                );
index b0e07f2..ab39a0e 100644 (file)
@@ -143,14 +143,14 @@ class FileBackendTest extends MediaWikiTestCase {
                        array( 'mwstore://backend/container/path', 'mwstore://backend/container/path' ),
                        array( 'mwstore://backend/container//path', 'mwstore://backend/container/path' ),
                        array( 'mwstore://backend/container///path', 'mwstore://backend/container/path' ),
-                       array( 'mwstore://backend/container///path//to///obj', 'mwstore://backend/container/path/to/obj',
+                       array( 'mwstore://backend/container///path//to///obj', 'mwstore://backend/container/path/to/obj' ),
                        array( 'mwstore://', null ),
                        array( 'mwstore://backend', null ),
                        array( 'mwstore://backend//container/path', null ),
                        array( 'mwstore://backend//container//path', null ),
                        array( 'mwstore:///', null ),
                        array( 'mwstore:/', null ),
-                       array( 'mwstore:', null ), )
+                       array( 'mwstore:', null ),
                );
        }
 
index 8f92c12..7cc25b1 100644 (file)
@@ -8,12 +8,14 @@ class FileRepoTest extends MediaWikiTestCase {
        function testFileRepoConstructionOptionCanNotBeNull() {
                $f = new FileRepo();
        }
+
        /**
         * @expectedException MWException
         */
        function testFileRepoConstructionOptionCanNotBeAnEmptyArray() {
                $f = new FileRepo( array() );
        }
+
        /**
         * @expectedException MWException
         */
@@ -22,6 +24,7 @@ class FileRepoTest extends MediaWikiTestCase {
                        'backend' => 'foobar'
                ) );
        }
+
        /**
         * @expectedException MWException
         */
@@ -33,10 +36,10 @@ class FileRepoTest extends MediaWikiTestCase {
 
        function testFileRepoConstructionWithRequiredOptions() {
                $f = new FileRepo( array(
-                       'name'    => 'FileRepoTestRepository',
+                       'name' => 'FileRepoTestRepository',
                        'backend' => new FSFileBackend( array(
-                               'name'           => 'local-testing',
-                               'lockManager'    => 'nullLockManager',
+                               'name' => 'local-testing',
+                               'lockManager' => 'nullLockManager',
                                'containerPaths' => array()
                        ) )
                ) );
index 5f01c70..a89ef98 100644 (file)
@@ -24,18 +24,18 @@ class StoreBatchTest extends MediaWikiTestCase {
                        $backend = new $class( $useConfig );
                } else {
                        $backend = new FSFileBackend( array(
-                               'name'        => 'local-testing',
+                               'name' => 'local-testing',
                                'lockManager' => 'nullLockManager',
                                'containerPaths' => array(
-                                       'unittests-public'  => "{$tmpPrefix}-public",
-                                       'unittests-thumb'   => "{$tmpPrefix}-thumb",
-                                       'unittests-temp'    => "{$tmpPrefix}-temp",
+                                       'unittests-public' => "{$tmpPrefix}-public",
+                                       'unittests-thumb' => "{$tmpPrefix}-thumb",
+                                       'unittests-temp' => "{$tmpPrefix}-temp",
                                        'unittests-deleted' => "{$tmpPrefix}-deleted",
                                )
                        ) );
                }
                $this->repo = new FileRepo( array(
-                       'name'    => 'unittests',
+                       'name' => 'unittests',
                        'backend' => $backend
                ) );
 
@@ -61,7 +61,7 @@ class StoreBatchTest extends MediaWikiTestCase {
         * @param $srcPath string The filepath or virtual URL
         * @param $flags integer Flags to pass into repo::store().
         */
-       private function storeit($originalName, $srcPath, $flags) {
+       private function storeit( $originalName, $srcPath, $flags ) {
                $hashPath = $this->repo->getHashPath( $originalName );
                $dstRel = "$hashPath{$this->date}!$originalName";
                $dstUrlRel = $hashPath . $this->date . '!' . rawurlencode( $originalName );
@@ -80,13 +80,13 @@ class StoreBatchTest extends MediaWikiTestCase {
         * @param $otherfn string The name of the different file (in the filesystem)
         * @param $fromrepo logical 'true' if we want to copy from a virtual URL out of the Repo.
         */
-       private function storecohort($fn, $infn, $otherfn, $fromrepo) {
+       private function storecohort( $fn, $infn, $otherfn, $fromrepo ) {
                $f = $this->storeit( $fn, $infn, 0 );
                $this->assertTrue( $f->isOK(), 'failed to store a new file' );
                $this->assertEquals( $f->failCount, 0, "counts wrong {$f->successCount} {$f->failCount}" );
                $this->assertEquals( $f->successCount, 1, "counts wrong {$f->successCount} {$f->failCount}" );
                if ( $fromrepo ) {
-                       $f = $this->storeit( "Other-$fn", $infn, FileRepo::OVERWRITE);
+                       $f = $this->storeit( "Other-$fn", $infn, FileRepo::OVERWRITE );
                        $infn = $f->value;
                }
                // This should work because we're allowed to overwrite
@@ -106,7 +106,7 @@ class StoreBatchTest extends MediaWikiTestCase {
                $this->assertEquals( $f->successCount, 1, "counts wrong {$f->successCount} {$f->failCount}" );
                // This should fail because we're overwriting different content.
                if ( $fromrepo ) {
-                       $f = $this->storeit( "Other-$fn", $otherfn, FileRepo::OVERWRITE);
+                       $f = $this->storeit( "Other-$fn", $otherfn, FileRepo::OVERWRITE );
                        $otherfn = $f->value;
                }
                $f = $this->storeit( $fn, $otherfn, FileRepo::OVERWRITE_SAME );
index 56485d3..74b921a 100644 (file)
@@ -24,17 +24,17 @@ class InstallDocFormatterTest extends MediaWikiTestCase {
                # Format: (expected string, unformattedText string, optional message)
                return array(
                        # Escape some wikitext
-                       array( 'Install &lt;tag>' , 'Install <tag>', 'Escaping <' ),
-                       array( 'Install &#123;&#123;template}}' , 'Install {{template}}', 'Escaping [[' ),
-                       array( 'Install &#91;&#91;page]]' , 'Install [[page]]', 'Escaping {{' ),
-                       array( 'Install ' , "Install \r", 'Removing \r' ),
+                       array( 'Install &lt;tag>', 'Install <tag>', 'Escaping <' ),
+                       array( 'Install &#123;&#123;template}}', 'Install {{template}}', 'Escaping [[' ),
+                       array( 'Install &#91;&#91;page]]', 'Install [[page]]', 'Escaping {{' ),
+                       array( 'Install ', "Install \r", 'Removing \r' ),
 
                        # Transform \t{1,2} into :{1,2}
                        array( ':One indentation', "\tOne indentation", 'Replacing a single \t' ),
                        array( '::Two indentations', "\t\tTwo indentations", 'Replacing 2 x \t' ),
 
                        # Transform 'bug 123' links
-                       array( 
+                       array(
                                '<span class="config-plainlink">[https://bugzilla.wikimedia.org/123 bug 123]</span>',
                                'bug 123', 'Testing bug 123 links' ),
                        array(
@@ -55,7 +55,7 @@ class InstallDocFormatterTest extends MediaWikiTestCase {
                        array(
                                '<span class="config-plainlink">[http://www.mediawiki.org/wiki/Manual:$wgFoo_Bar $wgFoo_Bar]</span>',
                                '$wgFoo_Bar', 'Testing $wgFoo_Bar (with underscore)' ),
-                       
+
                        # Icky variables that shouldn't link
                        array( '$myAwesomeVariable', '$myAwesomeVariable', 'Testing $myAwesomeVariable (not starting with $wg)' ),
                        array( '$()not!a&Var', '$()not!a&Var', 'Testing $()not!a&Var (obviously not a variable)' ),
diff --git a/tests/phpunit/includes/jobqueue/JobQueueTest.php b/tests/phpunit/includes/jobqueue/JobQueueTest.php
new file mode 100644 (file)
index 0000000..367a8b3
--- /dev/null
@@ -0,0 +1,274 @@
+<?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 8f2421a..56dc648 100644 (file)
@@ -14,7 +14,7 @@ class ServicesJsonTest extends MediaWikiTestCase {
                if ( !function_exists( 'json_encode' ) ) {
                        $this->markTestIncomplete( 'No PHP json support, unable to test' );
                        return;
-               } elseif( strtolower( json_encode( "\xf0\xa0\x80\x80" ) ) != '"\ud840\udc00"' ) {
+               } elseif ( strtolower( json_encode( "\xf0\xa0\x80\x80" ) ) != '"\ud840\udc00"' ) {
                        $this->markTestIncomplete( 'Have buggy PHP json support, unable to test' );
                        return;
                } else {
index 2cd86ea..26747b9 100644 (file)
@@ -17,10 +17,9 @@ class CSSJanusTest extends MediaWikiTestCase {
 
                        $transformedB = CSSJanus::transform( $cssB );
                        $this->assertEquals( $transformedB, $cssA, 'Test B-A transformation' );
-
-               // If no B version is provided, it means
-               // the output should equal the input.
                } else {
+                       // If no B version is provided, it means
+                       // the output should equal the input.
                        $transformedA = CSSJanus::transform( $cssA );
                        $this->assertEquals( $transformedA, $cssA, 'Nothing was flipped' );
                }
@@ -36,10 +35,11 @@ class CSSJanusTest extends MediaWikiTestCase {
                $flipped = CSSJanus::transform( $code, $swapLtrRtlInURL, $swapLeftRightInURL );
 
                $this->assertEquals( $expectedOutput, $flipped,
-                       'Test flipping, options: url-ltr-rtl=' . ($swapLtrRtlInURL ? 'true' : 'false')
-                               . ' url-left-right=' . ($swapLeftRightInURL ? 'true' : 'false')
+                       'Test flipping, options: url-ltr-rtl=' . ( $swapLtrRtlInURL ? 'true' : 'false' )
+                               . ' url-left-right=' . ( $swapLeftRightInURL ? 'true' : 'false' )
                );
        }
+
        /**
         * @dataProvider provideTransformBrokenCases
         * @group Broken
index 3bbf3aa..37a9b34 100644 (file)
@@ -112,8 +112,7 @@ abstract class GenericArrayObjectTest extends MediaWikiTestCase {
        public function testUnset( GenericArrayObject $list ) {
                if ( $list->isEmpty() ) {
                        $this->assertTrue( true ); // We cannot test unset if there are no elements
-               }
-               else {
+               } else {
                        $offset = $list->getIterator()->key();
                        $count = $list->count();
                        $list->offsetUnset( $offset );
@@ -154,7 +153,7 @@ abstract class GenericArrayObjectTest extends MediaWikiTestCase {
 
                $this->assertEquals( $listSize, $list->count() );
 
-               $this->checkTypeChecks( function( GenericArrayObject $list, $element ) {
+               $this->checkTypeChecks( function ( GenericArrayObject $list, $element ) {
                        $list->append( $element );
                } );
        }
@@ -173,11 +172,10 @@ abstract class GenericArrayObjectTest extends MediaWikiTestCase {
                foreach ( array( 42, 'foo', array(), new stdClass(), 4.2 ) as $element ) {
                        $validValid = $element instanceof $elementClass;
 
-                       try{
+                       try {
                                call_user_func( $function, $list, $element );
                                $valid = true;
-                       }
-                       catch ( InvalidArgumentException $exception ) {
+                       } catch ( InvalidArgumentException $exception ) {
                                $valid = false;
                        }
 
@@ -236,7 +234,7 @@ abstract class GenericArrayObjectTest extends MediaWikiTestCase {
 
                $this->assertEquals( count( $elements ), $list->count() );
 
-               $this->checkTypeChecks( function( GenericArrayObject $list, $element ) {
+               $this->checkTypeChecks( function ( GenericArrayObject $list, $element ) {
                        $list->offsetSet( mt_rand(), $element );
                } );
        }
index c6270e9..984907b 100644 (file)
@@ -5,7 +5,7 @@
  */
 class IEUrlExtensionTest extends MediaWikiTestCase {
        function testSimple() {
-               $this->assertEquals( 
+               $this->assertEquals(
                        'y',
                        IEUrlExtension::findIE6Extension( 'x.y' ),
                        'Simple extension'
index f121b01..1f55079 100644 (file)
@@ -14,7 +14,7 @@ class JavaScriptMinifierTest extends MediaWikiTestCase {
                         * At some point there was a bug that caused this comment to be ended at '* /',
                         * causing /M... to be left as the beginning of a regex.
                         */
-                       array( "/**\n * Foo\n * {\n * 'bar' : {\n * //Multiple rules with configurable operators\n * 'baz' : false\n * }\n */", ""),
+                       array( "/**\n * Foo\n * {\n * 'bar' : {\n * //Multiple rules with configurable operators\n * 'baz' : false\n * }\n */", "" ),
 
                        /**
                         * '  Foo \' bar \
@@ -80,7 +80,7 @@ class JavaScriptMinifierTest extends MediaWikiTestCase {
                        array( "switch(x){case y?z:{}/  x/g:{}/  x/g;}", "switch(x){case y?z:{}/x/g:{}/  x/g;}" ),
                        array( "function x(){}/  x/g", "function x(){}/  x/g" ),
                        array( "+function x(){}/  x/g", "+function x(){}/x/g" ),
-                       
+
                        // Multiline quoted string
                        array( "var foo=\"\\\nblah\\\n\";", "var foo=\"\\\nblah\\\n\";" ),
 
@@ -96,16 +96,16 @@ class JavaScriptMinifierTest extends MediaWikiTestCase {
                        // Division vs. regex nastiness
                        array( "alert( (10+10) / '/'.charCodeAt( 0 ) + '//' );", "alert((10+10)/'/'.charCodeAt(0)+'//');" ),
                        array( "if(1)/a /g.exec('Pa ss');", "if(1)/a /g.exec('Pa ss');" ),
-                       
+
                        // newline insertion after 1000 chars: break after the "++", not before
                        array( str_repeat( ';', 996 ) . "if(x++);", str_repeat( ';', 996 ) . "if(x++\n);" ),
 
                        // Unicode letter characters should pass through ok in identifiers (bug 31187)
-                       array( "var KaŝSkatolVal = {}", 'var KaŝSkatolVal={}'),
+                       array( "var KaŝSkatolVal = {}", 'var KaŝSkatolVal={}' ),
 
                        // Per spec unicode char escape values should work in identifiers,
                        // as long as it's a valid char. In future it might get normalized.
-                       array( "var Ka\\u015dSkatolVal = {}", 'var Ka\\u015dSkatolVal={}'),
+                       array( "var Ka\\u015dSkatolVal = {}", 'var Ka\\u015dSkatolVal={}' ),
 
                        // Some structures that might look invalid at first sight
                        array( "var a = 5.;", "var a=5.;" ),
@@ -137,7 +137,7 @@ class JavaScriptMinifierTest extends MediaWikiTestCase {
                        array(
                                // This one gets interpreted all together by the prior code;
                                // no break at the 'E' happens.
-                               '1.23456789E55',                                
+                               '1.23456789E55',
                        ),
                        array(
                                // This one breaks under the bad code; splits between 'E' and '+'
@@ -165,6 +165,6 @@ class JavaScriptMinifierTest extends MediaWikiTestCase {
 
                $minified = JavaScriptMinifier::minify( $input );
 
-               $this->assertEquals( $expected, $minified, "Line breaks must not occur in middle of exponent");
+               $this->assertEquals( $expected, $minified, "Line breaks must not occur in middle of exponent" );
        }
 }
index 2fa2cc0..e8ccf43 100755 (executable)
@@ -29,7 +29,7 @@ class LogFormatterTest extends MediaWikiLangTestCase {
                        'wgLogActionsHandlers' => array( 'phpunit/test' => 'LogFormatter',
                                'phpunit/param' => 'LogFormatter' ),
                        'wgUser' => User::newFromName( 'Testuser' ),
-                       'wgExtensionMessagesFiles' => array( 'LogTests' => __DIR__.'/LogTests.i18n.php' ),
+                       'wgExtensionMessagesFiles' => array( 'LogTests' => __DIR__ . '/LogTests.i18n.php' ),
                ) );
 
                $wgLang->getLocalisationCache()->recache( $wgLang->getCode() );
index c074696..78787ba 100755 (executable)
@@ -8,8 +8,8 @@
 $messages = array();
 
 $messages['en'] = array(
-       'log-name-phpunit'        => 'PHPUnit-log',
+       'log-name-phpunit' => 'PHPUnit-log',
        'log-description-phpunit' => 'Log for PHPUnit-tests',
-       'logentry-phpunit-test'   => '$1 {{GENDER:$2|tests}} with page $3',
-       'logentry-phpunit-param'  => '$4',
+       'logentry-phpunit-test' => '$1 {{GENDER:$2|tests}} with page $3',
+       'logentry-phpunit-param' => '$4',
 );
index cfd75d8..b221b83 100644 (file)
@@ -34,10 +34,10 @@ class BitmapMetadataHandlerTest extends MediaWikiTestCase {
 
                $expected = array(
                        'x-default' => 'right(iptc)',
-                       'en'        => 'right translation',
-                       '_type'     => 'lang'
+                       'en' => 'right translation',
+                       '_type' => 'lang'
                );
-               
+
                $this->assertArrayHasKey( 'ImageDescription', $meta,
                        'Did not extract any ImageDescription info?!' );
 
@@ -122,25 +122,25 @@ class BitmapMetadataHandlerTest extends MediaWikiTestCase {
                }
                $handler = new BitmapMetadataHandler();
                $result = $handler->png( $this->filePath . 'xmp.png' );
-               $expected = array (
+               $expected = array(
                        'frameCount' => 0,
                        'loopCount' => 1,
                        'duration' => 0,
                        'bitDepth' => 1,
                        'colorType' => 'index-coloured',
-                       'metadata' => array (
+                       'metadata' => array(
                                'SerialNumber' => '123456789',
                                '_MW_PNG_VERSION' => 1,
                        ),
                );
-               $this->assertEquals( $expected, $result ); 
+               $this->assertEquals( $expected, $result );
        }
 
        public function testPNGNative() {
                $handler = new BitmapMetadataHandler();
                $result = $handler->png( $this->filePath . 'Png-native-test.png' );
                $expected = 'http://example.com/url';
-               $this->assertEquals( $expected, $result['metadata']['Identifier']['x-default'] ); 
+               $this->assertEquals( $expected, $result['metadata']['Identifier']['x-default'] );
        }
 
        public function testTiffByteOrder() {
index eb1a536..3de60b7 100644 (file)
@@ -21,14 +21,14 @@ class BitmapScalingTest extends MediaWikiTestCase {
                $this->assertTrue( $valid );
                $this->assertEquals( $expectedParams, $params, $msg );
        }
-       
+
        function provideNormaliseParams() {
                return array(
-                       /* Regular resize operations */ 
+                       /* Regular resize operations */
                        array(
                                array( 1024, 768 ),
-                               array( 
-                                       'width' => 512, 'height' => 384, 
+                               array(
+                                       'width' => 512, 'height' => 384,
                                        'physicalWidth' => 512, 'physicalHeight' => 384,
                                        'page' => 1,
                                ),
@@ -37,53 +37,53 @@ class BitmapScalingTest extends MediaWikiTestCase {
                        ),
                        array(
                                array( 1024, 768 ),
-                               array( 
-                                       'width' => 512, 'height' => 384, 
+                               array(
+                                       'width' => 512, 'height' => 384,
                                        'physicalWidth' => 512, 'physicalHeight' => 384,
-                                       'page' => 1, 
+                                       'page' => 1,
                                ),
                                array( 'width' => 512, 'height' => 768 ),
                                'Resizing with height set too high',
                        ),
                        array(
                                array( 1024, 768 ),
-                               array( 
-                                       'width' => 512, 'height' => 384, 
+                               array(
+                                       'width' => 512, 'height' => 384,
                                        'physicalWidth' => 512, 'physicalHeight' => 384,
-                                       'page' => 1, 
+                                       'page' => 1,
                                ),
                                array( 'width' => 1024, 'height' => 384 ),
                                'Resizing with height set',
                        ),
-                       
+
                        /* Very tall images */
                        array(
                                array( 1000, 100 ),
-                               array( 
+                               array(
                                        'width' => 5, 'height' => 1,
                                        'physicalWidth' => 5, 'physicalHeight' => 1,
-                                       'page' => 1, 
+                                       'page' => 1,
                                ),
                                array( 'width' => 5 ),
                                'Very wide image',
                        ),
-                       
+
                        array(
                                array( 100, 1000 ),
-                               array( 
+                               array(
                                        'width' => 1, 'height' => 10,
                                        'physicalWidth' => 1, 'physicalHeight' => 10,
-                                       'page' => 1, 
+                                       'page' => 1,
                                ),
                                array( 'width' => 1 ),
                                'Very high image',
                        ),
                        array(
                                array( 100, 1000 ),
-                               array( 
+                               array(
                                        'width' => 1, 'height' => 5,
                                        'physicalWidth' => 1, 'physicalHeight' => 10,
-                                       'page' => 1, 
+                                       'page' => 1,
                                ),
                                array( 'width' => 10, 'height' => 5 ),
                                'Very high image with height set',
@@ -91,10 +91,10 @@ class BitmapScalingTest extends MediaWikiTestCase {
                        /* Max image area */
                        array(
                                array( 4000, 4000 ),
-                               array( 
+                               array(
                                        'width' => 5000, 'height' => 5000,
                                        'physicalWidth' => 4000, 'physicalHeight' => 4000,
-                                       'page' => 1, 
+                                       'page' => 1,
                                ),
                                array( 'width' => 5000 ),
                                'Bigger than max image size but doesn\'t need scaling',
@@ -106,7 +106,7 @@ class BitmapScalingTest extends MediaWikiTestCase {
                $file = new FakeDimensionFile( array( 4000, 4000 ) );
                $handler = new BitmapHandler;
                $params = array( 'width' => '3700' ); // Still bigger than max size.
-               $this->assertEquals( 'TransformParameterError', 
+               $this->assertEquals( 'TransformParameterError',
                        get_class( $handler->doTransform( $file, 'dummy path', '', $params ) ) );
        }
 
@@ -115,10 +115,10 @@ class BitmapScalingTest extends MediaWikiTestCase {
                $file->mustRender = true;
                $handler = new BitmapHandler;
                $params = array( 'width' => '5000' ); // Still bigger than max size.
-               $this->assertEquals( 'TransformParameterError', 
+               $this->assertEquals( 'TransformParameterError',
                        get_class( $handler->doTransform( $file, 'dummy path', '', $params ) ) );
        }
-       
+
        function testImageArea() {
                $file = new FakeDimensionFile( array( 7, 9 ) );
                $handler = new BitmapHandler;
@@ -130,20 +130,24 @@ class FakeDimensionFile extends File {
        public $mustRender = false;
 
        public function __construct( $dimensions ) {
-               parent::__construct( Title::makeTitle( NS_FILE, 'Test' ), 
+               parent::__construct( Title::makeTitle( NS_FILE, 'Test' ),
                        new NullRepo( null ) );
-               
+
                $this->dimensions = $dimensions;
        }
+
        public function getWidth( $page = 1 ) {
                return $this->dimensions[0];
        }
+
        public function getHeight( $page = 1 ) {
                return $this->dimensions[1];
        }
+
        public function mustRender() {
                return $this->mustRender;
        }
+
        public function getPath() {
                return '';
        }
index dd22321..1109c47 100644 (file)
@@ -50,9 +50,9 @@ class ExifBitmapTest extends MediaWikiTestCase {
 
        function testConvertMetadataLatest() {
                $metadata = array(
-                               'foo' => array( 'First', 'Second', '_type' => 'ol' ),
-                               'MEDIAWIKI_EXIF_VERSION' => 2
-                        );
+                       'foo' => array( 'First', 'Second', '_type' => 'ol' ),
+                       'MEDIAWIKI_EXIF_VERSION' => 2
+               );
                $res = $this->handler->convertMetadataVersion( $metadata, 2 );
                $this->assertEquals( $metadata, $res );
        }
@@ -78,7 +78,7 @@ class ExifBitmapTest extends MediaWikiTestCase {
 
        function testConvertMetadataSoftware() {
                $metadata = array(
-                       'Software' => array( array('GIMP', '1.1' ) ),
+                       'Software' => array( array( 'GIMP', '1.1' ) ),
                        'MEDIAWIKI_EXIF_VERSION' => 2,
                );
                $expected = array(
index 88b2a83..db29d17 100644 (file)
@@ -14,11 +14,11 @@ class ExifRotationTest extends MediaWikiTestCase {
                $tmpDir = $this->getNewTempDirectory();
 
                $this->repo = new FSRepo( array(
-                       'name'            => 'temp',
-                       'url'             => 'http://localhost/thumbtest',
-                       'backend'         => new FSFileBackend( array(
-                               'name'           => 'localtesting',
-                               'lockManager'    => 'nullLockManager',
+                       'name' => 'temp',
+                       'url' => 'http://localhost/thumbtest',
+                       'backend' => new FSFileBackend( array(
+                               'name' => 'localtesting',
+                               'lockManager' => 'nullLockManager',
                                'containerPaths' => array( 'temp-thumb' => $tmpDir, 'data' => $filePath )
                        ) )
                ) );
@@ -63,8 +63,8 @@ class ExifRotationTest extends MediaWikiTestCase {
                if ( !BitmapHandler::canRotate() ) {
                        $this->markTestSkipped( "This test needs a rasterizer that can auto-rotate." );
                }
-               foreach( $thumbs as $size => $out ) {
-                       if( preg_match('/^(\d+)px$/', $size, $matches ) ) {
+               foreach ( $thumbs as $size => $out ) {
+                       if ( preg_match( '/^(\d+)px$/', $size, $matches ) ) {
                                $params = array(
                                        'width' => $matches[1],
                                );
@@ -74,7 +74,7 @@ class ExifRotationTest extends MediaWikiTestCase {
                                        'height' => $matches[2]
                                );
                        } else {
-                               throw new MWException('bogus test data format ' . $size);
+                               throw new MWException( 'bogus test data format ' . $size );
                        }
 
                        $file = $this->dataFile( $name, $type );
@@ -84,13 +84,13 @@ class ExifRotationTest extends MediaWikiTestCase {
                        $this->assertEquals( $out[1], $thumb->getHeight(), "$name: thumb reported height check for $size" );
 
                        $gis = getimagesize( $thumb->getLocalCopyPath() );
-                       if ($out[0] > $info['width']) {
+                       if ( $out[0] > $info['width'] ) {
                                // Physical image won't be scaled bigger than the original.
-                               $this->assertEquals( $info['width'], $gis[0], "$name: thumb actual width check for $size");
-                               $this->assertEquals( $info['height'], $gis[1], "$name: thumb actual height check for $size");
+                               $this->assertEquals( $info['width'], $gis[0], "$name: thumb actual width check for $size" );
+                               $this->assertEquals( $info['height'], $gis[1], "$name: thumb actual height check for $size" );
                        } else {
-                               $this->assertEquals( $out[0], $gis[0], "$name: thumb actual width check for $size");
-                               $this->assertEquals( $out[1], $gis[1], "$name: thumb actual height check for $size");
+                               $this->assertEquals( $out[0], $gis[0], "$name: thumb actual width check for $size" );
+                               $this->assertEquals( $out[1], $gis[1], "$name: thumb actual height check for $size" );
                        }
                }
        }
@@ -157,8 +157,8 @@ class ExifRotationTest extends MediaWikiTestCase {
                global $wgEnableAutoRotation;
                $wgEnableAutoRotation = false;
 
-               foreach( $thumbs as $size => $out ) {
-                       if( preg_match('/^(\d+)px$/', $size, $matches ) ) {
+               foreach ( $thumbs as $size => $out ) {
+                       if ( preg_match( '/^(\d+)px$/', $size, $matches ) ) {
                                $params = array(
                                        'width' => $matches[1],
                                );
@@ -168,7 +168,7 @@ class ExifRotationTest extends MediaWikiTestCase {
                                        'height' => $matches[2]
                                );
                        } else {
-                               throw new MWException('bogus test data format ' . $size);
+                               throw new MWException( 'bogus test data format ' . $size );
                        }
 
                        $file = $this->dataFile( $name, $type );
@@ -178,13 +178,13 @@ class ExifRotationTest extends MediaWikiTestCase {
                        $this->assertEquals( $out[1], $thumb->getHeight(), "$name: thumb reported height check for $size" );
 
                        $gis = getimagesize( $thumb->getLocalCopyPath() );
-                       if ($out[0] > $info['width']) {
+                       if ( $out[0] > $info['width'] ) {
                                // Physical image won't be scaled bigger than the original.
-                               $this->assertEquals( $info['width'], $gis[0], "$name: thumb actual width check for $size");
-                               $this->assertEquals( $info['height'], $gis[1], "$name: thumb actual height check for $size");
+                               $this->assertEquals( $info['width'], $gis[0], "$name: thumb actual width check for $size" );
+                               $this->assertEquals( $info['height'], $gis[1], "$name: thumb actual height check for $size" );
                        } else {
-                               $this->assertEquals( $out[0], $gis[0], "$name: thumb actual width check for $size");
-                               $this->assertEquals( $out[1], $gis[1], "$name: thumb actual height check for $size");
+                               $this->assertEquals( $out[0], $gis[0], "$name: thumb actual width check for $size" );
+                               $this->assertEquals( $out[1], $gis[1], "$name: thumb actual height check for $size" );
                        }
                }
                $wgEnableAutoRotation = true;
@@ -232,9 +232,9 @@ class ExifRotationTest extends MediaWikiTestCase {
         */
        function testBitmapExtractPreRotationDimensions( $rotation, $expected ) {
                $result = $this->handler->extractPreRotationDimensions( array(
-                               'physicalWidth' => self::TEST_WIDTH,
-                               'physicalHeight' => self::TEST_HEIGHT,
-                       ), $rotation );
+                       'physicalWidth' => self::TEST_WIDTH,
+                       'physicalHeight' => self::TEST_HEIGHT,
+               ), $rotation );
                $this->assertEquals( $expected, $result );
        }
 
index 7cc56f6..e7e95f7 100644 (file)
@@ -15,7 +15,7 @@ class ExifTest extends MediaWikiTestCase {
 
        public function testGPSExtraction() {
                $filename = $this->mediaPath . 'exif-gps.jpg';
-               $seg = JpegMetadataExtractor::segmentSplitter( $filename ); 
+               $seg = JpegMetadataExtractor::segmentSplitter( $filename );
                $exif = new Exif( $filename, $seg['byteOrder'] );
                $data = $exif->getFilteredData();
                $expected = array(
@@ -30,7 +30,7 @@ class ExifTest extends MediaWikiTestCase {
 
        public function testUnicodeUserComment() {
                $filename = $this->mediaPath . 'exif-user-comment.jpg';
-               $seg = JpegMetadataExtractor::segmentSplitter( $filename ); 
+               $seg = JpegMetadataExtractor::segmentSplitter( $filename );
                $exif = new Exif( $filename, $seg['byteOrder'] );
                $data = $exif->getFilteredData();
 
index 4dadde5..f26d27e 100644 (file)
@@ -7,15 +7,15 @@ class FormatMetadataTest extends MediaWikiTestCase {
                if ( !wfDl( 'exif' ) ) {
                        $this->markTestSkipped( "This test needs the exif extension." );
                }
-               $filePath = __DIR__ .  '/../../data/media';
+               $filePath = __DIR__ . '/../../data/media';
                $this->backend = new FSFileBackend( array(
-                       'name'           => 'localtesting',
-                       'lockManager'    => 'nullLockManager',
+                       'name' => 'localtesting',
+                       'lockManager' => 'nullLockManager',
                        'containerPaths' => array( 'data' => $filePath )
                ) );
                $this->repo = new FSRepo( array(
-                       'name'    => 'temp',
-                       'url'     => 'http://localhost/thumbtest',
+                       'name' => 'temp',
+                       'url' => 'http://localhost/thumbtest',
                        'backend' => $this->backend
                ) );
 
@@ -24,11 +24,11 @@ class FormatMetadataTest extends MediaWikiTestCase {
 
        public function testInvalidDate() {
                $file = $this->dataFile( 'broken_exif_date.jpg', 'image/jpeg' );
-               
+
                // Throws an error if bug hit
                $meta = $file->formatMetadata();
                $this->assertNotEquals( false, $meta, 'Valid metadata extracted' );
-               
+
                // Find date exif entry
                $this->assertArrayHasKey( 'visible', $meta );
                $dateIndex = null;
@@ -38,7 +38,7 @@ class FormatMetadataTest extends MediaWikiTestCase {
                        }
                }
                $this->assertNotNull( $dateIndex, 'Date entry exists in metadata' );
-               $this->assertEquals( '0000:01:00 00:02:27', 
+               $this->assertEquals( '0000:01:00 00:02:27',
                        $meta['visible'][$dateIndex]['value'],
                        'File with invalid date metadata (bug 29471)' );
        }
index 3a750aa..86cf346 100644 (file)
@@ -6,6 +6,7 @@ class GIFMetadataExtractorTest extends MediaWikiTestCase {
 
                $this->mediaPath = __DIR__ . '/../../data/media/';
        }
+
        /**
         * Put in a file, and see if the metadata coming out is as expected.
         * @param $filename String
@@ -16,6 +17,7 @@ class GIFMetadataExtractorTest extends MediaWikiTestCase {
                $actual = GIFMetadataExtractor::getMetadata( $this->mediaPath . $filename );
                $this->assertEquals( $expected, $actual );
        }
+
        public static function provideGetMetadata() {
 
                $xmpNugget = <<<EOF
@@ -68,29 +70,35 @@ EOF;
                $xmpNugget = str_replace( "\r", '', $xmpNugget ); // Windows compat
 
                return array(
-                       array( 'nonanimated.gif', array(
-                               'comment' => array( 'GIF test file ⁕ Created with GIMP' ),
-                               'duration' => 0.1,
-                               'frameCount' => 1,
-                               'looped' => false,
-                               'xmp' => '',
+                       array(
+                               'nonanimated.gif',
+                               array(
+                                       'comment' => array( 'GIF test file ⁕ Created with GIMP' ),
+                                       'duration' => 0.1,
+                                       'frameCount' => 1,
+                                       'looped' => false,
+                                       'xmp' => '',
                                )
                        ),
-                       array( 'animated.gif', array(
-                               'comment' => array( 'GIF test file . Created with GIMP' ),
-                               'duration' => 2.4,
-                               'frameCount' => 4,
-                               'looped' => true,
-                               'xmp' => '',
+                       array(
+                               'animated.gif',
+                               array(
+                                       'comment' => array( 'GIF test file . Created with GIMP' ),
+                                       'duration' => 2.4,
+                                       'frameCount' => 4,
+                                       'looped' => true,
+                                       'xmp' => '',
                                )
                        ),
 
-                       array( 'animated-xmp.gif', array(
-                               'xmp' => $xmpNugget,
-                               'duration' => 2.4,
-                               'frameCount' => 4,
-                               'looped' => true,
-                               'comment' => array( 'GIƒ·test·file' ),
+                       array(
+                               'animated-xmp.gif',
+                               array(
+                                       'xmp' => $xmpNugget,
+                                       'duration' => 2.4,
+                                       'frameCount' => 4,
+                                       'looped' => true,
+                                       'comment' => array( 'GIƒ·test·file' ),
                                )
                        ),
                );
index 9ffc764..7ea6b7e 100644 (file)
@@ -4,15 +4,15 @@ class GIFHandlerTest extends MediaWikiTestCase {
        protected function setUp() {
                parent::setUp();
 
-               $this->filePath = __DIR__ .  '/../../data/media';
+               $this->filePath = __DIR__ . '/../../data/media';
                $this->backend = new FSFileBackend( array(
-                       'name'           => 'localtesting',
-                       'lockManager'    => 'nullLockManager',
+                       'name' => 'localtesting',
+                       'lockManager' => 'nullLockManager',
                        'containerPaths' => array( 'data' => $this->filePath )
                ) );
                $this->repo = new FSRepo( array(
-                       'name'    => 'temp',
-                       'url'     => 'http://localhost/thumbtest',
+                       'name' => 'temp',
+                       'url' => 'http://localhost/thumbtest',
                        'backend' => $this->backend
                ) );
                $this->handler = new GIFHandler();
@@ -33,6 +33,7 @@ class GIFHandlerTest extends MediaWikiTestCase {
                $actual = $this->handler->isAnimatedImage( $file );
                $this->assertEquals( $expected, $actual );
        }
+
        public static function provideIsAnimated() {
                return array(
                        array( 'animated.gif', true ),
@@ -50,6 +51,7 @@ class GIFHandlerTest extends MediaWikiTestCase {
                $actual = $this->handler->getImageArea( $file, $file->getWidth(), $file->getHeight() );
                $this->assertEquals( $expected, $actual );
        }
+
        public static function provideGetImageArea() {
                return array(
                        array( 'animated.gif', 5400 ),
@@ -66,6 +68,7 @@ class GIFHandlerTest extends MediaWikiTestCase {
                $actual = $this->handler->isMetadataValid( null, $metadata );
                $this->assertEquals( $expected, $actual );
        }
+
        public static function provideIsMetadataValid() {
                return array(
                        array( GIFHandler::BROKEN_FILE, GIFHandler::METADATA_GOOD ),
index ec6deeb..c9648a7 100644 (file)
@@ -14,6 +14,7 @@ class IPTCTest extends MediaWikiTestCase {
                $res = IPTC::Parse( $iptcData );
                $this->assertEquals( array( '¼' ), $res['Keywords'] );
        }
+
        /* This one contains a sequence that's valid iso 8859-1 but not valid utf8 */
        /* \xC3 = Ã, \xB8 = ¸  */
        public function testIPTCParseNoCharset88591b() {
@@ -21,6 +22,7 @@ class IPTCTest extends MediaWikiTestCase {
                $res = IPTC::Parse( $iptcData );
                $this->assertEquals( array( 'ÃÃø' ), $res['Keywords'] );
        }
+
        /* Same as testIPTCParseNoCharset88591b, but forcing the charset to utf-8.
         * What should happen is the first "\xC3\xC3" should be dropped as invalid,
         * leaving \xC3\xB8, which is ø
@@ -31,11 +33,13 @@ class IPTCTest extends MediaWikiTestCase {
                $res = IPTC::Parse( $iptcData );
                $this->assertEquals( array( 'ø' ), $res['Keywords'] );
        }
+
        public function testIPTCParseNoCharsetUTF8() {
                $iptcData = "Photoshop 3.0\08BIM\4\4\0\0\0\0\0\x07\x1c\x02\x19\x00\x02¼";
                $res = IPTC::Parse( $iptcData );
                $this->assertEquals( array( '¼' ), $res['Keywords'] );
        }
+
        // Testing something that has 2 values for keyword
        public function testIPTCParseMulti() {
                $iptcData = /* identifier */ "Photoshop 3.0\08BIM\4\4"
@@ -45,6 +49,7 @@ class IPTCTest extends MediaWikiTestCase {
                $res = IPTC::Parse( $iptcData );
                $this->assertEquals( array( '¼', '¼½' ), $res['Keywords'] );
        }
+
        public function testIPTCParseUTF8() {
                // This has the magic "\x1c\x01\x5A\x00\x03\x1B\x25\x47" which marks content as UTF8.
                $iptcData = "Photoshop 3.0\08BIM\4\4\0\0\0\0\0\x0F\x1c\x02\x19\x00\x02¼\x1c\x01\x5A\x00\x03\x1B\x25\x47";
index 6e1c0af..cae7137 100644 (file)
@@ -26,6 +26,7 @@ class JpegMetadataExtractorTest extends MediaWikiTestCase {
                $res = JpegMetadataExtractor::segmentSplitter( $this->filePath . $file );
                $this->assertEquals( array( 'UTF-8 JPEG Comment — ¼' ), $res['COM'] );
        }
+
        public static function provideUtf8Comment() {
                return array(
                        array( 'jpeg-comment-utf.jpg' ),
@@ -33,11 +34,13 @@ class JpegMetadataExtractorTest extends MediaWikiTestCase {
                        array( 'jpeg-padding-odd.jpg' ),
                );
        }
+
        /** The file is iso-8859-1, but it should get auto converted */
        public function testIso88591Comment() {
                $res = JpegMetadataExtractor::segmentSplitter( $this->filePath . 'jpeg-comment-iso8859-1.jpg' );
                $this->assertEquals( array( 'ISO-8859-1 JPEG Comment - ¼' ), $res['COM'] );
        }
+
        /** Comment values that are non-textual (random binary junk) should not be shown.
         * The example test file has a comment with a 0x5 byte in it which is a control character
         * and considered binary junk for our purposes.
@@ -46,6 +49,7 @@ class JpegMetadataExtractorTest extends MediaWikiTestCase {
                $res = JpegMetadataExtractor::segmentSplitter( $this->filePath . 'jpeg-comment-binary.jpg' );
                $this->assertEmpty( $res['COM'] );
        }
+
        /* Very rarely a file can have multiple comments.
         *   Order of comments is based on order inside the file.
         */
@@ -53,16 +57,19 @@ class JpegMetadataExtractorTest extends MediaWikiTestCase {
                $res = JpegMetadataExtractor::segmentSplitter( $this->filePath . 'jpeg-comment-multiple.jpg' );
                $this->assertEquals( array( 'foo', 'bar' ), $res['COM'] );
        }
+
        public function testXMPExtraction() {
                $res = JpegMetadataExtractor::segmentSplitter( $this->filePath . 'jpeg-xmp-psir.jpg' );
                $expected = file_get_contents( $this->filePath . 'jpeg-xmp-psir.xmp' );
                $this->assertEquals( $expected, $res['XMP'] );
        }
+
        public function testPSIRExtraction() {
                $res = JpegMetadataExtractor::segmentSplitter( $this->filePath . 'jpeg-xmp-psir.jpg' );
                $expected = '50686f746f73686f7020332e30003842494d04040000000000181c02190004746573741c02190003666f6f1c020000020004';
                $this->assertEquals( $expected, bin2hex( $res['PSIR'][0] ) );
        }
+
        public function testXMPExtractionAltAppId() {
                $res = JpegMetadataExtractor::segmentSplitter( $this->filePath . 'jpeg-xmp-alt.jpg' );
                $expected = file_get_contents( $this->filePath . 'jpeg-xmp-psir.xmp' );
@@ -76,18 +83,21 @@ class JpegMetadataExtractorTest extends MediaWikiTestCase {
 
                $this->assertEquals( 'iptc-no-hash', $res );
        }
+
        public function testIPTCHashComparisionBadHash() {
                $segments = JpegMetadataExtractor::segmentSplitter( $this->filePath . 'jpeg-iptc-bad-hash.jpg' );
                $res = JpegMetadataExtractor::doPSIR( $segments['PSIR'][0] );
 
                $this->assertEquals( 'iptc-bad-hash', $res );
        }
+
        public function testIPTCHashComparisionGoodHash() {
                $segments = JpegMetadataExtractor::segmentSplitter( $this->filePath . 'jpeg-iptc-good-hash.jpg' );
                $res = JpegMetadataExtractor::doPSIR( $segments['PSIR'][0] );
 
                $this->assertEquals( 'iptc-good-hash', $res );
        }
+
        public function testExifByteOrder() {
                $res = JpegMetadataExtractor::segmentSplitter( $this->filePath . 'exif-user-comment.jpg' );
                $expected = 'BE';
index 0260f29..1e91201 100644 (file)
@@ -5,8 +5,9 @@ class PNGMetadataExtractorTest extends MediaWikiTestCase {
                parent::setUp();
                $this->filePath = __DIR__ . '/../../data/media/';
        }
+
        /**
-        * Tests zTXt tag (compressed textual metadata) 
+        * Tests zTXt tag (compressed textual metadata)
         */
        function testPngNativetZtxt() {
                $this->checkPHPExtension( 'zlib' );
@@ -64,7 +65,7 @@ class PNGMetadataExtractorTest extends MediaWikiTestCase {
         * Test extraction of pHYs tags, which can tell what the
         * actual resolution of the image is (aka in dots per meter).
         */
-/*
+       /*
        function testPngPhysTag () {
                $meta = PNGMetadataExtractor::getMetadata( $this->filePath .
                        'Png-native-test.png' );
@@ -76,7 +77,7 @@ class PNGMetadataExtractorTest extends MediaWikiTestCase {
                $this->assertEquals( '2835/100', $meta['YResolution'] );
                $this->assertEquals( 3, $meta['ResolutionUnit'] ); // 3 = cm
        }
-*/
+       */
 
        /**
         * Given a normal static PNG, check the animation metadata returned.
@@ -110,6 +111,7 @@ class PNGMetadataExtractorTest extends MediaWikiTestCase {
 
                $this->assertEquals( 8, $meta['bitDepth'] );
        }
+
        function testPngBitDepth1() {
                $meta = PNGMetadataExtractor::getMetadata( $this->filePath .
                        '1bit-png.png' );
@@ -123,21 +125,25 @@ class PNGMetadataExtractorTest extends MediaWikiTestCase {
 
                $this->assertEquals( 'index-coloured', $meta['colorType'] );
        }
+
        function testPngRgbColour() {
                $meta = PNGMetadataExtractor::getMetadata( $this->filePath .
                        'rgb-png.png' );
                $this->assertEquals( 'truecolour-alpha', $meta['colorType'] );
        }
+
        function testPngRgbNoAlphaColour() {
                $meta = PNGMetadataExtractor::getMetadata( $this->filePath .
                        'rgb-na-png.png' );
                $this->assertEquals( 'truecolour', $meta['colorType'] );
        }
+
        function testPngGreyscaleColour() {
                $meta = PNGMetadataExtractor::getMetadata( $this->filePath .
                        'greyscale-png.png' );
                $this->assertEquals( 'greyscale-alpha', $meta['colorType'] );
        }
+
        function testPngGreyscaleNoAlphaColour() {
                $meta = PNGMetadataExtractor::getMetadata( $this->filePath .
                        'greyscale-na-png.png' );
index 2075758..855780d 100644 (file)
@@ -4,15 +4,15 @@ class PNGHandlerTest extends MediaWikiTestCase {
        protected function setUp() {
                parent::setUp();
 
-               $this->filePath = __DIR__ .  '/../../data/media';
+               $this->filePath = __DIR__ . '/../../data/media';
                $this->backend = new FSFileBackend( array(
-                       'name'           => 'localtesting',
-                       'lockManager'    => 'nullLockManager',
+                       'name' => 'localtesting',
+                       'lockManager' => 'nullLockManager',
                        'containerPaths' => array( 'data' => $this->filePath )
                ) );
                $this->repo = new FSRepo( array(
-                       'name'    => 'temp',
-                       'url'     => 'http://localhost/thumbtest',
+                       'name' => 'temp',
+                       'url' => 'http://localhost/thumbtest',
                        'backend' => $this->backend
                ) );
                $this->handler = new PNGHandler();
@@ -22,6 +22,7 @@ class PNGHandlerTest extends MediaWikiTestCase {
                $res = $this->handler->getMetadata( null, $this->filePath . '/README' );
                $this->assertEquals( PNGHandler::BROKEN_FILE, $res );
        }
+
        /**
         * @param $filename String basename of the file to check
         * @param $expected boolean Expected result.
@@ -32,6 +33,7 @@ class PNGHandlerTest extends MediaWikiTestCase {
                $actual = $this->handler->isAnimatedImage( $file );
                $this->assertEquals( $expected, $actual );
        }
+
        public static function provideIsAnimated() {
                return array(
                        array( 'Animated_PNG_example_bouncing_beach_ball.png', true ),
@@ -45,10 +47,11 @@ class PNGHandlerTest extends MediaWikiTestCase {
         * @dataProvider provideGetImageArea
         */
        public function testGetImageArea( $filename, $expected ) {
-               $file = $this->dataFile($filename, 'image/png' );
+               $file = $this->dataFile( $filename, 'image/png' );
                $actual = $this->handler->getImageArea( $file, $file->getWidth(), $file->getHeight() );
                $this->assertEquals( $expected, $actual );
        }
+
        public static function provideGetImageArea() {
                return array(
                        array( '1bit-png.png', 2500 ),
@@ -67,6 +70,7 @@ class PNGHandlerTest extends MediaWikiTestCase {
                $actual = $this->handler->isMetadataValid( null, $metadata );
                $this->assertEquals( $expected, $actual );
        }
+
        public static function provideIsMetadataValid() {
                return array(
                        array( PNGHandler::BROKEN_FILE, PNGHandler::METADATA_GOOD ),
@@ -88,10 +92,11 @@ class PNGHandlerTest extends MediaWikiTestCase {
 //             $this->assertEquals( unserialize( $expected ), unserialize( $actual ) );
                $this->assertEquals( ( $expected ), ( $actual ) );
        }
+
        public static function provideGetMetadata() {
                return array(
                        array( 'rgb-na-png.png', 'a:6:{s:10:"frameCount";i:0;s:9:"loopCount";i:1;s:8:"duration";d:0;s:8:"bitDepth";i:8;s:9:"colorType";s:10:"truecolour";s:8:"metadata";a:1:{s:15:"_MW_PNG_VERSION";i:1;}}' ),
-                       array( 'xmp.png', 'a:6:{s:10:"frameCount";i:0;s:9:"loopCount";i:1;s:8:"duration";d:0;s:8:"bitDepth";i:1;s:9:"colorType";s:14:"index-coloured";s:8:"metadata";a:2:{s:12:"SerialNumber";s:9:"123456789";s:15:"_MW_PNG_VERSION";i:1;}}' ), 
+                       array( 'xmp.png', 'a:6:{s:10:"frameCount";i:0;s:9:"loopCount";i:1;s:8:"duration";d:0;s:8:"bitDepth";i:1;s:9:"colorType";s:14:"index-coloured";s:8:"metadata";a:2:{s:12:"SerialNumber";s:9:"123456789";s:15:"_MW_PNG_VERSION";i:1;}}' ),
                );
        }
 
index f131972..97a0000 100644 (file)
@@ -13,13 +13,13 @@ class SVGMetadataExtractorTest extends MediaWikiTestCase {
        function testGetMetadata( $infile, $expected ) {
                $this->assertMetadata( $infile, $expected );
        }
-       
+
        /**
         * @dataProvider provideSvgFilesWithXMLMetadata
         */
        function testGetXMLMetadata( $infile, $expected ) {
                $r = new XMLReader();
-               if( !method_exists( $r, 'readInnerXML' ) ) {
+               if ( !method_exists( $r, 'readInnerXML' ) ) {
                        $this->markTestSkipped( 'XMLReader::readInnerXML() does not exist (libxml >2.6.20 needed).' );
                        return;
                }
@@ -84,8 +84,7 @@ class SVGMetadataExtractorTest extends MediaWikiTestCase {
 
        public static function provideSvgFilesWithXMLMetadata() {
                $base = __DIR__ . '/../../data/media';
-               $metadata = 
-    '<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
+               $metadata = '<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
       <ns4:Work xmlns:ns4="http://creativecommons.org/ns#" rdf:about="">
         <ns5:format xmlns:ns5="http://purl.org/dc/elements/1.1/">image/svg+xml</ns5:format>
         <ns5:type xmlns:ns5="http://purl.org/dc/elements/1.1/" rdf:resource="http://purl.org/dc/dcmitype/StillImage"/>
index 452016f..86c722b 100644 (file)
@@ -27,7 +27,7 @@ class XMPTest extends MediaWikiTestCase {
        }
 
        public static function provideXMPParse() {
-               $xmpPath = __DIR__ . '/../../data/xmp/' ;
+               $xmpPath = __DIR__ . '/../../data/xmp/';
                $data = array();
 
                // $xmpFiles format: array of arrays with first arg file base name,
@@ -54,8 +54,9 @@ class XMPTest extends MediaWikiTestCase {
                        array( 'utf32LE', 'UTF-32LE encoding' ),
                        array( 'xmpExt', 'Extended XMP missing second part' ),
                        array( 'gps', 'Handling of exif GPS parameters in XMP' ),
-                );
-               foreach( $xmpFiles as $file ) {
+               );
+
+               foreach ( $xmpFiles as $file ) {
                        $xmp = file_get_contents( $xmpPath . $file[0] . '.xmp' );
                        // I'm not sure if this is the best way to handle getting the
                        // result array, but it seems kind of big to put directly in the test
@@ -88,8 +89,8 @@ class XMPTest extends MediaWikiTestCase {
                $reader->parseExtended( $extendedPacket );
                $actual = $reader->getResults();
 
-               $expected = array( 'xmp-exif' =>
-                       array(
+               $expected = array(
+                       'xmp-exif' => array(
                                'DigitalZoomRatio' => '0/10',
                                'Flash' => 9,
                                'FNumber' => '2/10',
@@ -118,8 +119,8 @@ class XMPTest extends MediaWikiTestCase {
                $reader->parseExtended( $extendedPacket );
                $actual = $reader->getResults();
 
-               $expected = array( 'xmp-exif' =>
-                       array(
+               $expected = array(
+                       'xmp-exif' => array(
                                'DigitalZoomRatio' => '0/10',
                                'Flash' => 9,
                        )
@@ -127,6 +128,7 @@ class XMPTest extends MediaWikiTestCase {
 
                $this->assertEquals( $expected, $actual );
        }
+
        /**
         * Have a high offset to simulate a missing packet,
         * which should cause it to ignore the ExtendedXMP packet.
@@ -146,8 +148,8 @@ class XMPTest extends MediaWikiTestCase {
                $reader->parseExtended( $extendedPacket );
                $actual = $reader->getResults();
 
-               $expected = array( 'xmp-exif' =>
-                       array(
+               $expected = array(
+                       'xmp-exif' => array(
                                'DigitalZoomRatio' => '0/10',
                                'Flash' => 9,
                        )
index d5ad18d..86fd95c 100644 (file)
@@ -65,19 +65,24 @@ class CleanUpTest extends MediaWikiTestCase {
         */
        function XtestAllChars() {
                $rep = UTF8_REPLACEMENT;
-               for( $i = 0x0; $i < UNICODE_MAX; $i++ ) {
+               for ( $i = 0x0; $i < UNICODE_MAX; $i++ ) {
                        $char = codepointToUtf8( $i );
                        $clean = UtfNormal::cleanUp( $char );
                        $x = sprintf( "%04X", $i );
-                       if( $i % 0x1000 == 0 ) echo "U+$x\n";
-                       if( $i == 0x0009 ||
-                           $i == 0x000a ||
-                           $i == 0x000d ||
-                           ($i > 0x001f && $i < UNICODE_SURROGATE_FIRST) ||
-                           ($i > UNICODE_SURROGATE_LAST && $i < 0xfffe ) ||
-                           ($i > 0xffff && $i <= UNICODE_MAX ) ) {
-                               if( isset( UtfNormal::$utfCanonicalComp[$char] ) || isset( UtfNormal::$utfCanonicalDecomp[$char] ) ) {
-                                   $comp = UtfNormal::NFC( $char );
+
+                       if ( $i % 0x1000 == 0 ) {
+                               echo "U+$x\n";
+                       }
+
+                       if ( $i == 0x0009 ||
+                               $i == 0x000a ||
+                               $i == 0x000d ||
+                               ( $i > 0x001f && $i < UNICODE_SURROGATE_FIRST ) ||
+                               ( $i > UNICODE_SURROGATE_LAST && $i < 0xfffe ) ||
+                               ( $i > 0xffff && $i <= UNICODE_MAX )
+                       ) {
+                               if ( isset( UtfNormal::$utfCanonicalComp[$char] ) || isset( UtfNormal::$utfCanonicalDecomp[$char] ) ) {
+                                       $comp = UtfNormal::NFC( $char );
                                        $this->assertEquals(
                                                bin2hex( $comp ),
                                                bin2hex( $clean ),
@@ -104,26 +109,32 @@ class CleanUpTest extends MediaWikiTestCase {
 
        /** @todo document */
        function doTestBytes( $head, $tail ) {
-               for( $i = 0x0; $i < 256; $i++ ) {
+               for ( $i = 0x0; $i < 256; $i++ ) {
                        $char = $head . chr( $i ) . $tail;
                        $clean = UtfNormal::cleanUp( $char );
                        $x = sprintf( "%02X", $i );
-                       if( $i == 0x0009 ||
-                           $i == 0x000a ||
-                           $i == 0x000d ||
-                           ($i > 0x001f && $i < 0x80) ) {
+
+                       if ( $i == 0x0009 ||
+                               $i == 0x000a ||
+                               $i == 0x000d ||
+                               ( $i > 0x001f && $i < 0x80 )
+                       ) {
                                $this->assertEquals(
                                        bin2hex( $char ),
                                        bin2hex( $clean ),
                                        "ASCII byte $x should be intact" );
-                               if( $char != $clean ) return;
+                               if ( $char != $clean ) {
+                                       return;
+                               }
                        } else {
                                $norm = $head . UTF8_REPLACEMENT . $tail;
                                $this->assertEquals(
                                        bin2hex( $norm ),
                                        bin2hex( $clean ),
                                        "Forbidden byte $x should be rejected" );
-                               if( $norm != $clean ) return;
+                               if ( $norm != $clean ) {
+                                       return;
+                               }
                        }
                }
        }
@@ -140,35 +151,42 @@ class CleanUpTest extends MediaWikiTestCase {
         * @todo document
         */
        function doTestDoubleBytes( $head, $tail ) {
-               for( $first = 0xc0; $first < 0x100; $first+=2 ) {
-                       for( $second = 0x80; $second < 0x100; $second+=2 ) {
+               for ( $first = 0xc0; $first < 0x100; $first += 2 ) {
+                       for ( $second = 0x80; $second < 0x100; $second += 2 ) {
                                $char = $head . chr( $first ) . chr( $second ) . $tail;
                                $clean = UtfNormal::cleanUp( $char );
                                $x = sprintf( "%02X,%02X", $first, $second );
-                               if( $first > 0xc1 &&
-                                   $first < 0xe0 &&
-                                   $second < 0xc0 ) {
-                                   $norm = UtfNormal::NFC( $char );
+                               if ( $first > 0xc1 &&
+                                       $first < 0xe0 &&
+                                       $second < 0xc0
+                               ) {
+                                       $norm = UtfNormal::NFC( $char );
                                        $this->assertEquals(
                                                bin2hex( $norm ),
                                                bin2hex( $clean ),
                                                "Pair $x should be intact" );
-                                   if( $norm != $clean ) return;
-                               } elseif( $first > 0xfd || $second > 0xbf ) {
+                                       if ( $norm != $clean ) {
+                                               return;
+                                       }
+                               } elseif ( $first > 0xfd || $second > 0xbf ) {
                                        # fe and ff are not legal head bytes -- expect two replacement chars
                                        $norm = $head . UTF8_REPLACEMENT . UTF8_REPLACEMENT . $tail;
                                        $this->assertEquals(
                                                bin2hex( $norm ),
                                                bin2hex( $clean ),
                                                "Forbidden pair $x should be rejected" );
-                                       if( $norm != $clean ) return;
+                                       if ( $norm != $clean ) {
+                                               return;
+                                       }
                                } else {
                                        $norm = $head . UTF8_REPLACEMENT . $tail;
                                        $this->assertEquals(
                                                bin2hex( $norm ),
                                                bin2hex( $clean ),
                                                "Forbidden pair $x should be rejected" );
-                                       if( $norm != $clean ) return;
+                                       if ( $norm != $clean ) {
+                                               return;
+                                       }
                                }
                        }
                }
@@ -184,24 +202,27 @@ class CleanUpTest extends MediaWikiTestCase {
 
        /** @todo document */
        function doTestTripleBytes( $head, $tail ) {
-               for( $first = 0xc0; $first < 0x100; $first+=2 ) {
-                       for( $second = 0x80; $second < 0x100; $second+=2 ) {
+               for ( $first = 0xc0; $first < 0x100; $first += 2 ) {
+                       for ( $second = 0x80; $second < 0x100; $second += 2 ) {
                                #for( $third = 0x80; $third < 0x100; $third++ ) {
-                               for( $third = 0x80; $third < 0x81; $third++ ) {
+                               for ( $third = 0x80; $third < 0x81; $third++ ) {
                                        $char = $head . chr( $first ) . chr( $second ) . chr( $third ) . $tail;
                                        $clean = UtfNormal::cleanUp( $char );
                                        $x = sprintf( "%02X,%02X,%02X", $first, $second, $third );
-                                       if( $first >= 0xe0 &&
+
+                                       if ( $first >= 0xe0 &&
                                                $first < 0xf0 &&
                                                $second < 0xc0 &&
-                                               $third < 0xc0 ) {
-                                               if( $first == 0xe0 && $second < 0xa0 ) {
+                                               $third < 0xc0
+                                       ) {
+                                               if ( $first == 0xe0 && $second < 0xa0 ) {
                                                        $this->assertEquals(
                                                                bin2hex( $head . UTF8_REPLACEMENT . $tail ),
                                                                bin2hex( $clean ),
                                                                "Overlong triplet $x should be rejected" );
-                                               } elseif( $first == 0xed &&
-                                                       ( chr( $first ) . chr( $second ) . chr( $third ))  >= UTF8_SURROGATE_FIRST ) {
+                                               } elseif ( $first == 0xed &&
+                                                       ( chr( $first ) . chr( $second ) . chr( $third ) ) >= UTF8_SURROGATE_FIRST
+                                               ) {
                                                        $this->assertEquals(
                                                                bin2hex( $head . UTF8_REPLACEMENT . $tail ),
                                                                bin2hex( $clean ),
@@ -212,27 +233,28 @@ class CleanUpTest extends MediaWikiTestCase {
                                                                bin2hex( $clean ),
                                                                "Triplet $x should be intact" );
                                                }
-                                       } elseif( $first > 0xc1 && $first < 0xe0 && $second < 0xc0 ) {
+                                       } elseif ( $first > 0xc1 && $first < 0xe0 && $second < 0xc0 ) {
                                                $this->assertEquals(
                                                        bin2hex( UtfNormal::NFC( $head . chr( $first ) . chr( $second ) ) . UTF8_REPLACEMENT . $tail ),
                                                        bin2hex( $clean ),
                                                        "Valid 2-byte $x + broken tail" );
-                                       } elseif( $second > 0xc1 && $second < 0xe0 && $third < 0xc0 ) {
+                                       } elseif ( $second > 0xc1 && $second < 0xe0 && $third < 0xc0 ) {
                                                $this->assertEquals(
                                                        bin2hex( $head . UTF8_REPLACEMENT . UtfNormal::NFC( chr( $second ) . chr( $third ) . $tail ) ),
                                                        bin2hex( $clean ),
                                                        "Broken head + valid 2-byte $x" );
-                                       } elseif( ( $first > 0xfd || $second > 0xfd ) &&
-                                                   ( ( $second > 0xbf && $third > 0xbf ) ||
-                                                     ( $second < 0xc0 && $third < 0xc0 ) ||
-                                                     ( $second > 0xfd ) ||
-                                                     ( $third > 0xfd ) ) ) {
+                                       } elseif ( ( $first > 0xfd || $second > 0xfd ) &&
+                                               ( ( $second > 0xbf && $third > 0xbf ) ||
+                                                       ( $second < 0xc0 && $third < 0xc0 ) ||
+                                                       ( $second > 0xfd ) ||
+                                                       ( $third > 0xfd ) )
+                                       ) {
                                                # fe and ff are not legal head bytes -- expect three replacement chars
                                                $this->assertEquals(
                                                        bin2hex( $head . UTF8_REPLACEMENT . UTF8_REPLACEMENT . UTF8_REPLACEMENT . $tail ),
                                                        bin2hex( $clean ),
                                                        "Forbidden triplet $x should be rejected" );
-                                       } elseif( $first > 0xc2 && $second < 0xc0 && $third < 0xc0 ) {
+                                       } elseif ( $first > 0xc2 && $second < 0xc0 && $third < 0xc0 ) {
                                                $this->assertEquals(
                                                        bin2hex( $head . UTF8_REPLACEMENT . $tail ),
                                                        bin2hex( $clean ),
@@ -251,20 +273,20 @@ class CleanUpTest extends MediaWikiTestCase {
        /** @todo document */
        function testChunkRegression() {
                # Check for regression against a chunking bug
-               $text   = "\x46\x55\xb8" .
-                         "\xdc\x96" .
-                         "\xee" .
-                         "\xe7" .
-                         "\x44" .
-                         "\xaa" .
-                         "\x2f\x25";
+               $text = "\x46\x55\xb8" .
+                       "\xdc\x96" .
+                       "\xee" .
+                       "\xe7" .
+                       "\x44" .
+                       "\xaa" .
+                       "\x2f\x25";
                $expect = "\x46\x55\xef\xbf\xbd" .
-                         "\xdc\x96" .
-                         "\xef\xbf\xbd" .
-                         "\xef\xbf\xbd" .
-                         "\x44" .
-                         "\xef\xbf\xbd" .
-                         "\x2f\x25";
+                       "\xdc\x96" .
+                       "\xef\xbf\xbd" .
+                       "\xef\xbf\xbd" .
+                       "\x44" .
+                       "\xef\xbf\xbd" .
+                       "\x2f\x25";
 
                $this->assertEquals(
                        bin2hex( $expect ),
@@ -273,33 +295,33 @@ class CleanUpTest extends MediaWikiTestCase {
 
        /** @todo document */
        function testInterposeRegression() {
-               $text   = "\x4e\x30" .
-                         "\xb1" .              # bad tail
-                         "\x3a" .
-                         "\x92" .              # bad tail
-                         "\x62\x3a" .
-                         "\x84" .              # bad tail
-                         "\x43" .
-                         "\xc6" .              # bad head
-                         "\x3f" .
-                         "\x92" .              # bad tail
-                         "\xad" .              # bad tail
-                         "\x7d" .
-                         "\xd9\x95";
+               $text = "\x4e\x30" .
+                       "\xb1" . # bad tail
+                       "\x3a" .
+                       "\x92" . # bad tail
+                       "\x62\x3a" .
+                       "\x84" . # bad tail
+                       "\x43" .
+                       "\xc6" . # bad head
+                       "\x3f" .
+                       "\x92" . # bad tail
+                       "\xad" . # bad tail
+                       "\x7d" .
+                       "\xd9\x95";
 
                $expect = "\x4e\x30" .
-                         "\xef\xbf\xbd" .
-                         "\x3a" .
-                         "\xef\xbf\xbd" .
-                         "\x62\x3a" .
-                         "\xef\xbf\xbd" .
-                         "\x43" .
-                         "\xef\xbf\xbd" .
-                         "\x3f" .
-                         "\xef\xbf\xbd" .
-                         "\xef\xbf\xbd" .
-                         "\x7d" .
-                         "\xd9\x95";
+                       "\xef\xbf\xbd" .
+                       "\x3a" .
+                       "\xef\xbf\xbd" .
+                       "\x62\x3a" .
+                       "\xef\xbf\xbd" .
+                       "\x43" .
+                       "\xef\xbf\xbd" .
+                       "\x3f" .
+                       "\xef\xbf\xbd" .
+                       "\xef\xbf\xbd" .
+                       "\x7d" .
+                       "\xd9\x95";
 
                $this->assertEquals(
                        bin2hex( $expect ),
@@ -308,24 +330,24 @@ class CleanUpTest extends MediaWikiTestCase {
 
        /** @todo document */
        function testOverlongRegression() {
-               $text   = "\x67" .
-                         "\x1a" . # forbidden ascii
-                         "\xea" . # bad head
-                         "\xc1\xa6" . # overlong sequence
-                         "\xad" . # bad tail
-                         "\x1c" . # forbidden ascii
-                         "\xb0" . # bad tail
-                         "\x3c" .
-                         "\x9e";  # bad tail
+               $text = "\x67" .
+                       "\x1a" . # forbidden ascii
+                       "\xea" . # bad head
+                       "\xc1\xa6" . # overlong sequence
+                       "\xad" . # bad tail
+                       "\x1c" . # forbidden ascii
+                       "\xb0" . # bad tail
+                       "\x3c" .
+                       "\x9e"; # bad tail
                $expect = "\x67" .
-                         "\xef\xbf\xbd" .
-                         "\xef\xbf\xbd" .
-                         "\xef\xbf\xbd" .
-                         "\xef\xbf\xbd" .
-                         "\xef\xbf\xbd" .
-                         "\xef\xbf\xbd" .
-                         "\x3c" .
-                         "\xef\xbf\xbd";
+                       "\xef\xbf\xbd" .
+                       "\xef\xbf\xbd" .
+                       "\xef\xbf\xbd" .
+                       "\xef\xbf\xbd" .
+                       "\xef\xbf\xbd" .
+                       "\xef\xbf\xbd" .
+                       "\x3c" .
+                       "\xef\xbf\xbd";
                $this->assertEquals(
                        bin2hex( $expect ),
                        bin2hex( UtfNormal::cleanUp( $text ) ) );
@@ -333,14 +355,14 @@ class CleanUpTest extends MediaWikiTestCase {
 
        /** @todo document */
        function testSurrogateRegression() {
-               $text   = "\xed\xb4\x96" . # surrogate 0xDD16
-                         "\x83" . # bad tail
-                         "\xb4" . # bad tail
-                         "\xac";  # bad head
+               $text = "\xed\xb4\x96" . # surrogate 0xDD16
+                       "\x83" . # bad tail
+                       "\xb4" . # bad tail
+                       "\xac"; # bad head
                $expect = "\xef\xbf\xbd" .
-                         "\xef\xbf\xbd" .
-                         "\xef\xbf\xbd" .
-                         "\xef\xbf\xbd";
+                       "\xef\xbf\xbd" .
+                       "\xef\xbf\xbd" .
+                       "\xef\xbf\xbd";
                $this->assertEquals(
                        bin2hex( $expect ),
                        bin2hex( UtfNormal::cleanUp( $text ) ) );
@@ -348,14 +370,14 @@ class CleanUpTest extends MediaWikiTestCase {
 
        /** @todo document */
        function testBomRegression() {
-               $text   = "\xef\xbf\xbe" . # U+FFFE, illegal char
-                         "\xb2" . # bad tail
-                         "\xef" . # bad head
-                         "\x59";
+               $text = "\xef\xbf\xbe" . # U+FFFE, illegal char
+                       "\xb2" . # bad tail
+                       "\xef" . # bad head
+                       "\x59";
                $expect = "\xef\xbf\xbd" .
-                         "\xef\xbf\xbd" .
-                         "\xef\xbf\xbd" .
-                         "\x59";
+                       "\xef\xbf\xbd" .
+                       "\xef\xbf\xbd" .
+                       "\x59";
                $this->assertEquals(
                        bin2hex( $expect ),
                        bin2hex( UtfNormal::cleanUp( $text ) ) );
@@ -363,7 +385,7 @@ class CleanUpTest extends MediaWikiTestCase {
 
        /** @todo document */
        function testForbiddenRegression() {
-               $text   = "\xef\xbf\xbf"; # U+FFFF, illegal char
+               $text = "\xef\xbf\xbf"; # U+FFFF, illegal char
                $expect = "\xef\xbf\xbd";
                $this->assertEquals(
                        bin2hex( $expect ),
@@ -373,8 +395,8 @@ class CleanUpTest extends MediaWikiTestCase {
        /** @todo document */
        function testHangulRegression() {
                $text = "\xed\x9c\xaf" . # Hangul char
-                               "\xe1\x87\x81";  # followed by another final jamo
-               $expect = $text;         # Should *not* change.
+                       "\xe1\x87\x81"; # followed by another final jamo
+               $expect = $text; # Should *not* change.
                $this->assertEquals(
                        bin2hex( $expect ),
                        bin2hex( UtfNormal::cleanUp( $text ) ) );
index f5264be..f3dd0a0 100644 (file)
@@ -15,9 +15,8 @@ class BagOStuffTest extends MediaWikiTestCase {
                        $name = $this->getCliArg( 'use-bagostuff=' );
 
                        $this->cache = ObjectCache::newFromId( $name );
-
-               // no type defined - use simple hash
                } else {
+                       // no type defined - use simple hash
                        $this->cache = new HashBagOStuff;
                }
 
@@ -41,7 +40,7 @@ class BagOStuffTest extends MediaWikiTestCase {
                 * @use int $usleep
                 * @return int
                 */
-               $callback = function( BagOStuff $cache, $key, $existingValue ) use ( &$usleep ) {
+               $callback = function ( BagOStuff $cache, $key, $existingValue ) use ( &$usleep ) {
                        // let's pretend this is an expensive callback to test concurrent merge attempts
                        usleep( $usleep );
 
index c82ae9b..dfcdafd 100644 (file)
@@ -69,14 +69,17 @@ class MagicVariableTest extends MediaWikiTestCase {
        function testCurrentdayIsUnPadded( $day ) {
                $this->assertUnPadded( 'currentday', $day );
        }
+
        /** @dataProvider MediaWikiProvide::Days */
        function testCurrentdaytwoIsZeroPadded( $day ) {
                $this->assertZeroPadded( 'currentday2', $day );
        }
+
        /** @dataProvider MediaWikiProvide::Days */
        function testLocaldayIsUnPadded( $day ) {
                $this->assertUnPadded( 'localday', $day );
        }
+
        /** @dataProvider MediaWikiProvide::Days */
        function testLocaldaytwoIsZeroPadded( $day ) {
                $this->assertZeroPadded( 'localday2', $day );
@@ -88,14 +91,17 @@ class MagicVariableTest extends MediaWikiTestCase {
        function testCurrentmonthIsZeroPadded( $month ) {
                $this->assertZeroPadded( 'currentmonth', $month );
        }
+
        /** @dataProvider MediaWikiProvide::Months */
        function testCurrentmonthoneIsUnPadded( $month ) {
                $this->assertUnPadded( 'currentmonth1', $month );
        }
+
        /** @dataProvider MediaWikiProvide::Months */
        function testLocalmonthIsZeroPadded( $month ) {
                $this->assertZeroPadded( 'localmonth', $month );
        }
+
        /** @dataProvider MediaWikiProvide::Months */
        function testLocalmonthoneIsUnPadded( $month ) {
                $this->assertUnPadded( 'localmonth1', $month );
@@ -108,6 +114,7 @@ class MagicVariableTest extends MediaWikiTestCase {
        function testRevisiondayIsUnPadded( $day ) {
                $this->assertUnPadded( 'revisionday', $day );
        }
+
        /** @dataProvider MediaWikiProvide::Days */
        function testRevisiondaytwoIsZeroPadded( $day ) {
                $this->assertZeroPadded( 'revisionday2', $day );
@@ -119,6 +126,7 @@ class MagicVariableTest extends MediaWikiTestCase {
        function testRevisionmonthIsZeroPadded( $month ) {
                $this->assertZeroPadded( 'revisionmonth', $month );
        }
+
        /** @dataProvider MediaWikiProvide::Months */
        function testRevisionmonthoneIsUnPadded( $month ) {
                $this->assertUnPadded( 'revisionmonth1', $month );
@@ -130,13 +138,13 @@ class MagicVariableTest extends MediaWikiTestCase {
         */
        function testServernameFromDifferentProtocols() {
                global $wgServer;
-               $saved_wgServer= $wgServer;
+               $saved_wgServer = $wgServer;
 
                $wgServer = 'http://localhost/';
                $this->assertMagic( 'localhost', 'servername' );
                $wgServer = 'https://localhost/';
                $this->assertMagic( 'localhost', 'servername' );
-               $wgServer = '//localhost/';  # bug 31176
+               $wgServer = '//localhost/'; # bug 31176
                $this->assertMagic( 'localhost', 'servername' );
 
                $wgServer = $saved_wgServer;
@@ -163,8 +171,11 @@ class MagicVariableTest extends MediaWikiTestCase {
        private function assertMagicPadding( $magic, $value, $format ) {
                # Initialize parser timestamp as year 2010 at 12h34 56s.
                # month and day are given by the caller ($value). Month < 12!
-               if( $value > 12 ) { $month = $value % 12; }
-               else { $month = $value; }
+               if ( $value > 12 ) {
+                       $month = $value % 12;
+               } else {
+                       $month = $value;
+               }
 
                $this->setParserTS(
                        sprintf( '2010%02d%02d123456', $month, $value )
@@ -188,7 +199,7 @@ class MagicVariableTest extends MediaWikiTestCase {
         * Assertion helper to test a magic variable output
         */
        private function assertMagic( $expected, $magic ) {
-               if( in_array( $magic, $this->expectedAsInteger ) ) {
+               if ( in_array( $magic, $this->expectedAsInteger ) ) {
                        $expected = (int)$expected;
                }
 
index 013b02c..067a7c4 100644 (file)
@@ -3,9 +3,9 @@ require_once( __DIR__ . '/NewParserTest.php' );
 
 /**
  * The UnitTest must be either a class that inherits from MediaWikiTestCase
- * or a class that provides a public static suite() method which returns 
+ * or a class that provides a public static suite() method which returns
  * an PHPUnit_Framework_Test object
- * 
+ *
  * @group Parser
  * @group Database
  */
index 3e3b141..5c7597e 100644 (file)
@@ -8,7 +8,7 @@
  * @group Stub
  */
 class NewParserTest extends MediaWikiTestCase {
-       static protected $articles = array();   // Array of test articles defined by the tests
+       static protected $articles = array(); // Array of test articles defined by the tests
        /* The data provider is run on a different instance than the test, so it must be static
         * When running tests from several files, all tests will see all articles.
         */
@@ -60,12 +60,12 @@ class NewParserTest extends MediaWikiTestCase {
                $tmpGlobals['wgStylePath'] = '/skins';
                $tmpGlobals['wgThumbnailScriptPath'] = false;
                $tmpGlobals['wgLocalFileRepo'] = array(
-                       'class'           => 'LocalRepo',
-                       'name'            => 'local',
-                       'url'             => 'http://example.com/images',
-                       'hashLevels'      => 2,
+                       'class' => 'LocalRepo',
+                       'name' => 'local',
+                       'url' => 'http://example.com/images',
+                       'hashLevels' => 2,
                        'transformVia404' => false,
-                       'backend'         => 'local-backend'
+                       'backend' => 'local-backend'
                );
                $tmpGlobals['wgForeignFileRepos'] = array();
                $tmpGlobals['wgEnableParserCache'] = false;
@@ -132,44 +132,43 @@ class NewParserTest extends MediaWikiTestCase {
                # Hack: insert a few Wikipedia in-project interwiki prefixes,
                # for testing inter-language links
                $this->db->insert( 'interwiki', array(
-                       array( 'iw_prefix' => 'wikipedia',
-                                  'iw_url'    => 'http://en.wikipedia.org/wiki/$1',
-                                  'iw_api'    => '',
-                                  'iw_wikiid' => '',
-                                  'iw_local'  => 0 ),
-                       array( 'iw_prefix' => 'meatball',
-                                  'iw_url'    => 'http://www.usemod.com/cgi-bin/mb.pl?$1',
-                                  'iw_api'    => '',
-                                  'iw_wikiid' => '',
-                                  'iw_local'  => 0 ),
-                       array( 'iw_prefix' => 'zh',
-                                  'iw_url'    => 'http://zh.wikipedia.org/wiki/$1',
-                                  'iw_api'    => '',
-                                  'iw_wikiid' => '',
-                                  'iw_local'  => 1 ),
-                       array( 'iw_prefix' => 'es',
-                                  'iw_url'    => 'http://es.wikipedia.org/wiki/$1',
-                                  'iw_api'    => '',
-                                  'iw_wikiid' => '',
-                                  'iw_local'  => 1 ),
-                       array( 'iw_prefix' => 'fr',
-                                  'iw_url'    => 'http://fr.wikipedia.org/wiki/$1',
-                                  'iw_api'    => '',
-                                  'iw_wikiid' => '',
-                                  'iw_local'  => 1 ),
-                       array( 'iw_prefix' => 'ru',
-                                  'iw_url'    => 'http://ru.wikipedia.org/wiki/$1',
-                                  'iw_api'    => '',
-                                  'iw_wikiid' => '',
-                                  'iw_local'  => 1 ),
-                       /**
-                        * @todo Fixme! Why are we inserting duplicate data here? Shouldn't
-                        * need this IGNORE or shouldn't need the insert at all.
-                        */
+                               array( 'iw_prefix' => 'wikipedia',
+                                       'iw_url' => 'http://en.wikipedia.org/wiki/$1',
+                                       'iw_api' => '',
+                                       'iw_wikiid' => '',
+                                       'iw_local' => 0 ),
+                               array( 'iw_prefix' => 'meatball',
+                                       'iw_url' => 'http://www.usemod.com/cgi-bin/mb.pl?$1',
+                                       'iw_api' => '',
+                                       'iw_wikiid' => '',
+                                       'iw_local' => 0 ),
+                               array( 'iw_prefix' => 'zh',
+                                       'iw_url' => 'http://zh.wikipedia.org/wiki/$1',
+                                       'iw_api' => '',
+                                       'iw_wikiid' => '',
+                                       'iw_local' => 1 ),
+                               array( 'iw_prefix' => 'es',
+                                       'iw_url' => 'http://es.wikipedia.org/wiki/$1',
+                                       'iw_api' => '',
+                                       'iw_wikiid' => '',
+                                       'iw_local' => 1 ),
+                               array( 'iw_prefix' => 'fr',
+                                       'iw_url' => 'http://fr.wikipedia.org/wiki/$1',
+                                       'iw_api' => '',
+                                       'iw_wikiid' => '',
+                                       'iw_local' => 1 ),
+                               array( 'iw_prefix' => 'ru',
+                                       'iw_url' => 'http://ru.wikipedia.org/wiki/$1',
+                                       'iw_api' => '',
+                                       'iw_wikiid' => '',
+                                       'iw_local' => 1 ),
+                               /**
+                                * @todo Fixme! Why are we inserting duplicate data here? Shouldn't
+                                * need this IGNORE or shouldn't need the insert at all.
+                                */
                        ), __METHOD__, array( 'IGNORE' )
                );
 
-
                # Update certain things in site_stats
                $this->db->insert( 'site_stats',
                        array( 'ss_row_id' => 1, 'ss_images' => 2, 'ss_good_articles' => 1 ),
@@ -196,15 +195,15 @@ class NewParserTest extends MediaWikiTestCase {
                                'Upload of some lame file',
                                'Some lame file',
                                array(
-                                       'size'        => 12345,
-                                       'width'       => 1941,
-                                       'height'      => 220,
-                                       'bits'        => 24,
-                                       'media_type'  => MEDIATYPE_BITMAP,
-                                       'mime'        => 'image/jpeg',
-                                       'metadata'    => serialize( array() ),
-                                       'sha1'        => wfBaseConvert( '', 16, 36, 31 ),
-                                       'fileExists'  => true ),
+                                       'size' => 12345,
+                                       'width' => 1941,
+                                       'height' => 220,
+                                       'bits' => 24,
+                                       'media_type' => MEDIATYPE_BITMAP,
+                                       'mime' => 'image/jpeg',
+                                       'metadata' => serialize( array() ),
+                                       'sha1' => wfBaseConvert( '', 16, 36, 31 ),
+                                       'fileExists' => true ),
                                $this->db->timestamp( '20010115123500' ), $user
                        );
                }
@@ -217,23 +216,20 @@ class NewParserTest extends MediaWikiTestCase {
                                'zomgnotcensored',
                                'Borderline image',
                                array(
-                                       'size'        => 12345,
-                                       'width'       => 320,
-                                       'height'      => 240,
-                                       'bits'        => 24,
-                                       'media_type'  => MEDIATYPE_BITMAP,
-                                       'mime'        => 'image/jpeg',
-                                       'metadata'    => serialize( array() ),
-                                       'sha1'        => wfBaseConvert( '', 16, 36, 31 ),
-                                       'fileExists'  => true ),
+                                       'size' => 12345,
+                                       'width' => 320,
+                                       'height' => 240,
+                                       'bits' => 24,
+                                       'media_type' => MEDIATYPE_BITMAP,
+                                       'mime' => 'image/jpeg',
+                                       'metadata' => serialize( array() ),
+                                       'sha1' => wfBaseConvert( '', 16, 36, 31 ),
+                                       'fileExists' => true ),
                                $this->db->timestamp( '20010115123500' ), $user
                        );
                }
        }
 
-
-
-
        //ParserTest setup/teardown functions
 
        /**
@@ -271,11 +267,11 @@ class NewParserTest extends MediaWikiTestCase {
                        }
                } else {
                        $backend = new FSFileBackend( array(
-                               'name'        => 'local-backend',
+                               'name' => 'local-backend',
                                'lockManager' => 'nullLockManager',
                                'containerPaths' => array(
                                        'local-public' => "$uploadDir",
-                                       'local-thumb'  => "$uploadDir/thumb",
+                                       'local-thumb' => "$uploadDir/thumb",
                                )
                        ) );
                }
@@ -288,12 +284,12 @@ class NewParserTest extends MediaWikiTestCase {
                        'wgExtensionAssetsPath' => '/extensions',
                        'wgActionPaths' => array(),
                        'wgLocalFileRepo' => array(
-                               'class'           => 'LocalRepo',
-                               'name'            => 'local',
-                               'url'             => 'http://example.com/images',
-                               'hashLevels'      => 2,
+                               'class' => 'LocalRepo',
+                               'name' => 'local',
+                               'url' => 'http://example.com/images',
+                               'hashLevels' => 2,
                                'transformVia404' => false,
-                               'backend'         => $backend
+                               'backend' => $backend
                        ),
                        'wgEnableUploads' => self::getOptionValue( 'wgEnableUploads', $opts, true ),
                        'wgStylePath' => '/skins',
@@ -320,10 +316,10 @@ class NewParserTest extends MediaWikiTestCase {
                        'wgVariantArticlePath' => false,
                        'wgGroupPermissions' => array( '*' => array(
                                'createaccount' => true,
-                               'read'          => true,
-                               'edit'          => true,
-                               'createpage'    => true,
-                               'createtalk'    => true,
+                               'read' => true,
+                               'edit' => true,
+                               'createpage' => true,
+                               'createtalk' => true,
                        ) ),
                        'wgNamespaceProtection' => array( NS_MEDIAWIKI => 'editinterface' ),
                        'wgDefaultExternalStore' => array(),
@@ -466,7 +462,7 @@ class NewParserTest extends MediaWikiTestCase {
                $base = $this->getBaseDir();
                // delete the files first, then the dirs.
                self::deleteFiles(
-                       array (
+                       array(
                                "$base/local-public/3/3a/Foobar.jpg",
                                "$base/local-thumb/3/3a/Foobar.jpg/180px-Foobar.jpg",
                                "$base/local-thumb/3/3a/Foobar.jpg/200px-Foobar.jpg",
@@ -545,7 +541,7 @@ class NewParserTest extends MediaWikiTestCase {
                        // @todo: When setting up pages, force the content model. Only skip if
                        //        $wgtContentModelUseDB is false.
                        $this->markTestSkipped( "Main namespace does not support wikitext,"
-                                       . "skipping parser test: $desc" );
+                               . "skipping parser test: $desc" );
                }
 
                wfDebug( "Running parser test: $desc\n" );
@@ -558,8 +554,7 @@ class NewParserTest extends MediaWikiTestCase {
 
                if ( isset( $opts['title'] ) ) {
                        $titleText = $opts['title'];
-               }
-               else {
+               } else {
                        $titleText = 'Parser test';
                }
 
@@ -632,7 +627,7 @@ class NewParserTest extends MediaWikiTestCase {
 
                $files = $wgParserTestFiles;
 
-               if( $this->getCliArg( 'file=' ) ) {
+               if ( $this->getCliArg( 'file=' ) ) {
                        $files = array( $this->getCliArg( 'file=' ) );
                }
 
@@ -794,15 +789,16 @@ class NewParserTest extends MediaWikiTestCase {
         */
        public function requireHook( $name ) {
                global $wgParser;
-               $wgParser->firstCallInit( ); // make sure hooks are loaded.
+               $wgParser->firstCallInit(); // make sure hooks are loaded.
                return isset( $wgParser->mTagHooks[$name] );
        }
 
        public function requireFunctionHook( $name ) {
                global $wgParser;
-               $wgParser->firstCallInit( ); // make sure hooks are loaded.
+               $wgParser->firstCallInit(); // make sure hooks are loaded.
                return isset( $wgParser->mFunctionHooks[$name] );
        }
+
        //Various "cleanup" functions
 
        /**
@@ -828,8 +824,7 @@ class NewParserTest extends MediaWikiTestCase {
        public function removeEndingNewline( $s ) {
                if ( substr( $s, -1 ) === "\n" ) {
                        return substr( $s, 0, -1 );
-               }
-               else {
+               } else {
                        return $s;
                }
        }
index f3a12d0..5c1a268 100644 (file)
@@ -5,10 +5,10 @@ class ParserMethodsTest extends MediaWikiLangTestCase {
        public static function providePreSaveTransform() {
                return array(
                        array( 'hello this is ~~~',
-                              "hello this is [[Special:Contributions/127.0.0.1|127.0.0.1]]",
+                               "hello this is [[Special:Contributions/127.0.0.1|127.0.0.1]]",
                        ),
                        array( 'hello \'\'this\'\' is <nowiki>~~~</nowiki>',
-                              'hello \'\'this\'\' is <nowiki>~~~</nowiki>',
+                               'hello \'\'this\'\' is <nowiki>~~~</nowiki>',
                        ),
                );
        }
index 8c22c59..e16b407 100644 (file)
@@ -57,7 +57,7 @@ class ParserPreloadTest extends MediaWikiTestCase {
                );
        }
 
-       function assertPreloaded( $expected, $text, $msg='') {
+       function assertPreloaded( $expected, $text, $msg = '' ) {
                $this->assertEquals(
                        $expected,
                        $this->testParser->getPreloadText(
index c3a251f..c51a1dc 100644 (file)
@@ -52,16 +52,16 @@ class PreprocessorTest extends MediaWikiTestCase {
                        array( "Foo\n=\n==\n=\n", "<root>Foo\n=\n==\n=\n</root>" ),
                        array( "{{Foo}}", "<root><template><title>Foo</title></template></root>" ),
                        array( "\n{{Foo}}", "<root>\n<template lineStart=\"1\"><title>Foo</title></template></root>" ),
-                       array( "{{Foo|bar}}", "<root><template><title>Foo</title><part><name index=\"1\" /><value>bar</value></part></template></root>" ),  
-                       array( "{{Foo|bar}}a", "<root><template><title>Foo</title><part><name index=\"1\" /><value>bar</value></part></template>a</root>" ),  
-                       array( "{{Foo|bar|baz}}", "<root><template><title>Foo</title><part><name index=\"1\" /><value>bar</value></part><part><name index=\"2\" /><value>baz</value></part></template></root>" ),  
+                       array( "{{Foo|bar}}", "<root><template><title>Foo</title><part><name index=\"1\" /><value>bar</value></part></template></root>" ),
+                       array( "{{Foo|bar}}a", "<root><template><title>Foo</title><part><name index=\"1\" /><value>bar</value></part></template>a</root>" ),
+                       array( "{{Foo|bar|baz}}", "<root><template><title>Foo</title><part><name index=\"1\" /><value>bar</value></part><part><name index=\"2\" /><value>baz</value></part></template></root>" ),
                        array( "{{Foo|1=bar}}", "<root><template><title>Foo</title><part><name>1</name>=<value>bar</value></part></template></root>" ),
                        array( "{{Foo|=bar}}", "<root><template><title>Foo</title><part><name></name>=<value>bar</value></part></template></root>" ),
-                       array( "{{Foo|bar=baz}}", "<root><template><title>Foo</title><part><name>bar</name>=<value>baz</value></part></template></root>" ), 
+                       array( "{{Foo|bar=baz}}", "<root><template><title>Foo</title><part><name>bar</name>=<value>baz</value></part></template></root>" ),
                        array( "{{Foo|{{bar}}=baz}}", "<root><template><title>Foo</title><part><name><template><title>bar</title></template></name>=<value>baz</value></part></template></root>" ),
-                       array( "{{Foo|1=bar|baz}}", "<root><template><title>Foo</title><part><name>1</name>=<value>bar</value></part><part><name index=\"1\" /><value>baz</value></part></template></root>" ), 
+                       array( "{{Foo|1=bar|baz}}", "<root><template><title>Foo</title><part><name>1</name>=<value>bar</value></part><part><name index=\"1\" /><value>baz</value></part></template></root>" ),
                        array( "{{Foo|1=bar|2=baz}}", "<root><template><title>Foo</title><part><name>1</name>=<value>bar</value></part><part><name>2</name>=<value>baz</value></part></template></root>" ),
-                       array( "{{Foo|bar|foo=baz}}", "<root><template><title>Foo</title><part><name index=\"1\" /><value>bar</value></part><part><name>foo</name>=<value>baz</value></part></template></root>" ), 
+                       array( "{{Foo|bar|foo=baz}}", "<root><template><title>Foo</title><part><name index=\"1\" /><value>bar</value></part><part><name>foo</name>=<value>baz</value></part></template></root>" ),
                        array( "{{{1}}}", "<root><tplarg><title>1</title></tplarg></root>" ),
                        array( "{{{1|}}}", "<root><tplarg><title>1</title><part><name index=\"1\" /><value></value></part></tplarg></root>" ),
                        array( "{{{Foo}}}", "<root><tplarg><title>Foo</title></tplarg></root>" ),
@@ -84,26 +84,26 @@ class PreprocessorTest extends MediaWikiTestCase {
                        array( "Foo <gallery bar=\"baz\" />", "<root>Foo <ext><name>gallery</name><attr> bar=&quot;baz&quot; </attr></ext></root>" ),
                        array( "Foo <gallery bar=\"1\" baz=2 />", "<root>Foo <ext><name>gallery</name><attr> bar=&quot;1&quot; baz=2 </attr></ext></root>" ),
                        array( "</foo>Foo<//foo>", "<root><ext><name>/foo</name><attr></attr><inner>Foo</inner><close>&lt;//foo&gt;</close></ext></root>" ), # Worth blacklisting IMHO
-                       array( "{{#ifexpr: ({{{1|1}}} = 2) | Foo | Bar }}", "<root><template><title>#ifexpr: (<tplarg><title>1</title><part><name index=\"1\" /><value>1</value></part></tplarg> = 2) </title><part><name index=\"1\" /><value> Foo </value></part><part><name index=\"2\" /><value> Bar </value></part></template></root>"),
-                       array( "{{#if: {{{1|}}} | Foo | {{Bar}} }}", "<root><template><title>#if: <tplarg><title>1</title><part><name index=\"1\" /><value></value></part></tplarg> </title><part><name index=\"1\" /><value> Foo </value></part><part><name index=\"2\" /><value> <template><title>Bar</title></template> </value></part></template></root>"),
-                       array( "{{#if: {{{1|}}} | Foo | [[Bar]] }}", "<root><template><title>#if: <tplarg><title>1</title><part><name index=\"1\" /><value></value></part></tplarg> </title><part><name index=\"1\" /><value> Foo </value></part><part><name index=\"2\" /><value> [[Bar]] </value></part></template></root>"),
-                       array( "{{#if: {{{1|}}} | [[Foo]] | Bar }}", "<root><template><title>#if: <tplarg><title>1</title><part><name index=\"1\" /><value></value></part></tplarg> </title><part><name index=\"1\" /><value> [[Foo]] </value></part><part><name index=\"2\" /><value> Bar </value></part></template></root>"),
-                       array( "{{#if: {{{1|}}} | 1 | {{#if: {{{1|}}} | 2 | 3 }} }}", "<root><template><title>#if: <tplarg><title>1</title><part><name index=\"1\" /><value></value></part></tplarg> </title><part><name index=\"1\" /><value> 1 </value></part><part><name index=\"2\" /><value> <template><title>#if: <tplarg><title>1</title><part><name index=\"1\" /><value></value></part></tplarg> </title><part><name index=\"1\" /><value> 2 </value></part><part><name index=\"2\" /><value> 3 </value></part></template> </value></part></template></root>"),
-                       array( "{{ {{Foo}}", "<root>{{ <template><title>Foo</title></template></root>"),
-                       array( "{{Foobar {{Foo}} {{Bar}} {{Baz}} ", "<root>{{Foobar <template><title>Foo</title></template> <template><title>Bar</title></template> <template><title>Baz</title></template> </root>"),
-                       array( "[[Foo]] |", "<root>[[Foo]] |</root>"),
-                       array( "{{Foo|Bar|", "<root>{{Foo|Bar|</root>"),
-                       array( "[[Foo]", "<root>[[Foo]</root>"),
-                       array( "[[Foo|Bar]", "<root>[[Foo|Bar]</root>"),
-                       array( "{{Foo| [[Bar] }}", "<root>{{Foo| [[Bar] }}</root>"),
-                       array( "{{Foo| [[Bar|Baz] }}", "<root>{{Foo| [[Bar|Baz] }}</root>"),
-                       array( "{{Foo|bar=[[baz]}}", "<root>{{Foo|bar=[[baz]}}</root>"),
-                       array( "{{foo|", "<root>{{foo|</root>"),
-                       array( "{{foo|}", "<root>{{foo|}</root>"),
-                       array( "{{foo|} }}", "<root><template><title>foo</title><part><name index=\"1\" /><value>} </value></part></template></root>"),
-                       array( "{{foo|bar=|}", "<root>{{foo|bar=|}</root>"),
-                       array( "{{Foo|} Bar=", "<root>{{Foo|} Bar=</root>"),
-                       array( "{{Foo|} Bar=}}", "<root><template><title>Foo</title><part><name>} Bar</name>=<value></value></part></template></root>"),
+                       array( "{{#ifexpr: ({{{1|1}}} = 2) | Foo | Bar }}", "<root><template><title>#ifexpr: (<tplarg><title>1</title><part><name index=\"1\" /><value>1</value></part></tplarg> = 2) </title><part><name index=\"1\" /><value> Foo </value></part><part><name index=\"2\" /><value> Bar </value></part></template></root>" ),
+                       array( "{{#if: {{{1|}}} | Foo | {{Bar}} }}", "<root><template><title>#if: <tplarg><title>1</title><part><name index=\"1\" /><value></value></part></tplarg> </title><part><name index=\"1\" /><value> Foo </value></part><part><name index=\"2\" /><value> <template><title>Bar</title></template> </value></part></template></root>" ),
+                       array( "{{#if: {{{1|}}} | Foo | [[Bar]] }}", "<root><template><title>#if: <tplarg><title>1</title><part><name index=\"1\" /><value></value></part></tplarg> </title><part><name index=\"1\" /><value> Foo </value></part><part><name index=\"2\" /><value> [[Bar]] </value></part></template></root>" ),
+                       array( "{{#if: {{{1|}}} | [[Foo]] | Bar }}", "<root><template><title>#if: <tplarg><title>1</title><part><name index=\"1\" /><value></value></part></tplarg> </title><part><name index=\"1\" /><value> [[Foo]] </value></part><part><name index=\"2\" /><value> Bar </value></part></template></root>" ),
+                       array( "{{#if: {{{1|}}} | 1 | {{#if: {{{1|}}} | 2 | 3 }} }}", "<root><template><title>#if: <tplarg><title>1</title><part><name index=\"1\" /><value></value></part></tplarg> </title><part><name index=\"1\" /><value> 1 </value></part><part><name index=\"2\" /><value> <template><title>#if: <tplarg><title>1</title><part><name index=\"1\" /><value></value></part></tplarg> </title><part><name index=\"1\" /><value> 2 </value></part><part><name index=\"2\" /><value> 3 </value></part></template> </value></part></template></root>" ),
+                       array( "{{ {{Foo}}", "<root>{{ <template><title>Foo</title></template></root>" ),
+                       array( "{{Foobar {{Foo}} {{Bar}} {{Baz}} ", "<root>{{Foobar <template><title>Foo</title></template> <template><title>Bar</title></template> <template><title>Baz</title></template> </root>" ),
+                       array( "[[Foo]] |", "<root>[[Foo]] |</root>" ),
+                       array( "{{Foo|Bar|", "<root>{{Foo|Bar|</root>" ),
+                       array( "[[Foo]", "<root>[[Foo]</root>" ),
+                       array( "[[Foo|Bar]", "<root>[[Foo|Bar]</root>" ),
+                       array( "{{Foo| [[Bar] }}", "<root>{{Foo| [[Bar] }}</root>" ),
+                       array( "{{Foo| [[Bar|Baz] }}", "<root>{{Foo| [[Bar|Baz] }}</root>" ),
+                       array( "{{Foo|bar=[[baz]}}", "<root>{{Foo|bar=[[baz]}}</root>" ),
+                       array( "{{foo|", "<root>{{foo|</root>" ),
+                       array( "{{foo|}", "<root>{{foo|}</root>" ),
+                       array( "{{foo|} }}", "<root><template><title>foo</title><part><name index=\"1\" /><value>} </value></part></template></root>" ),
+                       array( "{{foo|bar=|}", "<root>{{foo|bar=|}</root>" ),
+                       array( "{{Foo|} Bar=", "<root>{{Foo|} Bar=</root>" ),
+                       array( "{{Foo|} Bar=}}", "<root><template><title>Foo</title><part><name>} Bar</name>=<value></value></part></template></root>" ),
                        /* array( file_get_contents( __DIR__ . '/QuoteQuran.txt' ), file_get_contents( __DIR__ . '/QuoteQuranExpanded.txt' ) ), */
                );
        }
@@ -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
                );
        }
 
@@ -180,7 +181,7 @@ class PreprocessorTest extends MediaWikiTestCase {
         * Tests from Bug 28642 · https://bugzilla.wikimedia.org/28642
         */
        function provideHeadings() {
-               return array(   /* These should become headings: */
+               return array( /* These should become headings: */
                        array( "== h ==<!--c1-->", "<root><h level=\"2\" i=\"1\">== h ==<comment>&lt;!--c1--&gt;</comment></h></root>" ),
                        array( "== h ==         <!--c1-->", "<root><h level=\"2\" i=\"1\">== h ==       <comment>&lt;!--c1--&gt;</comment></h></root>" ),
                        array( "== h ==<!--c1-->        ", "<root><h level=\"2\" i=\"1\">== h ==<comment>&lt;!--c1--&gt;</comment>      </h></root>" ),
index 292f13a..ed60079 100644 (file)
@@ -4,13 +4,12 @@
  * @group Parser
  */
 class TagHookTest extends MediaWikiTestCase {
-       
        public static function provideValidNames() {
                return array( array( 'foo' ), array( 'foo-bar' ), array( 'foo_bar' ), array( 'FOO-BAR' ), array( 'foo bar' ) );
        }
 
        public static function provideBadNames() {
-               return array( array( "foo<bar" ), array( "foo>bar" ), array( "foo\nbar" ),  array( "foo\rbar" ) );
+               return array( array( "foo<bar" ), array( "foo>bar" ), array( "foo\nbar" ), array( "foo\rbar" ) );
        }
 
        protected function setUp() {
@@ -25,14 +24,14 @@ class TagHookTest extends MediaWikiTestCase {
        function testTagHooks( $tag ) {
                global $wgParserConf, $wgContLang;
                $parser = new Parser( $wgParserConf );
-               
+
                $parser->setHook( $tag, array( $this, 'tagCallback' ) );
                $parserOutput = $parser->parse( "Foo<$tag>Bar</$tag>Baz", Title::newFromText( 'Test' ), ParserOptions::newFromUserAndLang( new User, $wgContLang ) );
                $this->assertEquals( "<p>FooOneBaz\n</p>", $parserOutput->getText() );
-               
+
                $parser->mPreprocessor = null; # Break the Parser <-> Preprocessor cycle
        }
-       
+
        /**
         * @dataProvider provideBadNames
         * @expectedException MWException
@@ -40,26 +39,26 @@ class TagHookTest extends MediaWikiTestCase {
        function testBadTagHooks( $tag ) {
                global $wgParserConf, $wgContLang;
                $parser = new Parser( $wgParserConf );
-               
+
                $parser->setHook( $tag, array( $this, 'tagCallback' ) );
                $parser->parse( "Foo<$tag>Bar</$tag>Baz", Title::newFromText( 'Test' ), ParserOptions::newFromUserAndLang( new User, $wgContLang ) );
-               $this->fail('Exception not thrown.');
+               $this->fail( 'Exception not thrown.' );
        }
-       
+
        /**
         * @dataProvider provideValidNames
         */
        function testFunctionTagHooks( $tag ) {
                global $wgParserConf, $wgContLang;
                $parser = new Parser( $wgParserConf );
-               
+
                $parser->setFunctionTagHook( $tag, array( $this, 'functionTagCallback' ), 0 );
                $parserOutput = $parser->parse( "Foo<$tag>Bar</$tag>Baz", Title::newFromText( 'Test' ), ParserOptions::newFromUserAndLang( new User, $wgContLang ) );
                $this->assertEquals( "<p>FooOneBaz\n</p>", $parserOutput->getText() );
-               
+
                $parser->mPreprocessor = null; # Break the Parser <-> Preprocessor cycle
        }
-       
+
        /**
         * @dataProvider provideBadNames
         * @expectedException MWException
@@ -67,16 +66,16 @@ class TagHookTest extends MediaWikiTestCase {
        function testBadFunctionTagHooks( $tag ) {
                global $wgParserConf, $wgContLang;
                $parser = new Parser( $wgParserConf );
-               
+
                $parser->setFunctionTagHook( $tag, array( $this, 'functionTagCallback' ), SFH_OBJECT_ARGS );
                $parser->parse( "Foo<$tag>Bar</$tag>Baz", Title::newFromText( 'Test' ), ParserOptions::newFromUserAndLang( new User, $wgContLang ) );
-               $this->fail('Exception not thrown.');
+               $this->fail( 'Exception not thrown.' );
        }
-       
+
        function tagCallback( $text, $params, $parser ) {
                return str_rot13( $text );
        }
-       
+
        function functionTagCallback( &$parser, $frame, $code, $attribs ) {
                return str_rot13( $code );
        }
index 7339fb8..6abca6d 100644 (file)
@@ -18,10 +18,10 @@ class SearchEngineTest extends MediaWikiLangTestCase {
                # Get database type and version
                $dbType = $this->db->getType();
                $dbSupported =
-                       ($dbType === 'mysql')
-                       || ( $dbType === 'sqlite' && $this->db->getFulltextSearchModule() == 'FTS3' );
+                       ( $dbType === 'mysql' )
+                               || ( $dbType === 'sqlite' && $this->db->getFulltextSearchModule() == 'FTS3' );
 
-               if( !$dbSupported ) {
+               if ( !$dbSupported ) {
                        $this->markTestSkipped( "MySQL or SQLite with FTS3 only" );
                }
 
@@ -49,29 +49,29 @@ class SearchEngineTest extends MediaWikiLangTestCase {
                        return;
                }
 
-               $this->insertPage( "Not_Main_Page",     "This is not a main page", 0 );
-               $this->insertPage( 'Talk:Not_Main_Page',        'This is not a talk page to the main page, see [[smithee]]', 1 );
-               $this->insertPage( 'Smithee',   'A smithee is one who smiths. See also [[Alan Smithee]]', 0 );
-               $this->insertPage( 'Talk:Smithee',      'This article sucks.', 1 );
-               $this->insertPage( 'Unrelated_page',    'Nothing in this page is about the S word.', 0 );
-               $this->insertPage( 'Another_page',      'This page also is unrelated.', 0 );
-               $this->insertPage( 'Help:Help',         'Help me!', 4 );
-               $this->insertPage( 'Thppt',             'Blah blah', 0 );
-               $this->insertPage( 'Alan_Smithee',      'yum', 0 );
-               $this->insertPage( 'Pages',             'are\'food', 0 );
-               $this->insertPage( 'HalfOneUp', 'AZ', 0 );
-               $this->insertPage( 'FullOneUp', 'AZ', 0 );
-               $this->insertPage( 'HalfTwoLow',        'az', 0 );
-               $this->insertPage( 'FullTwoLow',        'az', 0 );
-               $this->insertPage( 'HalfNumbers',       '1234567890', 0 );
-               $this->insertPage( 'FullNumbers',       '1234567890', 0 );
-               $this->insertPage( 'DomainName',        'example.com', 0 );
+               $this->insertPage( "Not_Main_Page", "This is not a main page", 0 );
+               $this->insertPage( 'Talk:Not_Main_Page', 'This is not a talk page to the main page, see [[smithee]]', 1 );
+               $this->insertPage( 'Smithee', 'A smithee is one who smiths. See also [[Alan Smithee]]', 0 );
+               $this->insertPage( 'Talk:Smithee', 'This article sucks.', 1 );
+               $this->insertPage( 'Unrelated_page', 'Nothing in this page is about the S word.', 0 );
+               $this->insertPage( 'Another_page', 'This page also is unrelated.', 0 );
+               $this->insertPage( 'Help:Help', 'Help me!', 4 );
+               $this->insertPage( 'Thppt', 'Blah blah', 0 );
+               $this->insertPage( 'Alan_Smithee', 'yum', 0 );
+               $this->insertPage( 'Pages', 'are\'food', 0 );
+               $this->insertPage( 'HalfOneUp', 'AZ', 0 );
+               $this->insertPage( 'FullOneUp', 'AZ', 0 );
+               $this->insertPage( 'HalfTwoLow', 'az', 0 );
+               $this->insertPage( 'FullTwoLow', 'az', 0 );
+               $this->insertPage( 'HalfNumbers', '1234567890', 0 );
+               $this->insertPage( 'FullNumbers', '1234567890', 0 );
+               $this->insertPage( 'DomainName', 'example.com', 0 );
        }
 
        function fetchIds( $results ) {
                if ( !$this->isWikitextNS( NS_MAIN ) ) {
                        $this->markTestIncomplete( __CLASS__ . " does no yet support non-wikitext content "
-                               . "in the main namespace");
+                               . "in the main namespace" );
                }
 
                $this->assertTrue( is_object( $results ) );
@@ -135,9 +135,9 @@ class SearchEngineTest extends MediaWikiLangTestCase {
 
        function testTextSearch() {
                $this->assertEquals(
-                               array( 'Smithee' ),
-                               $this->fetchIds( $this->search->searchText( 'smithee' ) ),
-                               "Plain search failed" );
+                       array( 'Smithee' ),
+                       $this->fetchIds( $this->search->searchText( 'smithee' ) ),
+                       "Plain search failed" );
        }
 
        function testTextPowerSearch() {
index 0307d4d..c329839 100644 (file)
@@ -80,8 +80,7 @@ class SiteListTest extends MediaWikiTestCase {
        public function testGetSiteByGlobalId( SiteList $sites ) {
                if ( $sites->isEmpty() ) {
                        $this->assertTrue( true );
-               }
-               else {
+               } else {
                        /**
                         * @var Site $site
                         */
index c11165b..d20e2a5 100644 (file)
@@ -244,8 +244,7 @@ class SiteTest extends MediaWikiTestCase {
        protected function assertTypeOrFalse( $type, $value ) {
                if ( $value === false ) {
                        $this->assertTrue( true );
-               }
-               else {
+               } else {
                        $this->assertInternalType( $type, $value );
                }
        }
index a33c7b6..3b82e07 100644 (file)
@@ -39,9 +39,9 @@ class QueryAllSpecialPagesTest extends MediaWikiTestCase {
                parent::__construct();
 
                global $wgQueryPages;
-               foreach( $wgQueryPages as $page ) {
+               foreach ( $wgQueryPages as $page ) {
                        $class = $page[0];
-                       if( ! in_array( $class, $this->manualTest ) ) {
+                       if ( !in_array( $class, $this->manualTest ) ) {
                                $this->queryPages[$class] = new $class;
                        }
                }
@@ -54,22 +54,22 @@ class QueryAllSpecialPagesTest extends MediaWikiTestCase {
        function testQuerypageSqlQuery() {
                global $wgDBtype;
 
-               foreach( $this->queryPages as $page ) {
+               foreach ( $this->queryPages as $page ) {
 
                        // With MySQL, skips special pages reopening a temporary table
                        // See http://bugs.mysql.com/bug.php?id=10327
-                       if(
+                       if (
                                $wgDBtype === 'mysql'
                                && in_array( $page->getName(), $this->reopensTempTable )
                        ) {
-                                       $this->markTestSkipped( "SQL query for page {$page->getName()} can not be tested on MySQL backend (it reopens a temporary table)" );
-                                       continue;
-                               }
+                               $this->markTestSkipped( "SQL query for page {$page->getName()} can not be tested on MySQL backend (it reopens a temporary table)" );
+                               continue;
+                       }
 
-                       $msg = "SQL query for page {$page->getName()} should give a result wrapper object" ;
+                       $msg = "SQL query for page {$page->getName()} should give a result wrapper object";
 
                        $result = $page->reallyDoQuery( 50 );
-                       if( $result instanceof ResultWrapper ) {
+                       if ( $result instanceof ResultWrapper ) {
                                $this->assertTrue( true, $msg );
                        } else {
                                $this->assertFalse( false, $msg );
index 11492a1..add830b 100644 (file)
@@ -41,7 +41,7 @@ class SpecialRecentchangesTest extends MediaWikiTestCase {
 
        /** return false if condition begin with 'rc_timestamp ' */
        private static function filterOutRcTimestampCondition( $var ) {
-               return (false === strpos( $var, 'rc_timestamp ' ));
+               return ( false === strpos( $var, 'rc_timestamp ' ) );
 
        }
 
@@ -70,7 +70,7 @@ class SpecialRecentchangesTest extends MediaWikiTestCase {
                                'namespace' => NS_MAIN,
                                'invert' => 1,
                        ),
-                 "rc conditions with namespace inverted"
+                       "rc conditions with namespace inverted"
                );
        }
 
@@ -89,7 +89,7 @@ class SpecialRecentchangesTest extends MediaWikiTestCase {
                                'namespace' => $ns1,
                                'associated' => 1,
                        ),
-                 "rc conditions with namespace inverted"
+                       "rc conditions with namespace inverted"
                );
        }
 
@@ -105,11 +105,11 @@ class SpecialRecentchangesTest extends MediaWikiTestCase {
                                1 => sprintf( "(rc_namespace != '%s' AND rc_namespace != '%s')", $ns1, $ns2 ),
                        ),
                        array(
-                               'namespace'  => $ns1,
+                               'namespace' => $ns1,
                                'associated' => 1,
-                               'invert'     => 1,
+                               'invert' => 1,
                        ),
-                 "rc conditions with namespace inverted"
+                       "rc conditions with namespace inverted"
                );
        }
 
@@ -119,8 +119,8 @@ class SpecialRecentchangesTest extends MediaWikiTestCase {
         */
        public static function provideNamespacesAssociations() {
                return array( # (NS => Associated_NS)
-                       array( NS_MAIN, NS_TALK),
-                       array( NS_TALK, NS_MAIN),
+                       array( NS_MAIN, NS_TALK ),
+                       array( NS_TALK, NS_MAIN ),
                );
        }
 
index f6652bc..f5ef0fb 100644 (file)
@@ -32,7 +32,7 @@ class SpecialSearchTest extends MediaWikiTestCase {
                        'ns6'=>true,
                ) ));
                 */
-               $context->setRequest( new FauxRequest( $requested ));
+               $context->setRequest( new FauxRequest( $requested ) );
                $search = new SpecialSearch();
                $search->setContext( $context );
                $search->load();
@@ -45,11 +45,11 @@ class SpecialSearchTest extends MediaWikiTestCase {
                $this->assertEquals(
                        array( /** Expected: */
                                'ProfileName' => $expectedProfile,
-                               'Namespaces'  => $expectedNS,
+                               'Namespaces' => $expectedNS,
                        )
                        , array( /** Actual: */
                                'ProfileName' => $search->getProfile(),
-                               'Namespaces'  => $search->getNamespaces(),
+                               'Namespaces' => $search->getNamespaces(),
                        )
                        , $message
                );
@@ -59,14 +59,14 @@ class SpecialSearchTest extends MediaWikiTestCase {
        function provideSearchOptionsTests() {
                $defaultNS = SearchEngine::defaultNamespaces();
                $EMPTY_REQUEST = array();
-               $NO_USER_PREF  = null;
+               $NO_USER_PREF = null;
 
                return array(
                        /**
                         * Parameters:
-                        *      <Web Request>, <User options>
+                        *     <Web Request>, <User options>
                         * Followed by expected values:
-                        *      <ProfileName>, <NSList>
+                        *     <ProfileName>, <NSList>
                         * Then an optional message.
                         */
                        array(
@@ -76,19 +76,19 @@ class SpecialSearchTest extends MediaWikiTestCase {
                        ),
                        array(
                                array( 'ns5' => 1 ), $NO_USER_PREF,
-                               'advanced', array(  5),
+                               'advanced', array( ),
                                'Web request with specific NS should override user preference'
                        ),
                        array(
                                $EMPTY_REQUEST, array(
-                                       'searchNs2' => 1,
-                                       'searchNs14' => 1,
-                               ) + array_fill_keys( array_map( function( $ns ) {
-                                       return "searchNs$ns";
-                               }, $defaultNS ), 0 ),
+                               'searchNs2' => 1,
+                               'searchNs14' => 1,
+                       ) + array_fill_keys( array_map( function ( $ns ) {
+                               return "searchNs$ns";
+                       }, $defaultNS ), 0 ),
                                'advanced', array( 2, 14 ),
                                'Bug 33583: search with no option should honor User search preferences'
-                               . ' and have all other namespace disabled'
+                                       . ' and have all other namespace disabled'
                        ),
                );
        }
@@ -98,11 +98,11 @@ class SpecialSearchTest extends MediaWikiTestCase {
         * User remains anonymous though
         */
        function newUserWithSearchNS( $opt = null ) {
-               $u = User::newFromId(0);
-               if( $opt === null ) {
+               $u = User::newFromId( 0 );
+               if ( $opt === null ) {
                        return $u;
                }
-               foreach($opt as $name => $value) {
+               foreach ( $opt as $name => $value ) {
                        $u->setOption( $name, $value );
                }
                return $u;
@@ -116,7 +116,7 @@ class SpecialSearchTest extends MediaWikiTestCase {
 
                # Initialize [[Special::Search]]
                $search = new SpecialSearch();
-               $search->getContext()->setTitle( Title::newFromText('Special:Search' ) );
+               $search->getContext()->setTitle( Title::newFromText( 'Special:Search' ) );
                $search->load();
 
                # Simulate a user searching for a given term
index a693cdb..4d2d8ce 100644 (file)
@@ -336,7 +336,7 @@ class UploadFromUrlTest extends ApiTestCase {
         */
        protected function deleteFile( $name ) {
                $t = Title::newFromText( $name, NS_FILE );
-               $this->assertTrue($t->exists(), "File '$name' exists");
+               $this->assertTrue( $t->exists(), "File '$name' exists" );
 
                if ( $t->exists() ) {
                        $file = wfFindFile( $name, array( 'ignoreRedirect' => true ) );
@@ -347,6 +347,6 @@ class UploadFromUrlTest extends ApiTestCase {
                }
                $t = Title::newFromText( $name, NS_FILE );
 
-               $this->assertFalse($t->exists(), "File '$name' was deleted");
+               $this->assertFalse( $t->exists(), "File '$name' was deleted" );
        }
- }
+}
index 857aef5..8fcaa21 100644 (file)
@@ -59,19 +59,19 @@ class UploadStashTest extends MediaWikiTestCase {
        }
 
        public function testValidRequest() {
-               $request = new FauxRequest( array( 'wpFileKey' => 'foo') );
-               $this->assertFalse( UploadFromStash::isValidRequest($request), 'Check failure on bad wpFileKey' );
+               $request = new FauxRequest( array( 'wpFileKey' => 'foo' ) );
+               $this->assertFalse( UploadFromStash::isValidRequest( $request ), 'Check failure on bad wpFileKey' );
 
-               $request = new FauxRequest( array( 'wpSessionKey' => 'foo') );
-               $this->assertFalse( UploadFromStash::isValidRequest($request), 'Check failure on bad wpSessionKey' );
+               $request = new FauxRequest( array( 'wpSessionKey' => 'foo' ) );
+               $this->assertFalse( UploadFromStash::isValidRequest( $request ), 'Check failure on bad wpSessionKey' );
 
-               $request = new FauxRequest( array( 'wpFileKey' => 'testkey-test.test') );
-               $this->assertTrue( UploadFromStash::isValidRequest($request), 'Check good wpFileKey' );
+               $request = new FauxRequest( array( 'wpFileKey' => 'testkey-test.test' ) );
+               $this->assertTrue( UploadFromStash::isValidRequest( $request ), 'Check good wpFileKey' );
 
-               $request = new FauxRequest( array( 'wpFileKey' => 'testkey-test.test') );
-               $this->assertTrue( UploadFromStash::isValidRequest($request), 'Check good wpSessionKey' );
+               $request = new FauxRequest( array( 'wpFileKey' => 'testkey-test.test' ) );
+               $this->assertTrue( UploadFromStash::isValidRequest( $request ), 'Check good wpSessionKey' );
 
-               $request = new FauxRequest( array( 'wpFileKey' => 'testkey-test.test', 'wpSessionKey' => 'foo') );
-               $this->assertTrue( UploadFromStash::isValidRequest($request), 'Check key precedence' );
+               $request = new FauxRequest( array( 'wpFileKey' => 'testkey-test.test', 'wpSessionKey' => 'foo' ) );
+               $this->assertTrue( UploadFromStash::isValidRequest( $request ), 'Check key precedence' );
        }
 }
index 34c57aa..b809d32 100644 (file)
@@ -12,7 +12,7 @@ class UploadTest extends MediaWikiTestCase {
 
                $this->upload = new UploadTestHandler;
                $this->hooks = $wgHooks;
-               $wgHooks['InterwikiLoadPrefix'][] = function( $prefix, &$data ) {
+               $wgHooks['InterwikiLoadPrefix'][] = function ( $prefix, &$data ) {
                        return false;
                };
        }
@@ -28,7 +28,7 @@ class UploadTest extends MediaWikiTestCase {
        /**
         * First checks the return code
         * of UploadBase::getTitle() and then the actual returned title
-        * 
+        *
         * @dataProvider provideTestTitleValidation
         */
        public function testTitleValidation( $srcFilename, $dstFilename, $code, $msg ) {
@@ -44,38 +44,38 @@ class UploadTest extends MediaWikiTestCase {
                                "$msg text" );
                }
        }
-       
+
        /**
         * Test various forms of valid and invalid titles that can be supplied.
         */
        public static function provideTestTitleValidation() {
                return array(
                        /* Test a valid title */
-                       array( 'ValidTitle.jpg', 'ValidTitle.jpg', UploadBase::OK, 
+                       array( 'ValidTitle.jpg', 'ValidTitle.jpg', UploadBase::OK,
                                'upload valid title' ),
                        /* A title with a slash */
-                       array( 'A/B.jpg', 'B.jpg', UploadBase::OK, 
+                       array( 'A/B.jpg', 'B.jpg', UploadBase::OK,
                                'upload title with slash' ),
                        /* A title with illegal char */
-                       array( 'A:B.jpg', 'A-B.jpg', UploadBase::OK, 
+                       array( 'A:B.jpg', 'A-B.jpg', UploadBase::OK,
                                'upload title with colon' ),
                        /* Stripping leading File: prefix */
-                       array( 'File:C.jpg', 'C.jpg', UploadBase::OK, 
+                       array( 'File:C.jpg', 'C.jpg', UploadBase::OK,
                                'upload title with File prefix' ),
                        /* Test illegal suggested title (r94601) */
-                       array( '%281%29.JPG', null, UploadBase::ILLEGAL_FILENAME, 
+                       array( '%281%29.JPG', null, UploadBase::ILLEGAL_FILENAME,
                                'illegal title for upload' ),
                        /* A title without extension */
-                       array( 'A', null, UploadBase::FILETYPE_MISSING, 
+                       array( 'A', null, UploadBase::FILETYPE_MISSING,
                                'upload title without extension' ),
                        /* A title with no basename */
-                       array( '.jpg', null, UploadBase::MIN_LENGTH_PARTNAME, 
+                       array( '.jpg', null, UploadBase::MIN_LENGTH_PARTNAME,
                                'upload title without basename' ),
                        /* A title that is longer than 255 bytes */
-                       array( str_repeat( 'a', 255 ) . '.jpg', null, UploadBase::FILENAME_TOO_LONG, 
+                       array( str_repeat( 'a', 255 ) . '.jpg', null, UploadBase::FILENAME_TOO_LONG,
                                'upload title longer than 255 bytes' ),
                        /* A title that is longer than 240 bytes */
-                       array( str_repeat( 'a', 240 ) . '.jpg', null, UploadBase::FILENAME_TOO_LONG, 
+                       array( str_repeat( 'a', 240 ) . '.jpg', null, UploadBase::FILENAME_TOO_LONG,
                                'upload title longer than 240 bytes' ),
                );
        }
@@ -118,26 +118,27 @@ class UploadTest extends MediaWikiTestCase {
                $wgMaxUploadSize = 100;
 
                $filename = $this->createFileOfSize( $wgMaxUploadSize );
-               $this->upload->initializePathInfo( basename($filename) . '.txt', $filename, 100 );
+               $this->upload->initializePathInfo( basename( $filename ) . '.txt', $filename, 100 );
                $result = $this->upload->verifyUpload();
                unlink( $filename );
 
                $this->assertEquals(
                        array( 'status' => UploadBase::OK ), $result );
 
-               $wgMaxUploadSize = $savedGlobal;  // restore global
+               $wgMaxUploadSize = $savedGlobal; // restore global
        }
 }
 
 class UploadTestHandler extends UploadBase {
-               public function initializeFromRequest( &$request ) { }
-               public function testTitleValidation( $name ) {
-                       $this->mTitle = false;
-                       $this->mDesiredDestName = $name;
-                       $this->mTitleError = UploadBase::OK;
-                       $this->getTitle();
-                       return $this->mTitleError;
-               }
+       public function initializeFromRequest( &$request ) {}
+
+       public function testTitleValidation( $name ) {
+               $this->mTitle = false;
+               $this->mDesiredDestName = $name;
+               $this->mTitleError = UploadBase::OK;
+               $this->getTitle();
+               return $this->mTitleError;
+       }
 
 
 }
index 16215c5..9723e1e 100644 (file)
@@ -10,12 +10,12 @@ class LanguageAmTest extends LanguageClassesTestCase {
 
        /** @dataProvider providePlural */
        function testPlural( $result, $value ) {
-               $forms =  array( 'one', 'other' );
+               $forms = array( 'one', 'other' );
                $this->assertEquals( $result, $this->getLang()->convertPlural( $value, $forms ) );
        }
 
        function providePlural() {
-               return array (
+               return array(
                        array( 'one', 0 ),
                        array( 'one', 1 ),
                        array( 'other', 2 ),
index 17f7352..523ee7f 100644 (file)
@@ -44,13 +44,15 @@ class LanguageArTest extends LanguageClassesTestCase {
                        ),
                );
        }
+
        /** @dataProvider providePlural */
        function testPlural( $result, $value ) {
-               $forms =  array( 'zero', 'one', 'two', 'few', 'many', 'other' );
+               $forms = array( 'zero', 'one', 'two', 'few', 'many', 'other' );
                $this->assertEquals( $result, $this->getLang()->convertPlural( $value, $forms ) );
        }
+
        function providePlural() {
-               return array (
+               return array(
                        array( 'zero', 0 ),
                        array( 'one', 1 ),
                        array( 'two', 2 ),
index 06ee240..0144941 100644 (file)
@@ -10,12 +10,12 @@ class LanguageBeTest extends LanguageClassesTestCase {
 
        /** @dataProvider providePlural */
        function testPlural( $result, $value ) {
-               $forms =  array( 'one', 'few', 'many', 'other' );
+               $forms = array( 'one', 'few', 'many', 'other' );
                $this->assertEquals( $result, $this->getLang()->convertPlural( $value, $forms ) );
        }
 
        function providePlural() {
-               return array (
+               return array(
                        array( 'one', 1 ),
                        array( 'many', 11 ),
                        array( 'one', 91 ),
index ad0ef43..5b246d8 100644 (file)
@@ -21,23 +21,26 @@ class LanguageBe_taraskTest extends LanguageClassesTestCase {
                        'bug 23156: U+2019 conversion to U+0027'
                );
        }
+
        /** see bug 23156 & r64981 */
        function testCommafy() {
                $this->assertEquals( '1,234,567', $this->getLang()->commafy( '1234567' ) );
-               $this->assertEquals(    '12,345', $this->getLang()->commafy(   '12345' ) );
+               $this->assertEquals( '12,345', $this->getLang()->commafy( '12345' ) );
        }
+
        /** see bug 23156 & r64981 */
        function testDoesNotCommafyFourDigitsNumber() {
-               $this->assertEquals(      '1234', $this->getLang()->commafy(    '1234' ) );
+               $this->assertEquals( '1234', $this->getLang()->commafy( '1234' ) );
        }
+
        /** @dataProvider providePluralFourForms */
        function testPluralFourForms( $result, $value ) {
-               $forms =  array( 'one', 'few', 'many', 'other' );
+               $forms = array( 'one', 'few', 'many', 'other' );
                $this->assertEquals( $result, $this->getLang()->convertPlural( $value, $forms ) );
        }
 
        function providePluralFourForms() {
-               return array (
+               return array(
                        array( 'one', 1 ),
                        array( 'many', 11 ),
                        array( 'one', 91 ),
@@ -51,13 +54,15 @@ class LanguageBe_taraskTest 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 ),
index 5bbd4fe..c364917 100644 (file)
@@ -10,12 +10,12 @@ class LanguageBhoTest extends LanguageClassesTestCase {
 
        /** @dataProvider providePlural */
        function testPlural( $result, $value ) {
-               $forms =  array( 'one', 'other' );
+               $forms = array( 'one', 'other' );
                $this->assertEquals( $result, $this->getLang()->convertPlural( $value, $forms ) );
        }
 
        function providePlural() {
-               return array (
+               return array(
                        array( 'one', 0 ),
                        array( 'one', 1 ),
                        array( 'other', 2 ),
index dd00428..76d0070 100644 (file)
@@ -10,12 +10,12 @@ class LanguageBsTest extends LanguageClassesTestCase {
 
        /** @dataProvider providePlural */
        function testPlural( $result, $value ) {
-               $forms =  array( 'one', 'few', 'many', 'other' );
+               $forms = array( 'one', 'few', 'many', 'other' );
                $this->assertEquals( $result, $this->getLang()->convertPlural( $value, $forms ) );
        }
 
        function providePlural() {
-               return array (
+               return array(
                        array( 'many', 0 ),
                        array( 'one', 1 ),
                        array( 'few', 2 ),
index 4f0a37f..6659dad 100644 (file)
@@ -32,7 +32,7 @@ abstract class LanguageClassesTestCase extends MediaWikiTestCase {
        /**
         * Regex used to find out the language code out of the class name
         * used by setUpBeforeClass
-       */
+        */
        private static $reExtractLangFromClass = '/Language(.*)Test/';
 
        /**
@@ -68,7 +68,7 @@ abstract class LanguageClassesTestCase extends MediaWikiTestCase {
                        $m[1] = 'en';
                        wfDebug(
                                __METHOD__ . " could not extract a language name "
-                               . "out of " . get_called_class() . " failling back to 'en'\n"
+                                       . "out of " . get_called_class() . " failling back to 'en'\n"
                        );
                }
                // TODO: validate $m[1] which should be a valid language code
index 72c9e79..884a129 100644 (file)
@@ -10,12 +10,12 @@ class LanguageCsTest extends LanguageClassesTestCase {
 
        /** @dataProvider providerPlural */
        function testPlural( $result, $value ) {
-               $forms =  array( 'one', 'few', 'other' );
+               $forms = array( 'one', 'few', 'other' );
                $this->assertEquals( $result, $this->getLang()->convertPlural( $value, $forms ) );
        }
 
        function providerPlural() {
-               return array (
+               return array(
                        array( 'other', 0 ),
                        array( 'one', 1 ),
                        array( 'few', 2 ),
index 95f8da7..e2394b3 100644 (file)
@@ -10,12 +10,12 @@ class LanguageCuTest extends LanguageClassesTestCase {
 
        /** @dataProvider providerPlural */
        function testPlural( $result, $value ) {
-               $forms =  array( 'one', 'few', 'many', 'other' );
+               $forms = array( 'one', 'few', 'many', 'other' );
                $this->assertEquals( $result, $this->getLang()->convertPlural( $value, $forms ) );
        }
 
        function providerPlural() {
-               return array (
+               return array(
                        array( 'other', 0 ),
                        array( 'one', 1 ),
                        array( 'few', 2 ),
index de6ba5c..2a7f4a9 100644 (file)
@@ -10,12 +10,12 @@ class LanguageCyTest extends LanguageClassesTestCase {
 
        /** @dataProvider providerPlural */
        function testPlural( $result, $value ) {
-               $forms =  array( 'zero', 'one', 'two', 'few', 'many', 'other' );
+               $forms = array( 'zero', 'one', 'two', 'few', 'many', 'other' );
                $this->assertEquals( $result, $this->getLang()->convertPlural( $value, $forms ) );
        }
 
        function providerPlural() {
-               return array (
+               return array(
                        array( 'zero', 0 ),
                        array( 'one', 1 ),
                        array( 'two', 2 ),
index 8fb6024..285ce64 100644 (file)
@@ -10,12 +10,12 @@ class LanguageDsbTest extends LanguageClassesTestCase {
 
        /** @dataProvider providePlural */
        function testPlural( $result, $value ) {
-               $forms =  array( 'one', 'two', 'few', 'other' );
+               $forms = array( 'one', 'two', 'few', 'other' );
                $this->assertEquals( $result, $this->getLang()->convertPlural( $value, $forms ) );
        }
 
        function providePlural() {
-               return array (
+               return array(
                        array( 'other', 0 ),
                        array( 'one', 1 ),
                        array( 'one', 101 ),
index 05de960..faf0de5 100644 (file)
@@ -10,12 +10,12 @@ class LanguageFrTest extends LanguageClassesTestCase {
 
        /** @dataProvider providePlural */
        function testPlural( $result, $value ) {
-               $forms =  array( 'one', 'other' );
+               $forms = array( 'one', 'other' );
                $this->assertEquals( $result, $this->getLang()->convertPlural( $value, $forms ) );
        }
 
        function providePlural() {
-               return array (
+               return array(
                        array( 'one', 0 ),
                        array( 'one', 1 ),
                        array( 'other', 2 ),
index 0a54592..2dbb088 100644 (file)
@@ -10,12 +10,12 @@ class LanguageGaTest extends LanguageClassesTestCase {
 
        /** @dataProvider providerPlural */
        function testPlural( $result, $value ) {
-               $forms =  array( 'one', 'two', 'other' );
+               $forms = array( 'one', 'two', 'other' );
                $this->assertEquals( $result, $this->getLang()->convertPlural( $value, $forms ) );
        }
 
        function providerPlural() {
-               return array (
+               return array(
                        array( 'other', 0 ),
                        array( 'one', 1 ),
                        array( 'two', 2 ),
index 7831cd2..409820f 100644 (file)
@@ -11,11 +11,12 @@ class LanguageGdTest extends LanguageClassesTestCase {
        /** @dataProvider providerPlural */
        function testPlural( $result, $value ) {
                // The CLDR ticket for this plural forms is not same as mw plural forms. See http://unicode.org/cldr/trac/ticket/2883
-               $forms =  array( 'Form 1', 'Form 2', 'Form 3', 'Form 4', 'Form 5', 'Form 6' );
+               $forms = array( 'Form 1', 'Form 2', 'Form 3', 'Form 4', 'Form 5', 'Form 6' );
                $this->assertEquals( $result, $this->getLang()->convertPlural( $value, $forms ) );
        }
+
        function providerPlural() {
-               return array (
+               return array(
                        array( 'Form 6', 0 ),
                        array( 'Form 1', 1 ),
                        array( 'Form 2', 2 ),
index 0edff59..4126e07 100644 (file)
@@ -11,11 +11,12 @@ class LanguageGvTest extends LanguageClassesTestCase {
        /** @dataProvider providerPlural */
        function testPlural( $result, $value ) {
                // This is not compatible with CLDR plural rules http://unicode.org/repos/cldr-tmp/trunk/diff/supplemental/language_plural_rules.html#gv
-               $forms =  array( 'Form 1', 'Form 2', 'Form 3', 'Form 4' );
+               $forms = array( 'Form 1', 'Form 2', 'Form 3', 'Form 4' );
                $this->assertEquals( $result, $this->getLang()->convertPlural( $value, $forms ) );
        }
+
        function providerPlural() {
-               return array (
+               return array(
                        array( 'Form 4', 0 ),
                        array( 'Form 2', 1 ),
                        array( 'Form 3', 2 ),
index 575b277..6de88e5 100644 (file)
@@ -15,7 +15,7 @@ class LanguageHeTest extends LanguageClassesTestCase {
        }
 
        function providerPluralDual() {
-               return array (
+               return array(
                        array( 'other', 0 ), // Zero -> plural
                        array( 'one', 1 ), // Singular
                        array( 'two', 2 ), // Dual
@@ -30,7 +30,7 @@ class LanguageHeTest extends LanguageClassesTestCase {
        }
 
        function providerPlural() {
-               return array (
+               return array(
                        array( 'other', 0 ), // Zero -> plural
                        array( 'one', 1 ), // Singular
                        array( 'other', 2 ), // Plural, no dual provided
@@ -46,7 +46,7 @@ class LanguageHeTest extends LanguageClassesTestCase {
        // The comments in the beginning of the line help avoid RTL problems
        // with text editors.
        function providerGrammar() {
-               return array (
+               return array(
                        array(
                                /* result */ 'וויקיפדיה',
                                /* word   */ 'ויקיפדיה',
index 5a780a2..86d6af5 100644 (file)
@@ -10,12 +10,12 @@ class LanguageHiTest extends LanguageClassesTestCase {
 
        /** @dataProvider providePlural */
        function testPlural( $result, $value ) {
-               $forms =  array( 'one', 'other' );
+               $forms = array( 'one', 'other' );
                $this->assertEquals( $result, $this->getLang()->convertPlural( $value, $forms ) );
        }
 
        function providePlural() {
-               return array (
+               return array(
                        array( 'one', 0 ),
                        array( 'one', 1 ),
                        array( 'other', 2 ),
index 748aaf4..9dce4ea 100644 (file)
@@ -10,12 +10,12 @@ class LanguageHrTest extends LanguageClassesTestCase {
 
        /** @dataProvider providerPlural */
        function testPlural( $result, $value ) {
-               $forms =  array( 'one', 'few', 'many', 'other' );
+               $forms = array( 'one', 'few', 'many', 'other' );
                $this->assertEquals( $result, $this->getLang()->convertPlural( $value, $forms ) );
        }
 
        function providerPlural() {
-               return array (
+               return array(
                        array( 'many', 0 ),
                        array( 'one', 1 ),
                        array( 'few', 2 ),
index 2d90ef0..bec7d81 100644 (file)
@@ -10,12 +10,12 @@ class LanguageHsbTest extends LanguageClassesTestCase {
 
        /** @dataProvider providePlural */
        function testPlural( $result, $value ) {
-               $forms =  array( 'one', 'two', 'few', 'other' );
+               $forms = array( 'one', 'two', 'few', 'other' );
                $this->assertEquals( $result, $this->getLang()->convertPlural( $value, $forms ) );
        }
 
        function providePlural() {
-               return array (
+               return array(
                        array( 'other', 0 ),
                        array( 'one', 1 ),
                        array( 'one', 101 ),
index e01278b..23d8e0c 100644 (file)
@@ -15,7 +15,7 @@ class LanguageHuTest extends LanguageClassesTestCase {
        }
 
        function providePlural() {
-               return array (
+               return array(
                        array( 'other', 0 ),
                        array( 'one', 1 ),
                        array( 'other', 2 ),
index ea6e255..7088d37 100644 (file)
@@ -10,13 +10,13 @@ class LanguageHyTest extends LanguageClassesTestCase {
 
        /** @dataProvider providerPlural */
        function testPlural( $result, $value ) {
-               $forms =  array( 'one', 'other' );
+               $forms = array( 'one', 'other' );
                $this->assertEquals( $result, $this->getLang()->convertPlural( $value, $forms ) );
        }
 
        function providerPlural() {
-               return array (
-                       array( 'one', 0 ),
+               return array(
+                       array( 'other', 0 ),
                        array( 'one', 1 ),
                        array( 'other', 2 ),
                        array( 'other', 200 ),
index e92d264..9b4a53a 100644 (file)
@@ -10,12 +10,12 @@ class LanguageKshTest extends LanguageClassesTestCase {
 
        /** @dataProvider providerPlural */
        function testPlural( $result, $value ) {
-               $forms =  array(  'one', 'other', 'zero' );
+               $forms = array( 'one', 'other', 'zero' );
                $this->assertEquals( $result, $this->getLang()->convertPlural( $value, $forms ) );
        }
 
        function providerPlural() {
-               return array (
+               return array(
                        array( 'zero', 0 ),
                        array( 'one', 1 ),
                        array( 'other', 2 ),
index 8853caa..669d8b0 100644 (file)
@@ -10,12 +10,12 @@ class LanguageLnTest extends LanguageClassesTestCase {
 
        /** @dataProvider providePlural */
        function testPlural( $result, $value ) {
-               $forms =  array( 'one', 'other' );
+               $forms = array( 'one', 'other' );
                $this->assertEquals( $result, $this->getLang()->convertPlural( $value, $forms ) );
        }
 
        function providePlural() {
-               return array (
+               return array(
                        array( 'one', 0 ),
                        array( 'one', 1 ),
                        array( 'other', 2 ),
index 485a090..9d6428b 100644 (file)
@@ -10,18 +10,18 @@ class LanguageLtTest extends LanguageClassesTestCase {
 
        /** @dataProvider provideOneFewOtherCases */
        function testOneFewOtherPlural( $result, $value ) {
-               $forms =  array( 'one', 'few', 'other' );
+               $forms = array( 'one', 'few', 'other' );
                $this->assertEquals( $result, $this->getLang()->convertPlural( $value, $forms ) );
        }
-       
+
        /** @dataProvider provideOneFewCases */
        function testOneFewPlural( $result, $value ) {
-               $forms =  array( 'one', 'few' );
+               $forms = array( 'one', 'few' );
                $this->assertEquals( $result, $this->getLang()->convertPlural( $value, $forms ) );
        }
 
        function provideOneFewOtherCases() {
-               return array (
+               return array(
                        array( 'other', 0 ),
                        array( 'one', 1 ),
                        array( 'few', 2 ),
@@ -35,9 +35,9 @@ class LanguageLtTest extends LanguageClassesTestCase {
                        array( 'one', 40001 ),
                );
        }
-       
+
        function provideOneFewCases() {
-               return array (
+               return array(
                        array( 'one', 1 ),
                        array( 'few', 15 ),
                );
index bf4f793..efb6de6 100644 (file)
@@ -10,12 +10,12 @@ class LanguageLvTest extends LanguageClassesTestCase {
 
        /** @dataProvider providerPlural */
        function testPlural( $result, $value ) {
-               $forms =  array( 'one', 'other' );
+               $forms = array( 'one', 'other' );
                $this->assertEquals( $result, $this->getLang()->convertPlural( $value, $forms ) );
        }
 
        function providerPlural() {
-               return array (
+               return array(
                        array( 'other', 0 ), #this must be zero form as per CLDR
                        array( 'one', 1 ),
                        array( 'other', 11 ),
index d6d3de9..c1e516b 100644 (file)
@@ -10,12 +10,12 @@ class LanguageMgTest extends LanguageClassesTestCase {
 
        /** @dataProvider providePlural */
        function testPlural( $result, $value ) {
-               $forms =  array( 'one', 'other' );
+               $forms = array( 'one', 'other' );
                $this->assertEquals( $result, $this->getLang()->convertPlural( $value, $forms ) );
        }
 
        function providePlural() {
-               return array (
+               return array(
                        array( 'one', 0 ),
                        array( 'one', 1 ),
                        array( 'other', 2 ),
index 8cd84b8..5c241ba 100644 (file)
@@ -10,13 +10,13 @@ class LanguageMkTest extends LanguageClassesTestCase {
 
        /** @dataProvider providerPlural */
        function testPlural( $result, $value ) {
-               $forms =  array( 'one', 'other' );
+               $forms = array( 'one', 'other' );
                $this->assertEquals( $result, $this->getLang()->convertPlural( $value, $forms ) );
        }
 
 
        function providerPlural() {
-               return array (
+               return array(
                        array( 'other', 0 ),
                        array( 'one', 1 ),
                        array( 'other', 11 ),
index 10ff664..396114d 100644 (file)
@@ -9,17 +9,17 @@
 class LanguageMlTest extends LanguageClassesTestCase {
 
        /** see bug 29495 */
-       /** @dataProvider providerFormatNum*/
+       /** @dataProvider providerFormatNum */
        function testFormatNum( $result, $value ) {
                $this->assertEquals( $result, $this->getLang()->formatNum( $value ) );
        }
 
        function providerFormatNum() {
                return array(
-                       array( '12,34,567', '1234567'  ),
+                       array( '12,34,567', '1234567' ),
                        array( '12,345', '12345' ),
                        array( '1', '1' ),
-                       array( '123', '123' ) ,
+                       array( '123', '123' ),
                        array( '1,234', '1234' ),
                        array( '12,345.56', '12345.56' ),
                        array( '12,34,56,79,81,23,45,678', '12345679812345678' ),
@@ -27,7 +27,7 @@ class LanguageMlTest extends LanguageClassesTestCase {
                        array( '-12,00,000', '-1200000' ),
                        array( '-98', '-98' ),
                        array( '-98', -98 ),
-                       array( '-1,23,45,678',  -12345678 ),
+                       array( '-1,23,45,678', -12345678 ),
                        array( '', '' ),
                        array( '', null ),
                );
index 491d8ac..f7da1cd 100644 (file)
@@ -10,25 +10,25 @@ class LanguageMoTest extends LanguageClassesTestCase {
 
        /** @dataProvider providerPlural */
        function testPlural( $result, $value ) {
-               $forms =  array( 'one', 'few', 'other' );
+               $forms = array( 'one', 'few', 'other' );
                $this->assertEquals( $result, $this->getLang()->convertPlural( $value, $forms ) );
        }
 
        function providerPlural() {
-               return array (
-                       array( 'few',   0 ),
-                       array( 'one',   1 ),
-                       array( 'few',   2 ),
-                       array( 'few',   19 ),
+               return array(
+                       array( 'few', 0 ),
+                       array( 'one', 1 ),
+                       array( 'few', 2 ),
+                       array( 'few', 19 ),
                        array( 'other', 20 ),
                        array( 'other', 99 ),
                        array( 'other', 100 ),
-                       array( 'few',   101 ),
-                       array( 'few',   119 ),
+                       array( 'few', 101 ),
+                       array( 'few', 119 ),
                        array( 'other', 120 ),
                        array( 'other', 200 ),
-                       array( 'few',   201 ),
-                       array( 'few',   219 ),
+                       array( 'few', 201 ),
+                       array( 'few', 219 ),
                        array( 'other', 220 ),
                );
        }
index 70cd93a..f2b881e 100644 (file)
@@ -15,21 +15,21 @@ class LanguageMtTest extends LanguageClassesTestCase {
        }
 
        function providerPluralAllForms() {
-               return array (
-                       array( 'few',   0 ),
-                       array( 'one',   1 ),
-                       array( 'few',   2 ),
-                       array( 'few',   10 ),
-                       array( 'many',  11 ),
-                       array( 'many',  19 ),
+               return array(
+                       array( 'few', 0 ),
+                       array( 'one', 1 ),
+                       array( 'few', 2 ),
+                       array( 'few', 10 ),
+                       array( 'many', 11 ),
+                       array( 'many', 19 ),
                        array( 'other', 20 ),
                        array( 'other', 99 ),
                        array( 'other', 100 ),
                        array( 'other', 101 ),
-                       array( 'few',   102 ),
-                       array( 'few',   110 ),
-                       array( 'many',  111 ),
-                       array( 'many',  119 ),
+                       array( 'few', 102 ),
+                       array( 'few', 110 ),
+                       array( 'many', 111 ),
+                       array( 'many', 119 ),
                        array( 'other', 120 ),
                        array( 'other', 201 ),
                );
@@ -42,23 +42,23 @@ class LanguageMtTest extends LanguageClassesTestCase {
        }
 
        function providerPluralTwoForms() {
-               return array (
-                       array( 'many',  0 ),
-                       array( 'one',   1 ),
-                       array( 'many',  2 ),
-                       array( 'many',  10 ),
-                       array( 'many',  11 ),
-                       array( 'many',  19 ),
-                       array( 'many',  20 ),
-                       array( 'many',  99 ),
-                       array( 'many',  100 ),
-                       array( 'many',  101 ),
-                       array( 'many',  102 ),
-                       array( 'many',  110 ),
-                       array( 'many',  111 ),
-                       array( 'many',  119 ),
-                       array( 'many',  120 ),
-                       array( 'many',  201 ),
+               return array(
+                       array( 'many', 0 ),
+                       array( 'one', 1 ),
+                       array( 'many', 2 ),
+                       array( 'many', 10 ),
+                       array( 'many', 11 ),
+                       array( 'many', 19 ),
+                       array( 'many', 20 ),
+                       array( 'many', 99 ),
+                       array( 'many', 100 ),
+                       array( 'many', 101 ),
+                       array( 'many', 102 ),
+                       array( 'many', 110 ),
+                       array( 'many', 111 ),
+                       array( 'many', 119 ),
+                       array( 'many', 120 ),
+                       array( 'many', 201 ),
                );
        }
 }
index 97146d3..9d80d13 100644 (file)
@@ -15,9 +15,9 @@ class LanguageNsoTest extends LanguageClassesTestCase {
        }
 
        function providerPlural() {
-               return array (
-                       array( 'one',  0 ),
-                       array( 'one',  1 ),
+               return array(
+                       array( 'one', 0 ),
+                       array( 'one', 1 ),
                        array( 'many', 2 ),
                );
        }
index 00b7e9e..1e36097 100644 (file)
@@ -15,23 +15,23 @@ class LanguagePlTest extends LanguageClassesTestCase {
        }
 
        function providerPluralFourForms() {
-               return array (
-                       array( 'many',  0 ),
-                       array( 'one',   1 ),
-                       array( 'few',   2 ),
-                       array( 'few',   3 ),
-                       array( 'few',   4 ),
-                       array( 'many',  5 ),
-                       array( 'many',  9 ),
-                       array( 'many',  10 ),
-                       array( 'many',  11 ),
-                       array( 'many',  21 ),
-                       array( 'few',   22 ),
-                       array( 'few',   23 ),
-                       array( 'few',   24 ),
-                       array( 'many',  25 ),
-                       array( 'many',  200 ),
-                       array( 'many',  201 ),
+               return array(
+                       array( 'many', 0 ),
+                       array( 'one', 1 ),
+                       array( 'few', 2 ),
+                       array( 'few', 3 ),
+                       array( 'few', 4 ),
+                       array( 'many', 5 ),
+                       array( 'many', 9 ),
+                       array( 'many', 10 ),
+                       array( 'many', 11 ),
+                       array( 'many', 21 ),
+                       array( 'few', 22 ),
+                       array( 'few', 23 ),
+                       array( 'few', 24 ),
+                       array( 'many', 25 ),
+                       array( 'many', 200 ),
+                       array( 'many', 201 ),
                );
        }
 
@@ -42,23 +42,23 @@ class LanguagePlTest extends LanguageClassesTestCase {
        }
 
        function providerPlural() {
-               return array (
-                       array( 'many',  0 ),
-                       array( 'one',   1 ),
-                       array( 'many',  2 ),
-                       array( 'many',  3 ),
-                       array( 'many',  4 ),
-                       array( 'many',  5 ),
-                       array( 'many',  9 ),
-                       array( 'many',  10 ),
-                       array( 'many',  11 ),
-                       array( 'many',  21 ),
-                       array( 'many',  22 ),
-                       array( 'many',  23 ),
-                       array( 'many',  24 ),
-                       array( 'many',  25 ),
-                       array( 'many',  200 ),
-                       array( 'many',  201 ),
+               return array(
+                       array( 'many', 0 ),
+                       array( 'one', 1 ),
+                       array( 'many', 2 ),
+                       array( 'many', 3 ),
+                       array( 'many', 4 ),
+                       array( 'many', 5 ),
+                       array( 'many', 9 ),
+                       array( 'many', 10 ),
+                       array( 'many', 11 ),
+                       array( 'many', 21 ),
+                       array( 'many', 22 ),
+                       array( 'many', 23 ),
+                       array( 'many', 24 ),
+                       array( 'many', 25 ),
+                       array( 'many', 200 ),
+                       array( 'many', 201 ),
                );
        }
 }
index 61726bc..916ea45 100644 (file)
@@ -10,25 +10,25 @@ class LanguageRoTest extends LanguageClassesTestCase {
 
        /** @dataProvider providerPlural */
        function testPlural( $result, $value ) {
-               $forms =  array( 'one', 'few', 'other' );
+               $forms = array( 'one', 'few', 'other' );
                $this->assertEquals( $result, $this->getLang()->convertPlural( $value, $forms ) );
        }
 
        function providerPlural() {
-               return array (
-                       array( 'few',   0 ),
-                       array( 'one',   1 ),
-                       array( 'few',   2 ),
-                       array( 'few',   19 ),
+               return array(
+                       array( 'few', 0 ),
+                       array( 'one', 1 ),
+                       array( 'few', 2 ),
+                       array( 'few', 19 ),
                        array( 'other', 20 ),
                        array( 'other', 99 ),
                        array( 'other', 100 ),
-                       array( 'few',   101 ),
-                       array( 'few',   119 ),
+                       array( 'few', 101 ),
+                       array( 'few', 119 ),
                        array( 'other', 120 ),
                        array( 'other', 200 ),
-                       array( 'few',   201 ),
-                       array( 'few',   219 ),
+                       array( 'few', 201 ),
+                       array( 'few', 219 ),
                        array( 'other', 220 ),
                );
        }
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 cf76353..c7dd802 100644 (file)
@@ -15,10 +15,10 @@ class LanguageSeTest extends LanguageClassesTestCase {
        }
 
        function providerPluralThreeForms() {
-               return array (
+               return array(
                        array( 'other', 0 ),
-                       array( 'one',   1 ),
-                       array( 'two',   2 ),
+                       array( 'one', 1 ),
+                       array( 'two', 2 ),
                        array( 'other', 3 ),
                );
        }
@@ -30,9 +30,9 @@ class LanguageSeTest extends LanguageClassesTestCase {
        }
 
        function providerPlural() {
-               return array (
+               return array(
                        array( 'other', 0 ),
-                       array( 'one',   1 ),
+                       array( 'one', 1 ),
                        array( 'other', 2 ),
                        array( 'other', 3 ),
                );
index e2a56ca..8a6e979 100644 (file)
@@ -15,33 +15,33 @@ class LanguageSgsTest extends LanguageClassesTestCase {
        }
 
        function providePluralAllForms() {
-               return array (
-                       array( 'many',  0 ),
-                       array( 'one',   1 ),
-                       array( 'few',   2 ),
+               return array(
+                       array( 'many', 0 ),
+                       array( 'one', 1 ),
+                       array( 'few', 2 ),
                        array( 'other', 3 ),
-                       array( 'many',  10 ),
-                       array( 'many',  11 ),
-                       array( 'many',  12 ),
-                       array( 'many',  19 ),
+                       array( 'many', 10 ),
+                       array( 'many', 11 ),
+                       array( 'many', 12 ),
+                       array( 'many', 19 ),
                        array( 'other', 20 ),
-                       array( 'many',  100 ),
-                       array( 'one',   101 ),
-                       array( 'many',  111 ),
-                       array( 'many',  112 ),
+                       array( 'many', 100 ),
+                       array( 'one', 101 ),
+                       array( 'many', 111 ),
+                       array( 'many', 112 ),
                );
        }
 
        /** @dataProvider providePluralTwoForms */
        function testPluralTwoForms( $result, $value ) {
-               $forms =  array( 'one', 'other' );
+               $forms = array( 'one', 'other' );
                $this->assertEquals( $result, $this->getLang()->convertPlural( $value, $forms ) );
        }
 
        function providePluralTwoForms() {
-               return array (
+               return array(
                        array( 'other', 0 ),
-                       array( 'one',   1 ),
+                       array( 'one', 1 ),
                        array( 'other', 2 ),
                        array( 'other', 3 ),
                        array( 'other', 10 ),
@@ -50,7 +50,7 @@ class LanguageSgsTest extends LanguageClassesTestCase {
                        array( 'other', 19 ),
                        array( 'other', 20 ),
                        array( 'other', 100 ),
-                       array( 'one',   101 ),
+                       array( 'one', 101 ),
                        array( 'other', 111 ),
                        array( 'other', 112 ),
                );
index 25618c4..282fd2f 100644 (file)
@@ -15,9 +15,9 @@ class LanguageShTest extends LanguageClassesTestCase {
        }
 
        function providerPlural() {
-               return array (
+               return array(
                        array( 'many', 0 ),
-                       array( 'one',  1 ),
+                       array( 'one', 1 ),
                        array( 'many', 2 ),
                );
        }
index b50f7df..89cbbf0 100644 (file)
@@ -16,7 +16,7 @@ class LanguageSkTest extends LanguageClassesTestCase {
        }
 
        function providerPlural() {
-               return array (
+               return array(
                        array( 'other', 0 ),
                        array( 'one', 1 ),
                        array( 'few', 2 ),
index bfb7c7e..075e6af 100644 (file)
@@ -16,19 +16,19 @@ class LanguageSlTest extends LanguageClassesTestCase {
        }
 
        function providerPlural() {
-               return array (
-                       array( 'zero',  0 ),
-                       array( 'one',   1 ),
-                       array( 'two',   2 ),
-                       array( 'few',   3 ),
-                       array( 'few',   4 ),
+               return array(
+                       array( 'zero', 0 ),
+                       array( 'one', 1 ),
+                       array( 'two', 2 ),
+                       array( 'few', 3 ),
+                       array( 'few', 4 ),
                        array( 'other', 5 ),
                        array( 'other', 99 ),
                        array( 'other', 100 ),
-                       array( 'one',   101 ),
-                       array( 'two',   102 ),
-                       array( 'few',   103 ),
-                       array( 'one',   201 ),
+                       array( 'one', 101 ),
+                       array( 'two', 102 ),
+                       array( 'few', 103 ),
+                       array( 'one', 201 ),
                );
        }
 }
index 85fa9fb..6d65521 100644 (file)
@@ -15,10 +15,10 @@ class LanguageSmaTest extends LanguageClassesTestCase {
        }
 
        function providerPluralThreeForms() {
-               return array (
+               return array(
                        array( 'other', 0 ),
-                       array( 'one',   1 ),
-                       array( 'two',   2 ),
+                       array( 'one', 1 ),
+                       array( 'two', 2 ),
                        array( 'other', 3 ),
                );
        }
@@ -30,9 +30,9 @@ class LanguageSmaTest extends LanguageClassesTestCase {
        }
 
        function providerPlural() {
-               return array (
+               return array(
                        array( 'other', 0 ),
-                       array( 'one',   1 ),
+                       array( 'one', 1 ),
                        array( 'other', 2 ),
                        array( 'other', 3 ),
                );
index c88115d..5611030 100644 (file)
@@ -19,7 +19,7 @@ class LanguageSrTest extends LanguageClassesTestCase {
 
        ##### TESTS #######################################################
 
-       function testEasyConversions( ) {
+       function testEasyConversions() {
                $this->assertCyrillic(
                        'шђчћжШЂЧЋЖ',
                        'Cyrillic guessing characters'
@@ -120,7 +120,7 @@ class LanguageSrTest extends LanguageClassesTestCase {
        }
 
        function providePluralFourForms() {
-               return array (
+               return array(
                        array( 'one', 1 ),
                        array( 'many', 11 ),
                        array( 'one', 91 ),
@@ -134,13 +134,15 @@ class LanguageSrTest extends LanguageClassesTestCase {
                        array( 'many', 120 ),
                );
        }
+
        /** @dataProvider providePluralTwoForms */
        function testPluralTwoForms( $result, $value ) {
                $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 ),
@@ -162,6 +164,7 @@ class LanguageSrTest extends LanguageClassesTestCase {
                        $msg
                );
        }
+
        /**
         * Wrapper to verify a text is different once converted to a variant.
         * @param $text string Text to convert
@@ -185,6 +188,7 @@ class LanguageSrTest extends LanguageClassesTestCase {
                $this->assertUnConverted( $text, 'sr-ec', $msg );
                $this->assertConverted( $text, 'sr-el', $msg );
        }
+
        /**
         * Verifiy the given Latin text is not converted when using
         * using the Latin variant and converted to Cyrillic when using
@@ -201,12 +205,14 @@ class LanguageSrTest extends LanguageClassesTestCase {
                return $this->getLang()
                        ->mConverter
                        ->convertTo(
-                               $text, $variant
-                       );
+                       $text, $variant
+               );
        }
+
        function convertToCyrillic( $text ) {
                return $this->convertTo( $text, 'sr-ec' );
        }
+
        function convertToLatin( $text ) {
                return $this->convertTo( $text, 'sr-el' );
        }
index 9507714..8b0b14b 100644 (file)
@@ -439,10 +439,10 @@ class LanguageTest extends LanguageClassesTestCase {
 
        function provideLanguageCodes() {
                return array(
-                       array( 'fr'       , 'Two letters, minor case' ),
-                       array( 'EN'       , 'Two letters, upper case' ),
-                       array( 'tyv'      , 'Three letters' ),
-                       array( 'tokipona'   , 'long language code' ),
+                       array( 'fr', 'Two letters, minor case' ),
+                       array( 'EN', 'Two letters, upper case' ),
+                       array( 'tyv', 'Three letters' ),
+                       array( 'tokipona', 'long language code' ),
                        array( 'be-tarask', 'With dash' ),
                        array( 'Zh-classical', 'Begin with upper case, dash' ),
                        array( 'Be-x-old', 'With extension (two dashes)' ),
@@ -455,7 +455,7 @@ class LanguageTest extends LanguageClassesTestCase {
         */
        function testKnownLanguageTag( $code, $message = '' ) {
                $this->assertTrue(
-                       (bool) Language::isKnownLanguageTag( $code ),
+                       (bool)Language::isKnownLanguageTag( $code ),
                        "validating code $code - $message"
                );
        }
@@ -477,7 +477,7 @@ class LanguageTest extends LanguageClassesTestCase {
                }
 
                $this->assertTrue(
-                       (bool) Language::isKnownLanguageTag( 'pal' ),
+                       (bool)Language::isKnownLanguageTag( 'pal' ),
                        'validating code "pal" an ancient language, which probably will not appear in Names.php, but appears in CLDR in English'
                );
        }
@@ -488,7 +488,7 @@ class LanguageTest extends LanguageClassesTestCase {
         */
        function testUnknownLanguageTag( $code, $message = '' ) {
                $this->assertFalse(
-                       (bool) Language::isKnownLanguageTag( $code ),
+                       (bool)Language::isKnownLanguageTag( $code ),
                        "checking that code $code is invalid - $message"
                );
        }
@@ -509,6 +509,7 @@ class LanguageTest extends LanguageClassesTestCase {
                        "sprintfDate('$format', '$ts'): $msg"
                );
        }
+
        /**
         * bug 33454. sprintfDate should always use UTC.
         * @dataProvider provideSprintfDateSamples
@@ -958,7 +959,6 @@ class LanguageTest extends LanguageClassesTestCase {
        }
 
 
-
        /**
         * @dataProvider provideFormatDuration
         */
@@ -1101,13 +1101,13 @@ class LanguageTest extends LanguageClassesTestCase {
        function testCheckTitleEncoding( $s ) {
                $this->assertEquals(
                        $s,
-                       $this->getLang()->checkTitleEncoding($s),
+                       $this->getLang()->checkTitleEncoding( $s ),
                        "checkTitleEncoding('$s')"
                );
        }
 
        function provideCheckTitleEncodingData() {
-               return array (
+               return array(
                        array( "" ),
                        array( "United States of America" ), // 7bit ASCII
                        array( rawurldecode( "S%C3%A9rie%20t%C3%A9l%C3%A9vis%C3%A9e" ) ),
@@ -1212,7 +1212,7 @@ class LanguageTest extends LanguageClassesTestCase {
                        array( 7000, 'MMMMMMM' ),
                        array( 8000, 'MMMMMMMM' ),
                        array( 9000, 'MMMMMMMMM' ),
-                       array( 9999, 'MMMMMMMMMCMXCIX'),
+                       array( 9999, 'MMMMMMMMMCMXCIX' ),
                        array( 10000, 'MMMMMMMMMM' ),
                );
        }
@@ -1311,7 +1311,7 @@ class LanguageTest extends LanguageClassesTestCase {
                $s = $lang->getMessageFromDB( 'word-separator' );
                $c = $lang->getMessageFromDB( 'comma-separator' );
 
-               $this->assertEquals( '', $lang->listToText( array( ) ) );
+               $this->assertEquals( '', $lang->listToText( array() ) );
                $this->assertEquals( 'a', $lang->listToText( array( 'a' ) ) );
                $this->assertEquals( "a{$and}{$s}b", $lang->listToText( array( 'a', 'b' ) ) );
                $this->assertEquals( "a{$c}b{$and}{$s}c", $lang->listToText( array( 'a', 'b', 'c' ) ) );
index 259e007..8af0eee 100644 (file)
@@ -15,9 +15,9 @@ class LanguageTiTest extends LanguageClassesTestCase {
        }
 
        function providerPlural() {
-               return array (
-                       array( 'one',  0 ),
-                       array( 'one',  1 ),
+               return array(
+                       array( 'one', 0 ),
+                       array( 'one', 1 ),
                        array( 'many', 2 ),
                );
        }
index bf3dafc..abd8581 100644 (file)
@@ -15,9 +15,9 @@ class LanguageTlTest extends LanguageClassesTestCase {
        }
 
        function providerPlural() {
-               return array (
-                       array( 'one',  0 ),
-                       array( 'one',  1 ),
+               return array(
+                       array( 'one', 0 ),
+                       array( 'one', 1 ),
                        array( 'many', 2 ),
                );
        }
index e4859df..e93d49d 100644 (file)
@@ -18,9 +18,9 @@ class LanguageTrTest extends LanguageClassesTestCase {
         * @dataProvider provideDottedAndDotlessI
         */
        function testDottedAndDotlessI( $func, $input, $inputCase, $expected ) {
-               if( $func == 'ucfirst' ) {
+               if ( $func == 'ucfirst' ) {
                        $res = $this->getLang()->ucfirst( $input );
-               } elseif( $func == 'lcfirst' ) {
+               } elseif ( $func == 'lcfirst' ) {
                        $res = $this->getLang()->lcfirst( $input );
                } else {
                        throw new MWException( __METHOD__ . " given an invalid function name '$func'" );
index f29b90b..9bbfaf6 100644 (file)
@@ -16,7 +16,7 @@ class LanguageUkTest extends LanguageClassesTestCase {
        }
 
        function providePluralFourForms() {
-               return array (
+               return array(
                        array( 'one', 1 ),
                        array( 'many', 11 ),
                        array( 'one', 91 ),
@@ -30,13 +30,15 @@ class LanguageUkTest extends LanguageClassesTestCase {
                        array( 'many', 120 ),
                );
        }
+
        /** @dataProvider providePluralTwoForms */
        function testPluralTwoForms( $result, $value ) {
                $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 ),
index 99607d1..495c0be 100644 (file)
@@ -64,6 +64,7 @@ class LanguageUzTest extends LanguageClassesTestCase {
                        $msg
                );
        }
+
        /**
         * Wrapper to verify a text is different once converted to a variant.
         * @param $text string Text to convert
@@ -87,6 +88,7 @@ class LanguageUzTest extends LanguageClassesTestCase {
                $this->assertUnConverted( $text, 'uz-cyrl', $msg );
                $this->assertConverted( $text, 'uz-latn', $msg );
        }
+
        /**
         * Verifiy the given Latin text is not converted when using
         * using the Latin variant and converted to Cyrillic when using
@@ -102,9 +104,11 @@ class LanguageUzTest extends LanguageClassesTestCase {
        function convertTo( $text, $variant ) {
                return $this->getLang()->mConverter->convertTo( $text, $variant );
        }
+
        function convertToCyrillic( $text ) {
                return $this->convertTo( $text, 'uz-cyrl' );
        }
+
        function convertToLatin( $text ) {
                return $this->convertTo( $text, 'uz-latn' );
        }
index 4a1c0e7..28329fa 100644 (file)
@@ -15,9 +15,9 @@ class LanguageWaTest extends LanguageClassesTestCase {
        }
 
        function providerPlural() {
-               return array (
-                       array( 'one',  0 ),
-                       array( 'one',  1 ),
+               return array(
+                       array( 'one', 0 ),
+                       array( 'one', 1 ),
                        array( 'many', 2 ),
                );
        }
index 58fcf16..73d5dcc 100644 (file)
@@ -31,19 +31,19 @@ class CLDRPluralRuleEvaluatorTest extends MediaWikiTestCase {
                        array( 1, 'n is 1', 1.1, 'float number and is' ),
                        array( 1, 'n is 1', 2, 'float number and is' ),
 
-                       array( 0, 'n in 1,3,5',     3, '' ),
+                       array( 0, 'n in 1,3,5', 3, '' ),
                        array( 1, 'n not in 1,3,5', 5, '' ),
 
-                       array( 1, 'n in 1,3,5',     2, '' ),
+                       array( 1, 'n in 1,3,5', 2, '' ),
                        array( 0, 'n not in 1,3,5', 4, '' ),
 
-                       array( 0, 'n in 1..3',      2, '' ),
-                       array( 0, 'n in 1..3',      3, 'in is inclusive' ),
-                       array( 1, 'n in 1..3',      0, '' ),
+                       array( 0, 'n in 1..3', 2, '' ),
+                       array( 0, 'n in 1..3', 3, 'in is inclusive' ),
+                       array( 1, 'n in 1..3', 0, '' ),
 
-                       array( 1, 'n not in 1..3',      2, '' ),
-                       array( 1, 'n not in 1..3',      3, 'in is inclusive' ),
-                       array( 0, 'n not in 1..3',      0, '' ),
+                       array( 1, 'n not in 1..3', 2, '' ),
+                       array( 1, 'n not in 1..3', 3, 'in is inclusive' ),
+                       array( 0, 'n not in 1..3', 0, '' ),
 
                        array( 1, 'n is not 1 and n is not 2 and n is not 3', 1, 'and relation' ),
                        array( 0, 'n is not 1 and n is not 2 and n is not 4', 3, 'and relation' ),
index 106fab8..40d24fc 100644 (file)
@@ -121,7 +121,8 @@ abstract class DumpTestCase extends MediaWikiLangTestCase {
        protected function skipToNodeEnd( $name ) {
                while ( $this->xml->read() ) {
                        if ( $this->xml->nodeType == XMLReader::END_ELEMENT &&
-                               $this->xml->name == $name ) {
+                               $this->xml->name == $name
+                       ) {
                                return true;
                        }
                }
@@ -189,7 +190,7 @@ abstract class DumpTestCase extends MediaWikiLangTestCase {
        protected function skipWhitespace() {
                $cont = true;
                while ( $cont && ( ( $this->xml->nodeType == XMLReader::WHITESPACE )
-                               || ( $this->xml->nodeType == XMLReader::SIGNIFICANT_WHITESPACE ) ) ) {
+                       || ( $this->xml->nodeType == XMLReader::SIGNIFICANT_WHITESPACE ) ) ) {
                        $cont = $this->xml->read();
                }
        }
@@ -300,7 +301,7 @@ abstract class DumpTestCase extends MediaWikiLangTestCase {
         * @param $parentid int|false: (optional) id of the parent revision
         */
        protected function assertRevision( $id, $summary, $text_id, $text_bytes, $text_sha1, $text = false, $parentid = false,
-                                               $model = CONTENT_MODEL_WIKITEXT, $format = CONTENT_FORMAT_WIKITEXT ) {
+                                                                          $model = CONTENT_MODEL_WIKITEXT, $format = CONTENT_FORMAT_WIKITEXT ) {
 
                $this->assertNodeStart( "revision" );
                $this->skipWhitespace();
@@ -358,7 +359,8 @@ abstract class DumpTestCase extends MediaWikiLangTestCase {
                        $this->assertFalse( $this->xml->hasValue, "Revision has text" );
                        $this->assertTrue( $this->xml->read(), "Skipping text start tag" );
                        if ( ( $this->xml->nodeType == XMLReader::END_ELEMENT )
-                               && ( $this->xml->name == "text" ) ) {
+                               && ( $this->xml->name == "text" )
+                       ) {
 
                                $this->xml->read();
                        }
index b9c0fb8..235e9ad 100644 (file)
@@ -81,14 +81,14 @@ class MaintenanceFixup extends Maintenance {
                        return;
                }
 
-               return call_user_func_array ( array( "parent", __FUNCTION__ ), func_get_args() );
+               return call_user_func_array( array( "parent", __FUNCTION__ ), func_get_args() );
        }
 
        /**
         * Safety net around register_shutdown_function of Maintenance.php
         */
        public function __destruct() {
-               if ( ! $this->shutdownSimulated ) {
+               if ( !$this->shutdownSimulated ) {
                        // Someone generated a MaintenanceFixup instance without calling
                        // simulateShutdown. We'd have to raise a PHPUnit exception to correctly
                        // flag this illegal usage. However, we are already in a destruktor, which
@@ -112,7 +112,6 @@ class MaintenanceFixup extends Maintenance {
        }
 
 
-
        // --- Making protected functions visible for test
 
        public function output( $out, $channel = null ) {
@@ -120,11 +119,10 @@ class MaintenanceFixup extends Maintenance {
                // Maintenance::output signature. However, we do not use (or rely on)
                // those variables. Instead we pass to Maintenance::output whatever we
                // receive at runtime.
-               return call_user_func_array ( array( "parent", __FUNCTION__ ), func_get_args() );
+               return call_user_func_array( array( "parent", __FUNCTION__ ), func_get_args() );
        }
 
 
-
        // --- Requirements for getting instance of abstract class
 
        public function execute() {
@@ -173,7 +171,7 @@ class MaintenanceTest extends MediaWikiTestCase {
        private function assertOutputPrePostShutdown( $preShutdownOutput, $expectNLAppending ) {
 
                $this->assertEquals( $preShutdownOutput, $this->getActualOutput(),
-                               "Output before shutdown simulation" );
+                       "Output before shutdown simulation" );
 
                $this->m->simulateShutdown();
                $this->m = null;
@@ -710,7 +708,7 @@ class MaintenanceTest extends MediaWikiTestCase {
                $m2->output( "bar" );
 
                $this->assertEquals( "foobar", $this->getActualOutput(),
-                               "Output before shutdown simulation (m2)" );
+                       "Output before shutdown simulation (m2)" );
                $m2->simulateShutdown();
                $this->assertOutputPrePostShutdown( "foobar", false );
        }
@@ -722,7 +720,7 @@ class MaintenanceTest extends MediaWikiTestCase {
                $m2->output( "bar", null );
 
                $this->assertEquals( "foobar", $this->getActualOutput(),
-                               "Output before shutdown simulation (m2)" );
+                       "Output before shutdown simulation (m2)" );
                $m2->simulateShutdown();
                $this->assertOutputPrePostShutdown( "foobar", false );
        }
@@ -734,7 +732,7 @@ class MaintenanceTest extends MediaWikiTestCase {
                $m2->output( "bar", "bazChannel" );
 
                $this->assertEquals( "foobar", $this->getActualOutput(),
-                               "Output before shutdown simulation (m2)" );
+                       "Output before shutdown simulation (m2)" );
                $m2->simulateShutdown();
                $this->assertOutputPrePostShutdown( "foobar\n", true );
        }
@@ -746,7 +744,7 @@ class MaintenanceTest extends MediaWikiTestCase {
                $m2->output( "bar\n", null );
 
                $this->assertEquals( "foo\nbar\n", $this->getActualOutput(),
-                               "Output before shutdown simulation (m2)" );
+                       "Output before shutdown simulation (m2)" );
                $m2->simulateShutdown();
                $this->assertOutputPrePostShutdown( "foo\nbar\n", false );
        }
@@ -758,7 +756,7 @@ class MaintenanceTest extends MediaWikiTestCase {
                $m2->output( "bar\n", "bazChannel" );
 
                $this->assertEquals( "foobar", $this->getActualOutput(),
-                               "Output before shutdown simulation (m2)" );
+                       "Output before shutdown simulation (m2)" );
                $m2->simulateShutdown();
                $this->assertOutputPrePostShutdown( "foobar\n", true );
        }
@@ -770,7 +768,7 @@ class MaintenanceTest extends MediaWikiTestCase {
                $m2->outputChanneled( "bar" );
 
                $this->assertEquals( "foo\nbar\n", $this->getActualOutput(),
-                               "Output before shutdown simulation (m2)" );
+                       "Output before shutdown simulation (m2)" );
                $m2->simulateShutdown();
                $this->assertOutputPrePostShutdown( "foo\nbar\n", false );
        }
@@ -782,7 +780,7 @@ class MaintenanceTest extends MediaWikiTestCase {
                $m2->outputChanneled( "bar", null );
 
                $this->assertEquals( "foo\nbar\n", $this->getActualOutput(),
-                               "Output before shutdown simulation (m2)" );
+                       "Output before shutdown simulation (m2)" );
                $m2->simulateShutdown();
                $this->assertOutputPrePostShutdown( "foo\nbar\n", false );
        }
@@ -794,7 +792,7 @@ class MaintenanceTest extends MediaWikiTestCase {
                $m2->outputChanneled( "bar", "bazChannel" );
 
                $this->assertEquals( "foobar", $this->getActualOutput(),
-                               "Output before shutdown simulation (m2)" );
+                       "Output before shutdown simulation (m2)" );
                $m2->simulateShutdown();
                $this->assertOutputPrePostShutdown( "foobar\n", true );
        }
@@ -806,13 +804,13 @@ class MaintenanceTest extends MediaWikiTestCase {
                $m2->outputChanneled( "bar", "bazChannel" );
 
                $this->assertEquals( "foobar", $this->getActualOutput(),
-                               "Output before first cleanup" );
+                       "Output before first cleanup" );
                $this->m->cleanupChanneled();
                $this->assertEquals( "foobar\n", $this->getActualOutput(),
-                               "Output after first cleanup" );
+                       "Output after first cleanup" );
                $m2->cleanupChanneled();
                $this->assertEquals( "foobar\n\n", $this->getActualOutput(),
-                               "Output after second cleanup" );
+                       "Output after second cleanup" );
 
                $m2->simulateShutdown();
                $this->assertOutputPrePostShutdown( "foobar\n\n", false );
index a029c92..cc00e6e 100644 (file)
@@ -265,12 +265,12 @@ class BaseDumpTest extends MediaWikiTestCase {
                foreach ( $requested_pages as $i ) {
                        $this->assertTrue( array_key_exists( $i, $available_pages ),
                                "Check for availability of requested page " . $i );
-                       $content .= $available_pages[ $i ];
+                       $content .= $available_pages[$i];
                }
                $content .= $tail;
 
                $this->assertEquals( strlen( $content ), file_put_contents(
-                               $fname, $content ), "Length of prepared prefetch" );
+                       $fname, $content ), "Length of prepared prefetch" );
 
                return $fname;
        }
index 2a12806..0962344 100644 (file)
@@ -65,7 +65,7 @@ class TextPassDumperTest extends DumpTestCase {
                        if ( $ns === NS_TALK ) {
                                //@todo: work around this.
                                throw new MWException( "The default wikitext namespace is the talk namespace. "
-                                       . " We can't currently deal with that.");
+                                       . " We can't currently deal with that." );
                        }
 
                        $title = Title::newFromText( 'BackupDumperTestP1', NS_TALK );
@@ -101,8 +101,8 @@ class TextPassDumperTest extends DumpTestCase {
                // Setting up the dump
                $nameStub = $this->setUpStub();
                $nameFull = $this->getNewTempFile();
-               $dumper = new TextPassDumper( array ( "--stub=file:" . $nameStub,
-                               "--output=file:" . $nameFull ) );
+               $dumper = new TextPassDumper( array( "--stub=file:" . $nameStub,
+                       "--output=file:" . $nameFull ) );
                $dumper->reporting = false;
                $dumper->setDb( $this->db );
 
@@ -164,8 +164,8 @@ class TextPassDumperTest extends DumpTestCase {
                // Setting up of the dump
                $nameStub = $this->setUpStub();
                $nameFull = $this->getNewTempFile();
-               $dumper = new TextPassDumper( array ( "--stub=file:"
-                               . $nameStub, "--output=file:" . $nameFull ) );
+               $dumper = new TextPassDumper( array( "--stub=file:"
+                       . $nameStub, "--output=file:" . $nameFull ) );
                $dumper->prefetch = $prefetchMock;
                $dumper->reporting = false;
                $dumper->setDb( $this->db );
@@ -250,10 +250,10 @@ class TextPassDumperTest extends DumpTestCase {
                        $this->assertTrue( wfMkdirParents( $nameOutputDir ),
                                "Creating temporary output directory " );
                        $this->setUpStub( $nameStub, $iterations );
-                       $dumper = new TextPassDumper( array ( "--stub=file:" . $nameStub,
-                                       "--output=" . $checkpointFormat . ":" . $nameOutputDir . "/full",
-                                       "--maxtime=1" /*This is in minutes. Fixup is below*/,
-                                       "--checkpointfile=checkpoint-%s-%s.xml.gz" ) );
+                       $dumper = new TextPassDumper( array( "--stub=file:" . $nameStub,
+                               "--output=" . $checkpointFormat . ":" . $nameOutputDir . "/full",
+                               "--maxtime=1" /*This is in minutes. Fixup is below*/,
+                               "--checkpointfile=checkpoint-%s-%s.xml.gz" ) );
                        $dumper->setDb( $this->db );
                        $dumper->maxTimeAllowed = $checkpointAfter; // Patching maxTime from 1 minute
                        $dumper->stderr = $stderr;
@@ -283,7 +283,7 @@ class TextPassDumperTest extends DumpTestCase {
 
                                $this->assertLessThan( 50000, $iterations,
                                        "Emergency stop against infinitely increasing iteration "
-                                       . "count ( last duration: $lastDuration )" );
+                                               . "count ( last duration: $lastDuration )" );
                        }
                }
 
@@ -300,11 +300,11 @@ class TextPassDumperTest extends DumpTestCase {
 
                // Each run of the following loop body tries to handle exactly 1 /page/ (not
                // iteration of stub content). $i is only increased after having treated page 4.
-               for ( $i = 0 ; $i < $iterations ; ) {
+               for ( $i = 0; $i < $iterations; ) {
 
                        // 1. Assuring a file is opened and ready. Skipping across header if
                        //    necessary.
-                       if ( ! $fileOpened ) {
+                       if ( !$fileOpened ) {
                                $this->assertNotEmpty( $files, "No more existing dump files, "
                                        . "but not yet all pages found" );
                                $fname = array_shift( $files );
@@ -323,65 +323,65 @@ class TextPassDumperTest extends DumpTestCase {
 
                        // 2. Performing a single page check
                        switch ( $lookingForPage ) {
-                       case 1:
-                               // Page 1
-                               $this->assertPageStart( $this->pageId1 + $i * self::$numOfPages, NS_MAIN,
-                                       "BackupDumperTestP1" );
-                               $this->assertRevision( $this->revId1_1 + $i * self::$numOfRevs, "BackupDumperTestP1Summary1",
-                                       $this->textId1_1, false, "0bolhl6ol7i6x0e7yq91gxgaan39j87",
-                                       "BackupDumperTestP1Text1" );
-                               $this->assertPageEnd();
-
-                               $lookingForPage = 2;
-                               break;
-
-                       case 2:
-                               // Page 2
-                               $this->assertPageStart( $this->pageId2 + $i * self::$numOfPages, NS_MAIN,
-                                       "BackupDumperTestP2" );
-                               $this->assertRevision( $this->revId2_1 + $i * self::$numOfRevs, "BackupDumperTestP2Summary1",
-                                       $this->textId2_1, false, "jprywrymfhysqllua29tj3sc7z39dl2",
-                                       "BackupDumperTestP2Text1" );
-                               $this->assertRevision( $this->revId2_2 + $i * self::$numOfRevs, "BackupDumperTestP2Summary2",
-                                       $this->textId2_2, false, "b7vj5ks32po5m1z1t1br4o7scdwwy95",
-                                       "BackupDumperTestP2Text2", $this->revId2_1 + $i * self::$numOfRevs );
-                               $this->assertRevision( $this->revId2_3 + $i * self::$numOfRevs, "BackupDumperTestP2Summary3",
-                                       $this->textId2_3, false, "jfunqmh1ssfb8rs43r19w98k28gg56r",
-                                       "BackupDumperTestP2Text3", $this->revId2_2 + $i * self::$numOfRevs );
-                               $this->assertRevision( $this->revId2_4 + $i * self::$numOfRevs,
-                                       "BackupDumperTestP2Summary4 extra",
-                                       $this->textId2_4, false, "6o1ciaxa6pybnqprmungwofc4lv00wv",
-                                       "BackupDumperTestP2Text4 some additional Text",
-                                       $this->revId2_3 + $i * self::$numOfRevs );
-                               $this->assertPageEnd();
-
-                               $lookingForPage = 4;
-                               break;
-
-                       case 4:
-                               // Page 4
-                               $this->assertPageStart( $this->pageId4 + $i * self::$numOfPages, NS_TALK,
-                                       "Talk:BackupDumperTestP1" );
-                               $this->assertRevision( $this->revId4_1 + $i * self::$numOfRevs,
-                                       "Talk BackupDumperTestP1 Summary1",
-                                       $this->textId4_1, false, "nktofwzd0tl192k3zfepmlzxoax1lpe",
-                                       "Talk about BackupDumperTestP1 Text1" );
-                               $this->assertPageEnd();
-
-                               $lookingForPage = 1;
-
-                               // We dealt with the whole iteration.
-                               $i++;
-                               break;
-
-                       default:
-                               $this->fail( "Bad setting for lookingForPage ($lookingForPage)" );
+                               case 1:
+                                       // Page 1
+                                       $this->assertPageStart( $this->pageId1 + $i * self::$numOfPages, NS_MAIN,
+                                               "BackupDumperTestP1" );
+                                       $this->assertRevision( $this->revId1_1 + $i * self::$numOfRevs, "BackupDumperTestP1Summary1",
+                                               $this->textId1_1, false, "0bolhl6ol7i6x0e7yq91gxgaan39j87",
+                                               "BackupDumperTestP1Text1" );
+                                       $this->assertPageEnd();
+
+                                       $lookingForPage = 2;
+                                       break;
+
+                               case 2:
+                                       // Page 2
+                                       $this->assertPageStart( $this->pageId2 + $i * self::$numOfPages, NS_MAIN,
+                                               "BackupDumperTestP2" );
+                                       $this->assertRevision( $this->revId2_1 + $i * self::$numOfRevs, "BackupDumperTestP2Summary1",
+                                               $this->textId2_1, false, "jprywrymfhysqllua29tj3sc7z39dl2",
+                                               "BackupDumperTestP2Text1" );
+                                       $this->assertRevision( $this->revId2_2 + $i * self::$numOfRevs, "BackupDumperTestP2Summary2",
+                                               $this->textId2_2, false, "b7vj5ks32po5m1z1t1br4o7scdwwy95",
+                                               "BackupDumperTestP2Text2", $this->revId2_1 + $i * self::$numOfRevs );
+                                       $this->assertRevision( $this->revId2_3 + $i * self::$numOfRevs, "BackupDumperTestP2Summary3",
+                                               $this->textId2_3, false, "jfunqmh1ssfb8rs43r19w98k28gg56r",
+                                               "BackupDumperTestP2Text3", $this->revId2_2 + $i * self::$numOfRevs );
+                                       $this->assertRevision( $this->revId2_4 + $i * self::$numOfRevs,
+                                               "BackupDumperTestP2Summary4 extra",
+                                               $this->textId2_4, false, "6o1ciaxa6pybnqprmungwofc4lv00wv",
+                                               "BackupDumperTestP2Text4 some additional Text",
+                                               $this->revId2_3 + $i * self::$numOfRevs );
+                                       $this->assertPageEnd();
+
+                                       $lookingForPage = 4;
+                                       break;
+
+                               case 4:
+                                       // Page 4
+                                       $this->assertPageStart( $this->pageId4 + $i * self::$numOfPages, NS_TALK,
+                                               "Talk:BackupDumperTestP1" );
+                                       $this->assertRevision( $this->revId4_1 + $i * self::$numOfRevs,
+                                               "Talk BackupDumperTestP1 Summary1",
+                                               $this->textId4_1, false, "nktofwzd0tl192k3zfepmlzxoax1lpe",
+                                               "Talk about BackupDumperTestP1 Text1" );
+                                       $this->assertPageEnd();
+
+                                       $lookingForPage = 1;
+
+                                       // We dealt with the whole iteration.
+                                       $i++;
+                                       break;
+
+                               default:
+                                       $this->fail( "Bad setting for lookingForPage ($lookingForPage)" );
                        }
 
                        // 3. Checking for the end of the current checkpoint file
                        if ( $this->xml->nodeType == XMLReader::END_ELEMENT
-                               && $this->xml->name == "mediawiki" ) {
-
+                               && $this->xml->name == "mediawiki"
+                       ) {
                                $this->assertDumpEnd();
                                $fileOpened = false;
                        }
@@ -578,8 +578,7 @@ class TextPassDumperTest extends DumpTestCase {
                }
                $content .= $tail;
                $this->assertEquals( strlen( $content ), file_put_contents(
-                               $fname, $content ), "Length of prepared stub" );
+                       $fname, $content ), "Length of prepared stub" );
                return $fname;
        }
-
 }
index afd8f43..5cf172e 100644 (file)
@@ -28,18 +28,18 @@ class BackupDumperLoggerTest extends DumpTestCase {
         * @return int id of the added log entry
         */
        private function addLogEntry( $type, $subtype, User $user, $ns, $title,
-               $comment = null, $parameters = null ) {
-
-                $logEntry = new ManualLogEntry( $type, $subtype );
+               $comment = null, $parameters = null
+       ) {
+               $logEntry = new ManualLogEntry( $type, $subtype );
                $logEntry->setPerformer( $user );
                $logEntry->setTarget( Title::newFromText( $title, $ns ) );
-                if ( $comment !== null ) {
+               if ( $comment !== null ) {
                        $logEntry->setComment( $comment );
                }
-                if ( $parameters !== null ) {
+               if ( $parameters !== null ) {
                        $logEntry->setParameters( $parameters );
                }
-                return $logEntry->insert();
+               return $logEntry->insert();
        }
 
        function addDBData() {
@@ -73,7 +73,7 @@ class BackupDumperLoggerTest extends DumpTestCase {
 
                        $this->logId3 = $this->addLogEntry( 'move', 'delete',
                                $user2, NS_MAIN, "PageA", "SomeOtherComment",
-                               array( 'key1' => 1,  3 => 'value3' ) );
+                               array( 'key1' => 1, 3 => 'value3' ) );
                        $this->assertGreaterThan( 0, $this->logId3 );
 
                } catch ( Exception $e ) {
@@ -101,7 +101,8 @@ class BackupDumperLoggerTest extends DumpTestCase {
         * @param $parameters array: (optional) unserialized data accompanying the log entry
         */
        private function assertLogItem( $id, $user_name, $user_id, $comment, $type,
-               $subtype, $title, $parameters = array() ) {
+               $subtype, $title, $parameters = array()
+       ) {
 
                $this->assertNodeStart( "logitem" );
                $this->skipWhitespace();
@@ -134,12 +135,12 @@ class BackupDumperLoggerTest extends DumpTestCase {
                $this->skipWhitespace();
        }
 
-       function testPlain () {
+       function testPlain() {
                global $wgContLang;
 
                // Preparing the dump
                $fname = $this->getNewTempFile();
-               $dumper = new BackupDumper( array ( "--output=file:" . $fname ) );
+               $dumper = new BackupDumper( array( "--output=file:" . $fname ) );
                $dumper->startId = $this->logId1;
                $dumper->endId = $this->logId3 + 1;
                $dumper->reporting = false;
@@ -176,8 +177,8 @@ class BackupDumperLoggerTest extends DumpTestCase {
 
                // Preparing the dump
                $fname = $this->getNewTempFile();
-               $dumper = new BackupDumper( array ( "--output=gzip:" . $fname,
-                               "--reporting=2" ) );
+               $dumper = new BackupDumper( array( "--output=gzip:" . $fname,
+                       "--reporting=2" ) );
                $dumper->startId = $this->logId1;
                $dumper->endId = $this->logId3 + 1;
                $dumper->setDb( $this->db );
index d7f2feb..07c7670 100644 (file)
@@ -23,7 +23,7 @@ class BackupDumperPageTest extends DumpTestCase {
                $this->setMwGlobals( array(
                        'wgLanguageCode' => 'en',
                        'wgContLang' => Language::factory( 'en' ),
-               ));
+               ) );
 
                $this->tablesUsed[] = 'page';
                $this->tablesUsed[] = 'revision';
@@ -36,7 +36,7 @@ class BackupDumperPageTest extends DumpTestCase {
                        if ( $this->namespace === $this->talk_namespace ) {
                                //@todo: work around this.
                                throw new MWException( "The default wikitext namespace is the talk namespace. "
-                                       . " We can't currently deal with that.");
+                                       . " We can't currently deal with that." );
                        }
 
                        $this->pageTitle1 = Title::newFromText( 'BackupDumperTestP1', $this->namespace );
@@ -96,10 +96,10 @@ class BackupDumperPageTest extends DumpTestCase {
 
        }
 
-       function testFullTextPlain () {
+       function testFullTextPlain() {
                // Preparing the dump
                $fname = $this->getNewTempFile();
-               $dumper = new BackupDumper( array ( "--output=file:" . $fname ) );
+               $dumper = new BackupDumper( array( "--output=file:" . $fname ) );
                $dumper->startId = $this->pageId1;
                $dumper->endId = $this->pageId4 + 1;
                $dumper->reporting = false;
@@ -147,10 +147,10 @@ class BackupDumperPageTest extends DumpTestCase {
                $this->assertDumpEnd();
        }
 
-       function testFullStubPlain () {
+       function testFullStubPlain() {
                // Preparing the dump
                $fname = $this->getNewTempFile();
-               $dumper = new BackupDumper( array ( "--output=file:" . $fname ) );
+               $dumper = new BackupDumper( array( "--output=file:" . $fname ) );
                $dumper->startId = $this->pageId1;
                $dumper->endId = $this->pageId4 + 1;
                $dumper->reporting = false;
@@ -192,10 +192,10 @@ class BackupDumperPageTest extends DumpTestCase {
                $this->assertDumpEnd();
        }
 
-       function testCurrentStubPlain () {
+       function testCurrentStubPlain() {
                // Preparing the dump
                $fname = $this->getNewTempFile();
-               $dumper = new BackupDumper( array ( "--output=file:" . $fname ) );
+               $dumper = new BackupDumper( array( "--output=file:" . $fname ) );
                $dumper->startId = $this->pageId1;
                $dumper->endId = $this->pageId4 + 1;
                $dumper->reporting = false;
@@ -231,12 +231,12 @@ class BackupDumperPageTest extends DumpTestCase {
                $this->assertDumpEnd();
        }
 
-       function testCurrentStubGzip () {
+       function testCurrentStubGzip() {
                $this->checkHasGzip();
 
                // Preparing the dump
                $fname = $this->getNewTempFile();
-               $dumper = new BackupDumper( array ( "--output=gzip:" . $fname ) );
+               $dumper = new BackupDumper( array( "--output=gzip:" . $fname ) );
                $dumper->startId = $this->pageId1;
                $dumper->endId = $this->pageId4 + 1;
                $dumper->reporting = false;
@@ -274,8 +274,7 @@ class BackupDumperPageTest extends DumpTestCase {
        }
 
 
-
-       function testXmlDumpsBackupUseCase () {
+       function testXmlDumpsBackupUseCase() {
                // xmldumps-backup typically performs a single dump that that writes
                // out three files
                // * gzipped stubs of everything (meta-history)
@@ -292,11 +291,11 @@ class BackupDumperPageTest extends DumpTestCase {
                $fnameMetaCurrent = $this->getNewTempFile();
                $fnameArticles = $this->getNewTempFile();
 
-               $dumper = new BackupDumper( array ( "--output=gzip:" . $fnameMetaHistory,
-                               "--output=gzip:" . $fnameMetaCurrent, "--filter=latest",
-                               "--output=gzip:" . $fnameArticles, "--filter=latest",
-                               "--filter=notalk", "--filter=namespace:!NS_USER",
-                               "--reporting=1000" ) );
+               $dumper = new BackupDumper( array( "--output=gzip:" . $fnameMetaHistory,
+                       "--output=gzip:" . $fnameMetaCurrent, "--filter=latest",
+                       "--output=gzip:" . $fnameArticles, "--filter=latest",
+                       "--filter=notalk", "--filter=namespace:!NS_USER",
+                       "--reporting=1000" ) );
                $dumper->startId = $this->pageId1;
                $dumper->endId = $this->pageId4 + 1;
                $dumper->setDb( $this->db );
@@ -406,5 +405,4 @@ class BackupDumperPageTest extends DumpTestCase {
        }
 
 
-
 }
index 04536f8..4d1d45d 100644 (file)
@@ -26,7 +26,6 @@ class SemiMockedFetchText extends FetchText {
        private $mockInvocations = array( 'getStdin' => 0 );
 
 
-
        /**
         * Data for the fake stdin
         *
@@ -57,7 +56,7 @@ class SemiMockedFetchText extends FetchText {
                                "Tried to get stdin with non null parameter" );
                }
 
-               if ( ! $this->mockSetUp ) {
+               if ( !$this->mockSetUp ) {
                        throw new PHPUnit_Framework_ExpectationFailedException(
                                "Tried to get stdin before setting up rerouting" );
                }
@@ -172,7 +171,6 @@ class FetchTextTest extends MediaWikiTestCase {
        }
 
 
-
        // Instead of the following functions, a data provider would be great.
        // However, as data providers are evaluated /before/ addDBData, a data
        // provider would not know the required ids.
@@ -189,14 +187,14 @@ class FetchTextTest extends MediaWikiTestCase {
 
        function testExistingSeveral() {
                $this->assertFilter( "$this->textId1\n$this->textId5\n"
-                       . "$this->textId3\n$this->textId3",
+                               . "$this->textId3\n$this->textId3",
                        implode( "", array(
-                                       $this->textId1 . "\n23\nFetchTextTestPage1Text1",
-                                       $this->textId5 . "\n44\nFetchTextTestPage2Text4 "
+                               $this->textId1 . "\n23\nFetchTextTestPage1Text1",
+                               $this->textId5 . "\n44\nFetchTextTestPage2Text4 "
                                        . "some additional Text",
-                                       $this->textId3 . "\n23\nFetchTextTestPage2Text2",
-                                       $this->textId3 . "\n23\nFetchTextTestPage2Text2"
-                               ) ) );
+                               $this->textId3 . "\n23\nFetchTextTestPage2Text2",
+                               $this->textId3 . "\n23\nFetchTextTestPage2Text2"
+                       ) ) );
        }
 
        function testEmpty() {
@@ -228,15 +226,15 @@ class FetchTextTest extends MediaWikiTestCase {
 
        function testMix() {
                $this->assertFilter( "ab\n" . $this->textId4 . ".5cd\n\nefg\n" . $this->textId2
-                       . "\n" . $this->textId3,
+                               . "\n" . $this->textId3,
                        implode( "", array(
-                                       "0\n-1\n",
-                                       $this->textId4 . "\n23\nFetchTextTestPage2Text3",
-                                       "0\n-1\n",
-                                       "0\n-1\n",
-                                       $this->textId2 . "\n23\nFetchTextTestPage2Text1",
-                                       $this->textId3 . "\n23\nFetchTextTestPage2Text2"
-                               ) ) );
+                               "0\n-1\n",
+                               $this->textId4 . "\n23\nFetchTextTestPage2Text3",
+                               "0\n-1\n",
+                               "0\n-1\n",
+                               $this->textId2 . "\n23\nFetchTextTestPage2Text1",
+                               $this->textId3 . "\n23\nFetchTextTestPage2Text2"
+                       ) ) );
        }
 
 }
index bcbf4ec..2a0298a 100755 (executable)
@@ -21,10 +21,10 @@ class PHPUnitMaintClass extends Maintenance {
 
        function __construct() {
                parent::__construct();
-               $this->addOption( 'with-phpunitdir'
-                       , 'Directory to include PHPUnit from, for example when using a git fetchout from upstream. Path will be prepended to PHP `include_path`.'
-                       , false # not required
-                       , true  # need arg
+               $this->addOption( 'with-phpunitdir',
+                       'Directory to include PHPUnit from, for example when using a git fetchout from upstream. Path will be prepended to PHP `include_path`.',
+                       false, # not required
+                       true # need arg
                );
        }
 
@@ -49,26 +49,26 @@ class PHPUnitMaintClass extends Maintenance {
                // Assume UTC for testing purposes
                $wgLocaltimezone = 'UTC';
 
-               $wgLocalisationCacheConf['storeClass'] =  'LCStore_Null';
+               $wgLocalisationCacheConf['storeClass'] = 'LCStore_Null';
        }
 
        public function execute() {
                global $IP;
 
                # Make sure we have --configuration or PHPUnit might complain
-               if( !in_array( '--configuration', $_SERVER['argv'] ) ) {
+               if ( !in_array( '--configuration', $_SERVER['argv'] ) ) {
                        //Hack to eliminate the need to use the Makefile (which sucks ATM)
                        array_splice( $_SERVER['argv'], 1, 0,
                                array( '--configuration', $IP . '/tests/phpunit/suite.xml' ) );
                }
 
                # --with-phpunitdir let us override the default PHPUnit version
-               if( $phpunitDir = $this->getOption( 'with-phpunitdir' ) ) {
+               if ( $phpunitDir = $this->getOption( 'with-phpunitdir' ) ) {
                        # Sanity checks
-                       if( !is_dir($phpunitDir) ) {
+                       if ( !is_dir( $phpunitDir ) ) {
                                $this->error( "--with-phpunitdir should be set to an existing directory", 1 );
                        }
-                       if( !is_readable( $phpunitDir."/PHPUnit/Runner/Version.php" ) ) {
+                       if ( !is_readable( $phpunitDir . "/PHPUnit/Runner/Version.php" ) ) {
                                $this->error( "No usable PHPUnit installation in $phpunitDir.\nAborting.\n", 1 );
                        }
 
@@ -80,8 +80,8 @@ class PHPUnitMaintClass extends Maintenance {
                        # Cleanup $args array so the option and its value do not
                        # pollute PHPUnit
                        $key = array_search( '--with-phpunitdir', $_SERVER['argv'] );
-                       unset( $_SERVER['argv'][$key]   ); // the option
-                       unset( $_SERVER['argv'][$key+1] ); // its value
+                       unset( $_SERVER['argv'][$key] ); // the option
+                       unset( $_SERVER['argv'][$key + 1] ); // its value
                        $_SERVER['argv'] = array_values( $_SERVER['argv'] );
 
                }
@@ -97,8 +97,9 @@ require( RUN_MAINTENANCE_IF_MAIN );
 
 require_once( 'PHPUnit/Runner/Version.php' );
 
-if( PHPUnit_Runner_Version::id() !== '@package_version@'
-   && version_compare( PHPUnit_Runner_Version::id(), '3.6.7', '<' ) ) {
+if ( PHPUnit_Runner_Version::id() !== '@package_version@'
+       && version_compare( PHPUnit_Runner_Version::id(), '3.6.7', '<' )
+) {
        die( 'PHPUnit 3.6.7 or later required, you have ' . PHPUnit_Runner_Version::id() . ".\n" );
 }
 require_once( 'PHPUnit/Autoload.php' );
index 18db399..71b8c67 100644 (file)
@@ -62,7 +62,7 @@ class ResourcesTest extends MediaWikiTestCase {
 
                foreach ( $rl->getModuleNames() as $moduleName ) {
                        $module = $rl->getModule( $moduleName );
-                       if ( ! $module instanceof ResourceLoaderFileModule ) {
+                       if ( !$module instanceof ResourceLoaderFileModule ) {
                                continue;
                        }
 
index 85ed0b4..3902b68 100644 (file)
@@ -22,8 +22,8 @@ class SideBarTest extends MediaWikiLangTestCase {
                        'helppage',
                );
 
-               foreach( $URL_messages as $m ) {
-                       $titleName = MessageCache::singleton()->get($m);
+               foreach ( $URL_messages as $m ) {
+                       $titleName = MessageCache::singleton()->get( $m );
                        $title = Title::newFromText( $titleName );
                        $this->messages[$m]['href'] = $title->getLocalURL();
                }
@@ -35,6 +35,7 @@ class SideBarTest extends MediaWikiLangTestCase {
                $this->skin = new SkinTemplate();
                $this->skin->getContext()->setLanguage( Language::factory( 'en' ) );
        }
+
        protected function tearDown() {
                parent::tearDown();
                $this->skin = null;
@@ -54,11 +55,11 @@ class SideBarTest extends MediaWikiLangTestCase {
 
        function testSidebarWithOnlyTwoTitles() {
                $this->assertSideBar(
-               array(
-                       'Title1' => array(),
-                       'Title2' => array(),
-               ),
-'* Title1
+                       array(
+                               'Title1' => array(),
+                               'Title2' => array(),
+                       ),
+                       '* Title1
 * Title2
 '
                );
@@ -66,15 +67,15 @@ class SideBarTest extends MediaWikiLangTestCase {
 
        function testExpandMessages() {
                $this->assertSidebar(
-               array( 'Title' => array(
-                       array(
-                               'text' => 'Help',
-                               'href' => $this->messages['helppage']['href'],
-                               'id' => 'n-help',
-                               'active' => null
-                       )
-               )),
-'* Title
+                       array( 'Title' => array(
+                               array(
+                                       'text' => 'Help',
+                                       'href' => $this->messages['helppage']['href'],
+                                       'id' => 'n-help',
+                                       'active' => null
+                               )
+                       ) ),
+                       '* Title
 ** helppage|help
 '
                );
@@ -82,63 +83,62 @@ class SideBarTest extends MediaWikiLangTestCase {
 
        function testExternalUrlsRequireADescription() {
                $this->assertSidebar(
-               array( 'Title' => array(
-                       # ** http://www.mediawiki.org/| Home
-                       array(
-                               'text'   => 'Home',
-                               'href'   => 'http://www.mediawiki.org/',
-                               'id'     => 'n-Home',
-                               'active' => null,
-                               'rel'    => 'nofollow',
-                       ),
-                       # ** http://valid.no.desc.org/
-                       # ... skipped since it is missing a pipe with a description
-               )),
-'* Title
+                       array( 'Title' => array(
+                               # ** http://www.mediawiki.org/| Home
+                               array(
+                                       'text' => 'Home',
+                                       'href' => 'http://www.mediawiki.org/',
+                                       'id' => 'n-Home',
+                                       'active' => null,
+                                       'rel' => 'nofollow',
+                               ),
+                               # ** http://valid.no.desc.org/
+                               # ... skipped since it is missing a pipe with a description
+                       ) ),
+                       '* Title
 ** http://www.mediawiki.org/| Home
 ** http://valid.no.desc.org/
 '
-
                );
 
        }
+
        /**
         * bug 33321 - Make sure there's a | after transforming.
         * @group Database
         */
        function testTrickyPipe() {
                $this->assertSidebar(
-               array( 'Title' => array(
-                       # The first 2 are skipped
-                       # Doesn't really test the url properly
-                       # because it will vary with $wgArticlePath et al.
-                       # ** Baz|Fred
-                       array(
-                               'text'   => 'Fred',
-                               'href'   => Title::newFromText( 'Baz' )->getLocalUrl(),
-                               'id'     => 'n-Fred',
-                               'active' => null,
-                       ),
-                       array(
-                               'text'   => 'title-to-display',
-                               'href'   => Title::newFromText( 'page-to-go-to' )->getLocalUrl(),
-                               'id'     => 'n-title-to-display',
-                               'active' => null,
-                       ),
-               )),
-'* Title
+                       array( 'Title' => array(
+                               # The first 2 are skipped
+                               # Doesn't really test the url properly
+                               # because it will vary with $wgArticlePath et al.
+                               # ** Baz|Fred
+                               array(
+                                       'text' => 'Fred',
+                                       'href' => Title::newFromText( 'Baz' )->getLocalUrl(),
+                                       'id' => 'n-Fred',
+                                       'active' => null,
+                               ),
+                               array(
+                                       'text' => 'title-to-display',
+                                       'href' => Title::newFromText( 'page-to-go-to' )->getLocalUrl(),
+                                       'id' => 'n-title-to-display',
+                                       'active' => null,
+                               ),
+                       ) ),
+                       '* Title
 ** {{PAGENAME|Foo}}
 ** Bar
 ** Baz|Fred
 ** {{PLURAL:1|page-to-go-to{{int:pipe-separator/en}}title-to-display|branch not taken}}
 '
                );
-
        }
 
 
        #### Attributes for external links ##########################
-       private function getAttribs( ) {
+       private function getAttribs() {
                # Sidebar text we will use everytime
                $text = '* Title
 ** http://www.mediawiki.org/| Home';
index d728807..eec773d 100644 (file)
@@ -1,4 +1,4 @@
-<?php 
+<?php
 /**
  * This test suite runs unit tests registered by extensions.
  * See http://www.mediawiki.org/wiki/Manual:Hooks/UnitTestsList for details of how to register your tests.
index 366d8f2..28d38ab 100644 (file)
@@ -17,8 +17,8 @@ class UploadFromUrlTestSuite extends PHPUnit_Framework_TestSuite {
 
        protected function setUp() {
                global $wgParser, $wgParserConf, $IP, $messageMemc, $wgMemc,
-                         $wgUser, $wgLang, $wgOut, $wgRequest, $wgStyleDirectory, $wgEnableParserCache,
-                         $wgNamespaceAliases, $wgNamespaceProtection, $parserMemc;
+                       $wgUser, $wgLang, $wgOut, $wgRequest, $wgStyleDirectory, $wgEnableParserCache,
+                       $wgNamespaceAliases, $wgNamespaceProtection, $parserMemc;
 
                $tmpGlobals = array();
 
@@ -29,18 +29,18 @@ class UploadFromUrlTestSuite extends PHPUnit_Framework_TestSuite {
                $tmpGlobals['wgStylePath'] = '/skins';
                $tmpGlobals['wgThumbnailScriptPath'] = false;
                $tmpGlobals['wgLocalFileRepo'] = array(
-                       'class'           => 'LocalRepo',
-                       'name'            => 'local',
-                       'url'             => 'http://example.com/images',
-                       'hashLevels'      => 2,
+                       'class' => 'LocalRepo',
+                       'name' => 'local',
+                       'url' => 'http://example.com/images',
+                       'hashLevels' => 2,
                        'transformVia404' => false,
-                       'backend'         => new FSFileBackend( array(
-                               'name'        => 'local-backend',
+                       'backend' => new FSFileBackend( array(
+                               'name' => 'local-backend',
                                'lockManager' => 'fsLockManager',
                                'containerPaths' => array(
-                                       'local-public'  => wfTempDir() . '/test-repo/public',
-                                       'local-thumb'   => wfTempDir() . '/test-repo/thumb',
-                                       'local-temp'    => wfTempDir() . '/test-repo/temp',
+                                       'local-public' => wfTempDir() . '/test-repo/public',
+                                       'local-thumb' => wfTempDir() . '/test-repo/thumb',
+                                       'local-temp' => wfTempDir() . '/test-repo/temp',
                                        'local-deleted' => wfTempDir() . '/test-repo/delete',
                                )
                        ) ),
@@ -72,7 +72,7 @@ class UploadFromUrlTestSuite extends PHPUnit_Framework_TestSuite {
                $wgRequest = $context->getRequest();
 
                if ( $wgStyleDirectory === false ) {
-                       $wgStyleDirectory   = "$IP/skins";
+                       $wgStyleDirectory = "$IP/skins";
                }
 
                RepoGroup::destroySingleton();
@@ -105,7 +105,7 @@ class UploadFromUrlTestSuite extends PHPUnit_Framework_TestSuite {
 
                // delete the files first, then the dirs.
                self::deleteFiles(
-                       array (
+                       array(
                                "$dir/3/3a/Foobar.jpg",
                                "$dir/thumb/3/3a/Foobar.jpg/180px-Foobar.jpg",
                                "$dir/thumb/3/3a/Foobar.jpg/200px-Foobar.jpg",
@@ -117,7 +117,7 @@ class UploadFromUrlTestSuite extends PHPUnit_Framework_TestSuite {
                );
 
                self::deleteDirs(
-                       array (
+                       array(
                                "$dir/3/3a",
                                "$dir/3",
                                "$dir/thumb/6/65",
index 911dc3a..774000b 100644 (file)
@@ -85,9 +85,9 @@ class GenerateJqueryMsgData extends Maintenance {
        );
 
        public function __construct() {
-                       parent::__construct();
-                       $this->mDescription = 'Create a specification for message parsing ini JSON format';
-                       // add any other options here
+               parent::__construct();
+               $this->mDescription = 'Create a specification for message parsing ini JSON format';
+               // add any other options here
        }
 
        public function execute() {
@@ -100,7 +100,7 @@ class GenerateJqueryMsgData extends Maintenance {
                $tests = array();
                foreach ( array( 'en', 'fr', 'ar', 'jp', 'zh' ) as $languageCode ) {
                        foreach ( self::$keyToTestArgs as $key => $testArgs ) {
-                               foreach ($testArgs as $args) {
+                               foreach ( $testArgs as $args ) {
                                        // Get the raw message, without any transformations.
                                        $template = wfMessage( $key )->inLanguage( $languageCode )->plain();
 
@@ -132,14 +132,14 @@ class GenerateJqueryMsgData extends Maintenance {
 
                $output =
                        "// This file stores the output from the PHP parser for various messages, arguments,\n"
-                       . "// languages, and parser modes. Intended for use by a unit test framework by looping\n"
-                       . "// through the object and comparing its parser return value with the 'result' property.\n"
-                       . '// Last generated with ' . basename( __FILE__ ) . ' at ' . gmdate( 'r' ) . "\n"
-                       // This file will contain unquoted JSON strings as javascript native object literals,
-                       // flip the quotemark convention for this file.
-                       . "/*jshint quotmark: double */\n"
-                       . "\n"
-                       . 'mediaWiki.libs.phpParserData = ' . FormatJson::encode( $phpParserData, true ) . ";\n";
+                               . "// languages, and parser modes. Intended for use by a unit test framework by looping\n"
+                               . "// through the object and comparing its parser return value with the 'result' property.\n"
+                               . '// Last generated with ' . basename( __FILE__ ) . ' at ' . gmdate( 'r' ) . "\n"
+                               // This file will contain unquoted JSON strings as javascript native object literals,
+                               // flip the quotemark convention for this file.
+                               . "/*jshint quotmark: double */\n"
+                               . "\n"
+                               . 'mediaWiki.libs.phpParserData = ' . FormatJson::encode( $phpParserData, true ) . ";\n";
 
                $fp = file_put_contents( $dataSpecFile, $output );
                if ( $fp === false ) {
index 25c42d6..3ed5514 100644 (file)
@@ -1,2 +1,2 @@
 QUnit.start();
-QUnit.assert.ok( true, 'Successfully loaded!');
+QUnit.assert.ok( true, 'Successfully loaded!' );
index 1870d5a..0e84581 100644 (file)
@@ -47,9 +47,9 @@ $wait = isset( $params['wait'] ) ? (int)$params['wait'] : 0; // seconds
 
 sleep( $wait );
 
-$css =  "
+$css = "
 /**
- * Generated " . gmdate( 'r' ) .  ".
+ * Generated " . gmdate( 'r' ) . ".
  * Waited {$wait}s.
  */
 
index 0c3d364..c89656d 100644 (file)
@@ -52,7 +52,7 @@
        /**
         * CompletenessTest
         */
-       // Adds toggle checkbox to header
+        // Adds toggle checkbox to header
        QUnit.config.urlConfig.push( {
                id: 'completenesstest',
                label: 'Run CompletenessTest',
@@ -92,7 +92,7 @@
        /**
         * Test environment recommended for all QUnit test modules
         */
-       // Whether to log environment changes to the console
+        // Whether to log environment changes to the console
        QUnit.config.urlConfig.push( 'mwlogenv' );
 
        /**
                        // e.g. mw.config.set( 'wgFileExtensions', [] ) would not effect liveConfig,
                        // but mw.config.get( 'wgFileExtensions' ).push( 'png' ) would as the array
                        // was passed by reference in $.extend's loop.
-                       return $.extend( {}, liveConfig, custom, /*deep=*/true );
+                       return $.extend( /*deep=*/true, {}, liveConfig, custom );
                }
 
                function freshMessagesCopy( custom ) {
-                       return $.extend( {}, liveMessages, custom, /*deep=*/true );
+                       return $.extend( /*deep=*/true, {}, liveMessages, custom );
                }
 
                log = QUnit.urlParams.mwlogenv ? mw.log : function () {};
                        // Whether this one fails or not, forwards it to
                        // the 'done' (resolve) callback of the alternative promise.
                        arg.always( alt.resolve );
-               });
+               } );
 
                return $.when.apply( $, altPromises );
        };
         * initializations defined above in this file.
         */
        envExecCount = 0;
-       QUnit.module( 'mediawiki.tests.qunit.testrunner', QUnit.newMwEnvironment({
+       QUnit.module( 'mediawiki.tests.qunit.testrunner', QUnit.newMwEnvironment( {
                setup: function () {
                        envExecCount += 1;
                        this.mwHtmlLive = mw.html;
                messages: {
                        testMsg: 'Foo.'
                }
-       }) );
+       } ) );
 
        QUnit.test( 'Setup', 3, function ( assert ) {
                assert.equal( mw.html.escape( 'foo' ), 'mocked-1', 'extra setup() callback was ran.' );
 
                mw.config.set( 'testVar', 'bar' );
                mw.messages.set( 'testMsg', 'Bar.' );
-       });
+       } );
 
        QUnit.test( 'Teardown', 3, function ( assert ) {
                assert.equal( mw.html.escape( 'foo' ), 'mocked-2', 'extra setup() callback was re-ran.' );
                assert.equal( mw.config.get( 'testVar' ), 'foo', 'config object restored and re-applied after test()' );
                assert.equal( mw.messages.get( 'testMsg' ), 'Foo.', 'messages object restored and re-applied after test()' );
-       });
+       } );
 
        QUnit.module( 'mediawiki.tests.qunit.testrunner-after', QUnit.newMwEnvironment() );
 
                assert.equal( mw.html.escape( '<' ), '&lt;', 'extra teardown() callback was ran.' );
                assert.equal( mw.config.get( 'testVar' ), null, 'config object restored to live in next module()' );
                assert.equal( mw.messages.get( 'testMsg' ), null, 'messages object restored to live in next module()' );
-       });
+       } );
 
 }( jQuery, mediaWiki, QUnit ) );
index feeec55..e189524 100644 (file)
@@ -53,6 +53,6 @@
                } else {
                        assert.gt( $span.width(), $span.parent().width(), 'Fit is maximal (adding two characters makes it not fit any more)' );
                }
-       });
+       } );
 
 }( jQuery ) );
index 378ea4b..e4e579b 100644 (file)
@@ -2,7 +2,7 @@
        QUnit.module( 'jquery.byteLength', QUnit.newMwEnvironment() );
 
        QUnit.test( 'Simple text', 5, function ( assert ) {
-               var     azLc = 'abcdefghijklmnopqrstuvwxyz',
+               var azLc = 'abcdefghijklmnopqrstuvwxyz',
                        azUc = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ',
                        num = '0123456789',
                        x = '*',
index 2990de2..c21844e 100644 (file)
        // Basic sendkey-implementation
        function addChars( $input, charstr ) {
                var c, len;
+
                function x( $input, i ) {
                        // Add character to the value
                        return $input.val() + charstr.charAt( i );
                }
+
                for ( c = 0, len = charstr.length; c < len; c += 1 ) {
                        $input
                                .val( x( $input, c ) )
         * The limit should be less than 20 (the sample data's length)
         */
        function byteLimitTest( options ) {
-               var opt = $.extend({
+               var opt = $.extend( {
                        description: '',
                        $input: null,
                        sample: '',
                        hasLimit: false,
                        expected: '',
                        limit: null
-               }, options);
+               }, options );
 
                QUnit.asyncTest( opt.description, opt.hasLimit ? 3 : 2, function ( assert ) {
-               setTimeout( function () {
-                       var rawVal, fn, effectiveVal;
-
-                       opt.$input.appendTo( '#qunit-fixture' );
-
-                       // Simulate pressing keys for each of the sample characters
-                       addChars( opt.$input, opt.sample );
-
-                       rawVal = opt.$input.val();
-                       fn = opt.$input.data( 'byteLimit.callback' );
-                       effectiveVal = fn ? fn( rawVal ) : rawVal;
-
-                       if ( opt.hasLimit ) {
-                               assert.ltOrEq(
-                                       $.byteLength( effectiveVal ),
-                                       opt.limit,
-                                       'Prevent keypresses after byteLimit was reached, length never exceeded the limit'
-                               );
-                               assert.equal(
-                                       $.byteLength( rawVal ),
-                                       $.byteLength( opt.expected ),
-                                       'Not preventing keypresses too early, length has reached the expected length'
-                               );
-                               assert.equal( rawVal, opt.expected, 'New value matches the expected string' );
-
-                       } else {
-                               assert.equal(
-                                       $.byteLength( effectiveVal ),
-                                       $.byteLength( opt.expected ),
-                                       'Unlimited scenarios are not affected, expected length reached'
-                               );
-                               assert.equal( rawVal, opt.expected, 'New value matches the expected string' );
-                       }
-                       QUnit.start();
-               }, 10 );
+                       setTimeout( function () {
+                               var rawVal, fn, effectiveVal;
+
+                               opt.$input.appendTo( '#qunit-fixture' );
+
+                               // Simulate pressing keys for each of the sample characters
+                               addChars( opt.$input, opt.sample );
+
+                               rawVal = opt.$input.val();
+                               fn = opt.$input.data( 'byteLimit.callback' );
+                               effectiveVal = fn ? fn( rawVal ) : rawVal;
+
+                               if ( opt.hasLimit ) {
+                                       assert.ltOrEq(
+                                               $.byteLength( effectiveVal ),
+                                               opt.limit,
+                                               'Prevent keypresses after byteLimit was reached, length never exceeded the limit'
+                                       );
+                                       assert.equal(
+                                               $.byteLength( rawVal ),
+                                               $.byteLength( opt.expected ),
+                                               'Not preventing keypresses too early, length has reached the expected length'
+                                       );
+                                       assert.equal( rawVal, opt.expected, 'New value matches the expected string' );
+
+                               } else {
+                                       assert.equal(
+                                               $.byteLength( effectiveVal ),
+                                               $.byteLength( opt.expected ),
+                                               'Unlimited scenarios are not affected, expected length reached'
+                                       );
+                                       assert.equal( rawVal, opt.expected, 'New value matches the expected string' );
+                               }
+                               QUnit.start();
+                       }, 10 );
                } );
        }
 
-       byteLimitTest({
+       byteLimitTest( {
                description: 'Plain text input',
                $input: $( '<input type="text"/>' ),
                sample: simpleSample,
                hasLimit: false,
                expected: simpleSample
-       });
+       } );
 
-       byteLimitTest({
+       byteLimitTest( {
                description: 'Plain text input. Calling byteLimit with no parameters and no maxlength attribute (bug 36310)',
                $input: $( '<input type="text"/>' )
                        .byteLimit(),
                sample: simpleSample,
                hasLimit: false,
                expected: simpleSample
-       });
+       } );
 
-       byteLimitTest({
+       byteLimitTest( {
                description: 'Limit using the maxlength attribute',
                $input: $( '<input type="text"/>' )
                        .attr( 'maxlength', '10' )
                hasLimit: true,
                limit: 10,
                expected: '1234567890'
-       });
+       } );
 
-       byteLimitTest({
+       byteLimitTest( {
                description: 'Limit using a custom value',
                $input: $( '<input type="text"/>' )
                        .byteLimit( 10 ),
                hasLimit: true,
                limit: 10,
                expected: '1234567890'
-       });
+       } );
 
-       byteLimitTest({
+       byteLimitTest( {
                description: 'Limit using a custom value, overriding maxlength attribute',
                $input: $( '<input type="text"/>' )
                        .attr( 'maxlength', '10' )
                hasLimit: true,
                limit: 15,
                expected: '123456789012345'
-       });
+       } );
 
-       byteLimitTest({
+       byteLimitTest( {
                description: 'Limit using a custom value (multibyte)',
                $input: $( '<input type="text"/>' )
                        .byteLimit( 14 ),
                hasLimit: true,
                limit: 14,
                expected: '1234567890' + U_20AC + '1'
-       });
+       } );
 
-       byteLimitTest({
+       byteLimitTest( {
                description: 'Limit using a custom value (multibyte) overlapping a byte',
                $input: $( '<input type="text"/>' )
                        .byteLimit( 12 ),
                hasLimit: true,
                limit: 12,
                expected: '1234567890' + '12'
-       });
+       } );
 
-       byteLimitTest({
+       byteLimitTest( {
                description: 'Pass the limit and a callback as input filter',
                $input: $( '<input type="text"/>' )
                        .byteLimit( 6, function ( val ) {
                hasLimit: true,
                limit: 6, // 'Sample' length
                expected: 'User:Sample'
-       });
+       } );
 
-       byteLimitTest({
+       byteLimitTest( {
                description: 'Limit using the maxlength attribute and pass a callback as input filter',
                $input: $( '<input type="text"/>' )
                        .attr( 'maxlength', '6' )
                hasLimit: true,
                limit: 6, // 'Sample' length
                expected: 'User:Sample'
-       });
+       } );
 
        QUnit.test( 'Confirm properties and attributes set', 4, function ( assert ) {
                var $el, $elA, $elB;
                assert.strictEqual( $el.length, 2, 'Verify that there are no other elements clashing with this test suite' );
 
                $el.byteLimit();
-       });
+       } );
 
        QUnit.test( 'Trim from insertion when limit exceeded', 2, function ( assert ) {
                var $el;
                        .val( 'azbc' ).trigger( 'change' );
 
                assert.strictEqual( $el.val(), 'abc', 'Trim from the insertion point (at 1), not the end' );
-       });
-
+       } );
 }( jQuery, mediaWiki ) );
index 44aaefd..88bbf5c 100644 (file)
                };
                $.each( uas, function () {
                        uacount++;
-               });
+               } );
                return uas;
        }() );
 
        QUnit.test( 'profile userAgent support', uacount, function ( assert ) {
                // Generate a client profile object and compare recursively
-               var uaTest = function( rawUserAgent, data ) {
+               var uaTest = function ( rawUserAgent, data ) {
                        var ret = $.client.profile( {
                                userAgent: rawUserAgent,
                                platform: data.platform
 
        QUnit.test( 'profile return validation for current user agent', 7, function ( assert ) {
                var p = $.client.profile();
+
                function unknownOrType( val, type, summary ) {
                        assert.ok( typeof val === type || val === 'unknown', summary );
                }
                unknownOrType( p.version, 'string', 'p.version is a string (or "unknown")' );
                unknownOrType( p.versionBase, 'string', 'p.versionBase is a string (or "unknown")' );
                assert.equal( typeof p.versionNumber, 'number', 'p.versionNumber is a number' );
-       });
+       } );
 
        // Example from WikiEditor
        // Make sure to use raw numbers, a string like "7.0" would fail on a
 
                assert.equal( typeof testMatch, 'boolean', 'test returns a boolean value' );
 
-       });
+       } );
 
        QUnit.test( 'User-agent matches against WikiEditor\'s compatibility map', uacount * 2, function ( assert ) {
-               var     $body = $( 'body' ),
+               var $body = $( 'body' ),
                        bodyClasses = $body.attr( 'class' );
 
                // Loop through and run tests
                                $body.removeClass( dir );
 
                                assert.equal( testMatch, data.wikiEditor[dir], 'testing comparison based on ' + dir + ', ' + agent );
-                       });
-               });
+                       } );
+               } );
 
                // Restore body classes
                $body.attr( 'class', bodyClasses );
-       });
+       } );
 }( jQuery ) );
index 51a892e..97e0533 100644 (file)
@@ -24,7 +24,7 @@
                assert.deepEqual( $.colorUtil.getRGB( 'lightGreen' ), [144, 238, 144], 'Color names (lightGreen)' );
                assert.deepEqual( $.colorUtil.getRGB( 'transparent' ), [255, 255, 255], 'Color names (transparent)' );
                assert.strictEqual( $.colorUtil.getRGB( 'mediaWiki' ), undefined, 'Inexisting color name' );
-       });
+       } );
 
        QUnit.test( 'rgbToHsl', 1, function ( assert ) {
                var hsl, ret;
                function dualDecimals( a ) {
                        return Math.round( a * 100 ) / 100;
                }
+
                // Re-create the rgbToHsl return array items, limited to two decimals.
                hsl = $.colorUtil.rgbToHsl( 144, 238, 144 );
                ret = [ dualDecimals( hsl[0] ), dualDecimals( hsl[1] ), dualDecimals( hsl[2] ) ];
 
                assert.deepEqual( ret, [0.33, 0.73, 0.75], 'rgb(144, 238, 144): hsl(0.33, 0.73, 0.75)' );
-       });
+       } );
 
        QUnit.test( 'hslToRgb', 1, function ( assert ) {
                var rgb, ret;
                rgb = $.colorUtil.hslToRgb( 0.3, 0.7, 0.8 );
 
                // Re-create the hslToRgb return array items, rounded to whole numbers.
-               ret = [ Math.round(rgb[0]), Math.round(rgb[1]), Math.round(rgb[2]) ];
+               ret = [ Math.round( rgb[0] ), Math.round( rgb[1] ), Math.round( rgb[2] ) ];
 
-               assert.deepEqual( ret ,[183, 240, 168], 'hsl(0.3, 0.7, 0.8): rgb(183, 240, 168)' );
-       });
+               assert.deepEqual( ret[183, 240, 168], 'hsl(0.3, 0.7, 0.8): rgb(183, 240, 168)' );
+       } );
 
        QUnit.test( 'getColorBrightness', 2, function ( assert ) {
                var a, b;
@@ -58,5 +59,5 @@
 
                b = $.colorUtil.getColorBrightness( 'rgb(200,50,50)', -0.2 );
                assert.equal( b, 'rgb(118,29,29)', 'Start with rgb string "rgb(200,50,50)", darken 20%' );
-       });
+       } );
 }( jQuery ) );
index 3e7d5ff..234b19c 100644 (file)
@@ -1,37 +1,37 @@
 ( function ( $ ) {
-       QUnit.asyncTest('jquery.delayedBind with data option', 2, function ( assert ) {
-               var $fixture = $('<div>').appendTo('#qunit-fixture'),
+       QUnit.asyncTest( 'jquery.delayedBind with data option', 2, function ( assert ) {
+               var $fixture = $( '<div>' ).appendTo( '#qunit-fixture' ),
                        data = {
                                magic: 'beeswax'
                        },
                        delay = 50;
 
-               $fixture.delayedBind(delay, 'testevent', data, function ( e ) {
-                       assert.ok( true, 'testevent fired');
-                       assert.ok( e.data === data, 'data is passed through delayedBind');
+               $fixture.delayedBind( delay, 'testevent', data, function ( e ) {
+                       assert.ok( true, 'testevent fired' );
+                       assert.ok( e.data === data, 'data is passed through delayedBind' );
                        QUnit.start();
-               });
+               } );
 
                // We'll trigger it thrice, but it should only happen once.
                $fixture.trigger( 'testevent', {} );
                $fixture.trigger( 'testevent', {} );
                $fixture.trigger( 'testevent', {} );
                $fixture.trigger( 'testevent', {} );
-       });
+       } );
 
-       QUnit.asyncTest('jquery.delayedBind without data option', 1, function ( assert ) {
-               var $fixture = $('<div>').appendTo('#qunit-fixture'),
+       QUnit.asyncTest( 'jquery.delayedBind without data option', 1, function ( assert ) {
+               var $fixture = $( '<div>' ).appendTo( '#qunit-fixture' ),
                        delay = 50;
 
-               $fixture.delayedBind(delay, 'testevent', function () {
-                       assert.ok(true, 'testevent fired');
+               $fixture.delayedBind( delay, 'testevent', function () {
+                       assert.ok( true, 'testevent fired' );
                        QUnit.start();
-               });
+               } );
 
                // We'll trigger it thrice, but it should only happen once.
                $fixture.trigger( 'testevent', {} );
                $fixture.trigger( 'testevent', {} );
                $fixture.trigger( 'testevent', {} );
                $fixture.trigger( 'testevent', {} );
-       });
+       } );
 }( jQuery ) );
index 82566c2..0b7e87e 100644 (file)
@@ -2,7 +2,7 @@
        QUnit.module( 'jquery.getAttrs', QUnit.newMwEnvironment() );
 
        QUnit.test( 'Check', 1, function ( assert ) {
-               var     attrs = {
+               var attrs = {
                                foo: 'bar',
                                'class': 'lorem'
                        },
index d75c378..140da38 100644 (file)
@@ -4,7 +4,7 @@
        QUnit.test( 'devicePixelRatio', function ( assert ) {
                var devicePixelRatio = $.devicePixelRatio();
                assert.equal( typeof devicePixelRatio, 'number', '$.devicePixelRatio() returns a number' );
-       });
+       } );
 
        QUnit.test( 'matchSrcSet', function ( assert ) {
                var srcset = 'onefive.png 1.5x, two.png 2x';
@@ -18,5 +18,5 @@
                assert.equal( $.matchSrcSet( 1.25, srcset ), null, '1.25 gives no match' );
                assert.equal( $.matchSrcSet( 1.75, srcset ), 'onefive.png', '1.75 gives match to 1.5' );
                assert.equal( $.matchSrcSet( 2.25, srcset ), 'two.png', '2.25 gives match to 2' );
-       });
+       } );
 }( jQuery ) );
index 3810a04..d3877e0 100644 (file)
                assert.strictEqual( $lc.length, 1, 'link is created' );
                assert.strictEqual( $lc.text(), 'link', 'the link text got added' );
        } );
-}( jQuery, mediaWiki ) ) ;
+}( jQuery, mediaWiki ) );
index 3ffcbf5..2765498 100644 (file)
@@ -2,38 +2,36 @@
        QUnit.module( 'jquery.mwExtension', QUnit.newMwEnvironment() );
 
        QUnit.test( 'String functions', function ( assert ) {
-
                assert.equal( $.trimLeft( '  foo bar  ' ), 'foo bar  ', 'trimLeft' );
                assert.equal( $.trimRight( '  foo bar  ' ), '  foo bar', 'trimRight' );
                assert.equal( $.ucFirst( 'foo' ), 'Foo', 'ucFirst' );
 
                assert.equal( $.escapeRE( '<!-- ([{+mW+}]) $^|?>' ),
-                '<!\\-\\- \\(\\[\\{\\+mW\\+\\}\\]\\) \\$\\^\\|\\?>', 'escapeRE - Escape specials' );
+                       '<!\\-\\- \\(\\[\\{\\+mW\\+\\}\\]\\) \\$\\^\\|\\?>', 'escapeRE - Escape specials' );
                assert.equal( $.escapeRE( 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' ),
-                'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'escapeRE - Leave uppercase alone' );
+                       'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'escapeRE - Leave uppercase alone' );
                assert.equal( $.escapeRE( 'abcdefghijklmnopqrstuvwxyz' ),
-                'abcdefghijklmnopqrstuvwxyz', 'escapeRE - Leave lowercase alone' );
+                       'abcdefghijklmnopqrstuvwxyz', 'escapeRE - Leave lowercase alone' );
                assert.equal( $.escapeRE( '0123456789' ), '0123456789', 'escapeRE - Leave numbers alone' );
-       });
+       } );
 
        QUnit.test( 'Is functions', function ( assert ) {
-
                assert.strictEqual( $.isDomElement( document.getElementById( 'qunit-header' ) ), true,
-                'isDomElement: #qunit-header Node' );
+                       'isDomElement: #qunit-header Node' );
                assert.strictEqual( $.isDomElement( document.getElementById( 'random-name' ) ), false,
-                'isDomElement: #random-name (null)' );
+                       'isDomElement: #random-name (null)' );
                assert.strictEqual( $.isDomElement( document.getElementsByTagName( 'div' ) ), false,
-                'isDomElement: getElementsByTagName Array' );
+                       'isDomElement: getElementsByTagName Array' );
                assert.strictEqual( $.isDomElement( document.getElementsByTagName( 'div' )[0] ), true,
-                'isDomElement: getElementsByTagName(..)[0] Node' );
+                       'isDomElement: getElementsByTagName(..)[0] Node' );
                assert.strictEqual( $.isDomElement( $( 'div' ) ), false,
-                'isDomElement: jQuery object' );
-               assert.strictEqual( $.isDomElement( $( 'div' ).get(0) ), true,
-                'isDomElement: jQuery object > Get node' );
+                       'isDomElement: jQuery object' );
+               assert.strictEqual( $.isDomElement( $( 'div' ).get( 0 ) ), true,
+                       'isDomElement: jQuery object > Get node' );
                assert.strictEqual( $.isDomElement( document.createElement( 'div' ) ), true,
-                'isDomElement: createElement' );
+                       'isDomElement: createElement' );
                assert.strictEqual( $.isDomElement( { foo: 1 } ), false,
-                'isDomElement: Object' );
+                       'isDomElement: Object' );
 
                assert.strictEqual( $.isEmpty( 'string' ), false, 'isEmptry: "string"' );
                assert.strictEqual( $.isEmpty( '0' ), true, 'isEmptry: "0"' );
 
                // Documented behaviour
                assert.strictEqual( $.isEmpty( { length: 0 } ), true, 'isEmptry: { length: 0 }' );
-       });
+       } );
 
        QUnit.test( 'Comparison functions', function ( assert ) {
-
                assert.ok( $.compareArray( [0, 'a', [], [2, 'b'] ], [0, 'a', [], [2, 'b'] ] ),
-                'compareArray: Two deep arrays that are excactly the same' );
+                       'compareArray: Two deep arrays that are excactly the same' );
                assert.ok( !$.compareArray( [1], [2] ), 'compareArray: Two different arrays (false)' );
 
                assert.ok( $.compareObject( {}, {} ), 'compareObject: Two empty objects' );
                assert.ok( $.compareObject( { foo: 1 }, { foo: 1 } ), 'compareObject: Two the same objects' );
                assert.ok( !$.compareObject( { bar: true }, { baz: false } ),
-                'compareObject: Two different objects (false)' );
-       });
+                       'compareObject: Two different objects (false)' );
+       } );
 }( jQuery ) );
index e31fc63..1213793 100644 (file)
@@ -3,35 +3,33 @@
 
        QUnit.test( 'firstTabIndex', 2, function ( assert ) {
                var html, $testA, $testB;
-               html =
-       '<form>' +
-               '<input tabindex="7" />' +
-               '<input tabindex="9" />' +
-               '<textarea tabindex="2">Foobar</textarea>' +
-               '<textarea tabindex="5">Foobar</textarea>' +
-       '</form>';
+               html = '<form>' +
+                       '<input tabindex="7" />' +
+                       '<input tabindex="9" />' +
+                       '<textarea tabindex="2">Foobar</textarea>' +
+                       '<textarea tabindex="5">Foobar</textarea>' +
+                       '</form>';
 
                $testA = $( '<div>' ).html( html ).appendTo( '#qunit-fixture' );
                assert.strictEqual( $testA.firstTabIndex(), 2, 'First tabindex should be 2 within this context.' );
 
                $testB = $( '<div>' );
                assert.strictEqual( $testB.firstTabIndex(), null, 'Return null if none available.' );
-       });
+       } );
 
        QUnit.test( 'lastTabIndex', 2, function ( assert ) {
                var html, $testA, $testB;
-               html =
-       '<form>' +
-               '<input tabindex="7" />' +
-               '<input tabindex="9" />' +
-               '<textarea tabindex="2">Foobar</textarea>' +
-               '<textarea tabindex="5">Foobar</textarea>' +
-       '</form>';
+               html = '<form>' +
+                       '<input tabindex="7" />' +
+                       '<input tabindex="9" />' +
+                       '<textarea tabindex="2">Foobar</textarea>' +
+                       '<textarea tabindex="5">Foobar</textarea>' +
+                       '</form>';
 
                $testA = $( '<div>' ).html( html ).appendTo( '#qunit-fixture' );
                assert.strictEqual( $testA.lastTabIndex(), 9, 'Last tabindex should be 9 within this context.' );
 
                $testB = $( '<div>' );
                assert.strictEqual( $testB.lastTabIndex(), null, 'Return null if none available.' );
-       });
+       } );
 }( jQuery ) );
index b8d816e..deff5b0 100644 (file)
@@ -8,7 +8,7 @@
                wgContentLanguage: 'en'
        };
 
-       QUnit.module( 'jquery.tablesorter', QUnit.newMwEnvironment({ config: config }) );
+       QUnit.module( 'jquery.tablesorter', QUnit.newMwEnvironment( { config: config } ) );
 
        /**
         * Create an HTML table from an array of row arrays containing text strings.
@@ -18,7 +18,7 @@
         * @param {String[][]} data
         * @return jQuery
         */
-       function tableCreate(  header, data ) {
+       function tableCreate( header, data ) {
                var i,
                        $table = $( '<table class="sortable"><thead></thead><tbody></tbody></table>' ),
                        $thead = $table.find( 'thead' ),
@@ -28,7 +28,7 @@
                $.each( header, function ( i, str ) {
                        var $th = $( '<th>' );
                        $th.text( str ).appendTo( $tr );
-               });
+               } );
                $tr.appendTo( $thead );
 
                for ( i = 0; i < data.length; i++ ) {
@@ -37,7 +37,7 @@
                        $.each( data[i], function ( j, str ) {
                                var $td = $( '<td>' );
                                $td.text( str ).appendTo( $tr );
-                       });
+                       } );
                        $tr.appendTo( $tbody );
                }
                return $table;
        function tableExtract( $table ) {
                var data = [];
 
-               $table.find( 'tbody' ).find( 'tr' ).each( function( i, tr ) {
+               $table.find( 'tbody' ).find( 'tr' ).each( function ( i, tr ) {
                        var row = [];
-                       $( tr ).find( 'td,th' ).each( function( i, td ) {
+                       $( tr ).find( 'td,th' ).each( function ( i, td ) {
                                row.push( $( td ).text() );
-                       });
+                       } );
                        data.push( row );
-               });
+               } );
                return data;
        }
 
                        // to asynchronous, we'll need a timeout or a callback here.
                        var extracted = tableExtract( $table );
                        assert.deepEqual( extracted, expected, msg );
-               });
+               } );
        }
 
-       function reversed(arr) {
+       function reversed( arr ) {
                // Clone array
-               var arr2 = arr.slice(0);
+               var arr2 = arr.slice( 0 );
 
                arr2.reverse();
 
        }
 
        // Sample data set using planets named and their radius
-       var header  = [ 'Planet' , 'Radius (km)'],
+       var header = [ 'Planet' , 'Radius (km)'],
                mercury = [ 'Mercury', '2439.7' ],
-               venus   = [ 'Venus'  , '6051.8' ],
-               earth   = [ 'Earth'  , '6371.0' ],
-               mars    = [ 'Mars'   , '3390.0' ],
-               jupiter = [ 'Jupiter',  '69911' ],
-               saturn  = [ 'Saturn' ,  '58232' ];
+               venus = [ 'Venus'  , '6051.8' ],
+               earth = [ 'Earth'  , '6371.0' ],
+               mars = [ 'Mars'   , '3390.0' ],
+               jupiter = [ 'Jupiter', '69911' ],
+               saturn = [ 'Saturn' , '58232' ];
 
        // Initial data set
-       var planets         = [mercury, venus, earth, mars, jupiter, saturn];
-       var ascendingName   = [earth, jupiter, mars, mercury, saturn, venus];
+       var planets = [mercury, venus, earth, mars, jupiter, saturn];
+       var ascendingName = [earth, jupiter, mars, mercury, saturn, venus];
        var ascendingRadius = [mercury, mars, venus, earth, saturn, jupiter];
 
        tableTest(
                planets,
                ascendingName,
                function ( $table ) {
-                       $table.tablesorter( { sortList: [ { 0: 'asc' } ] } );
+                       $table.tablesorter( { sortList: [
+                               { 0: 'asc' }
+                       ] } );
                }
        );
        tableTest(
                'Basic planet table: sorting initially - descending by radius',
                header,
                planets,
-               reversed(ascendingRadius),
+               reversed( ascendingRadius ),
                function ( $table ) {
-                       $table.tablesorter( { sortList: [ { 1: 'desc' } ] } );
+                       $table.tablesorter( { sortList: [
+                               { 1: 'desc' }
+                       ] } );
                }
        );
        tableTest(
                'Basic planet table: descending by name',
                header,
                planets,
-               reversed(ascendingName),
+               reversed( ascendingName ),
                function ( $table ) {
                        $table.tablesorter();
                        $table.find( '.headerSort:eq(0)' ).click().click();
                'Basic planet table: descending radius',
                header,
                planets,
-               reversed(ascendingRadius),
+               reversed( ascendingRadius ),
                function ( $table ) {
                        $table.tablesorter();
                        $table.find( '.headerSort:eq(1)' ).click().click();
                asc,
                function ( $table ) {
                        $table.tablesorter(
-                               { sortList: [ { 0: 'asc' }, { 1: 'asc' } ] }
+                               { sortList: [
+                                       { 0: 'asc' },
+                                       { 1: 'asc' }
+                               ] }
                        );
                }
        );
                function ( $table ) {
                        $table.tablesorter();
                        $table.data( 'tablesorter' ).sort(
-                               [ { 0: 'desc' }, { 1: 'asc' } ]
+                               [
+                                       { 0: 'desc' },
+                                       { 1: 'asc' }
+                               ]
                        );
                }
        );
                asc,
                function ( $table ) {
                        $table.tablesorter(
-                               { sortList: [ { 0: 'asc' }, { 1: 'asc' } ] }
+                               { sortList: [
+                                       { 0: 'asc' },
+                                       { 1: 'asc' }
+                               ] }
                        );
                        $table.data( 'tablesorter' ).sort(
-                               [ { 0: 'desc' }, { 1: 'asc' } ]
+                               [
+                                       { 0: 'desc' },
+                                       { 1: 'asc' }
+                               ]
                        );
                        $table.data( 'tablesorter' ).sort();
                }
        QUnit.test( 'Reset sorting making table appear unsorted', 3, function ( assert ) {
                var $table = tableCreate( header, initial );
                $table.tablesorter(
-                       { sortList: [ { 0: 'desc' }, { 1: 'asc' } ] }
+                       { sortList: [
+                               { 0: 'desc' },
+                               { 1: 'asc' }
+                       ] }
                );
                $table.data( 'tablesorter' ).sort( [] );
 
        tableTest(
                'Bug 28775: German-style (dmy) short numeric dates',
                ['Date'],
-               [ // German-style dates are day-month-year
+               [
+                       // German-style dates are day-month-year
                        ['11.11.2011'],
                        ['01.11.2011'],
                        ['02.10.2011'],
                        ['03.08.2011'],
                        ['09.11.2011']
                ],
-               [ // Sorted by ascending date
+               [
+                       // Sorted by ascending date
                        ['03.08.2011'],
                        ['02.10.2011'],
                        ['01.11.2011'],
        tableTest(
                'Bug 28775: American-style (mdy) short numeric dates',
                ['Date'],
-               [ // American-style dates are month-day-year
+               [
+                       // American-style dates are month-day-year
                        ['11.11.2011'],
                        ['01.11.2011'],
                        ['02.10.2011'],
                        ['03.08.2011'],
                        ['09.11.2011']
                ],
-               [ // Sorted by ascending date
+               [
+                       // Sorted by ascending date
                        ['01.11.2011'],
                        ['02.10.2011'],
                        ['03.08.2011'],
                'Bug 17141: IPv4 address sorting (reverse)',
                ['IP'],
                ipv4,
-               reversed(ipv4Sorted),
+               reversed( ipv4Sorted ),
                function ( $table ) {
                        $table.tablesorter();
                        $table.find( '.headerSort:eq(0)' ).click().click();
                                'ä': 'ae',
                                'ö': 'oe',
                                'ß': 'ss',
-                               'ü':'ue'
+                               'ü': 'ue'
                        } );
 
                        $table.tablesorter();
                        3,
                        'Rowspan not exploded'
                );
-       });
+       } );
 
-       var planetsRowspan = [ [ 'Earth', '6051.8' ], jupiter, [ 'Mars', '6051.8' ], mercury, saturn, venus ];
+       var planetsRowspan = [
+               [ 'Earth', '6051.8' ],
+               jupiter,
+               [ 'Mars', '6051.8' ],
+               mercury,
+               saturn,
+               venus
+       ];
        var planetsRowspanII = [ jupiter, mercury, saturn, venus, [ 'Venus', '6371.0' ], [ 'Venus', '3390.0' ] ];
 
        tableTest(
                        //   This covers the removed cell in the 4th and 5th row.
                        $table.find( 'tr:eq(2) td:eq(1)' ).prop( 'rowspan', '3' );
 
-                       $table.tablesorter( { sortList: [ { 0: 'asc' } ] } );
+                       $table.tablesorter( { sortList: [
+                               { 0: 'asc' }
+                       ] } );
                }
        );
        tableTest(
                }
        );
 
-       var ascendingNameLegacy = ascendingName.slice(0);
+       var ascendingNameLegacy = ascendingName.slice( 0 );
        ascendingNameLegacy[4] = ascendingNameLegacy[5];
        ascendingNameLegacy.pop();
 
                header,
                planets,
                ascendingNameLegacy,
-               function( $table ) {
+               function ( $table ) {
                        $table.find( 'tr:last' ).addClass( 'sortbottom' );
                        $table.tablesorter();
                        $table.find( '.headerSort:eq(0)' ).click();
                var $table;
                $table = $(
                        '<table class="sortable">' +
-                       '<caption>CAPTION</caption>' +
-                       '<tr><th>THEAD</th></tr>' +
-                       '<tr><td>1</td></tr>' +
-                       '<tr class="sortbottom"><td>text</td></tr>' +
-                       '</table>'
+                               '<caption>CAPTION</caption>' +
+                               '<tr><th>THEAD</th></tr>' +
+                               '<tr><td>1</td></tr>' +
+                               '<tr class="sortbottom"><td>text</td></tr>' +
+                               '</table>'
                );
                $table.tablesorter();
                $table.find( '.headerSort:eq(0)' ).click();
                var $table;
                $table = $(
                        '<table class="sortable">' +
-                       '<caption>CAPTION</caption>' +
-                       '<tr><th>THEAD</th></tr>' +
-                       '<tr><td>A</td></tr>' +
-                       '<tr><td>B</td></tr>' +
-                       '<tr class="sortbottom"><td>TFOOT</td></tr>' +
-                       '</table>'
-                       );
+                               '<caption>CAPTION</caption>' +
+                               '<tr><th>THEAD</th></tr>' +
+                               '<tr><td>A</td></tr>' +
+                               '<tr><td>B</td></tr>' +
+                               '<tr class="sortbottom"><td>TFOOT</td></tr>' +
+                               '</table>'
+               );
                $table.tablesorter();
 
                assert.equal(
-                       $table.children( ).get( 0 ).nodeName,
+                       $table.children().get( 0 ).nodeName,
                        'CAPTION',
                        'First element after <thead> must be <caption> (bug 32047)'
                );
-       });
+       } );
 
        QUnit.test( 'data-sort-value attribute, when available, should override sorting position', function ( assert ) {
                var $table, data;
                                '<tr><td data-sort-value="Bananna">Ferret</td></tr>' +
                                '<tr><td data-sort-value="Drupe">Elephant</td></tr>' +
                                '<tr><td data-sort-value="Cherry">Dolphin</td></tr>' +
-                       '</tbody></table>'
+                               '</tbody></table>'
                );
                $table.tablesorter().find( '.headerSort:eq(0)' ).click();
 
                data = [];
-               $table.find( 'tbody > tr' ).each( function( i, tr ) {
-                       $( tr ).find( 'td' ).each( function( i, td ) {
+               $table.find( 'tbody > tr' ).each( function ( i, tr ) {
+                       $( tr ).find( 'td' ).each( function ( i, td ) {
                                data.push( {
                                        data: $( td ).data( 'sortValue' ),
                                        text: $( td ).text()
                                } );
-                       });
-               });
+                       } );
+               } );
 
                assert.deepEqual( data, [
                        {
                                data: 'Apple',
                                text: 'Bird'
-                       }, {
+                       },
+                       {
                                data: 'Bananna',
                                text: 'Ferret'
-                       }, {
+                       },
+                       {
                                data: undefined,
                                text: 'Cheetah'
-                       }, {
+                       },
+                       {
                                data: 'Cherry',
                                text: 'Dolphin'
-                       }, {
+                       },
+                       {
                                data: 'Drupe',
                                text: 'Elephant'
                        }
                                '<tr><td>B</td></tr>' +
                                '<tr><td>G</td></tr>' +
                                '<tr><td data-sort-value="F">C</td></tr>' +
-                       '</tbody></table>'
+                               '</tbody></table>'
                );
                $table.tablesorter().find( '.headerSort:eq(0)' ).click();
 
                                        data: $( td ).data( 'sortValue' ),
                                        text: $( td ).text()
                                } );
-                       });
-               });
+                       } );
+               } );
 
                assert.deepEqual( data, [
                        {
                                data: undefined,
                                text: 'B'
-                       }, {
+                       },
+                       {
                                data: undefined,
                                text: 'D'
-                       }, {
+                       },
+                       {
                                data: 'E',
                                text: 'A'
-                       }, {
+                       },
+                       {
                                data: 'F',
                                text: 'C'
-                       }, {
+                       },
+                       {
                                data: undefined,
                                text: 'G'
                        }
                                '<tr><td>B</td></tr>' +
                                '<tr><td data-sort-value="2">G</td></tr>' +
                                '<tr><td>C</td></tr>' +
-                       '</tbody></table>'
+                               '</tbody></table>'
                );
                // initialize table sorter and sort once
                $table
                $table.find( '.headerSort:eq(0)' ).click();
 
                data = [];
-               $table.find( 'tbody > tr' ).each( function( i, tr ) {
-                       $( tr ).find( 'td' ).each( function( i, td ) {
+               $table.find( 'tbody > tr' ).each( function ( i, tr ) {
+                       $( tr ).find( 'td' ).each( function ( i, td ) {
                                data.push( {
                                        data: $( td ).data( 'sortValue' ),
                                        text: $( td ).text()
                                } );
-                       });
-               });
+                       } );
+               } );
 
                assert.deepEqual( data, [
                        {
                                data: 1,
                                text: 'B'
-                       }, {
+                       },
+                       {
                                data: 2,
                                text: 'G'
-                       }, {
+                       },
+                       {
                                data: 3,
                                text: 'A'
-                       }, {
+                       },
+                       {
                                data: undefined,
                                text: 'C'
-                       }, {
+                       },
+                       {
                                data: undefined,
                                text: 'D'
                        }
                ], 'Order matches expected order, using the current sortValue in $.data()' );
 
-       });
+       } );
 
        var numbers = [
                [ '12'    ],
 
        tableTest( 'bug 8115: sort numbers with commas (ascending)',
                ['Numbers'], numbers, numbersAsc,
-               function( $table ) {
+               function ( $table ) {
                        $table.tablesorter();
                        $table.find( '.headerSort:eq(0)' ).click();
                }
        );
 
        tableTest( 'bug 8115: sort numbers with commas (descending)',
-               ['Numbers'], numbers, reversed(numbersAsc),
-               function( $table ) {
+               ['Numbers'], numbers, reversed( numbersAsc ),
+               function ( $table ) {
                        $table.tablesorter();
                        $table.find( '.headerSort:eq(0)' ).click().click();
                }
                var $table;
                $table = $(
                        '<table class="sortable" id="mw-bug-32888">' +
-                       '<tr><th>header<table id="mw-bug-32888-2">'+
+                               '<tr><th>header<table id="mw-bug-32888-2">' +
                                '<tr><th>1</th><th>2</th></tr>' +
-                       '</table></th></tr>' +
-                       '<tr><td>A</td></tr>' +
-                       '<tr><td>B</td></tr>' +
-                       '</table>'
-                       );
+                               '</table></th></tr>' +
+                               '<tr><td>A</td></tr>' +
+                               '<tr><td>B</td></tr>' +
+                               '</table>'
+               );
                $table.tablesorter();
 
                assert.equal(
-                       $table.find('> thead:eq(0) > tr > th.headerSort').length,
+                       $table.find( '> thead:eq(0) > tr > th.headerSort' ).length,
                        1,
                        'Child tables inside a headercell should not interfere with sortable headers (bug 32888)'
                );
                assert.equal(
-                       $( '#mw-bug-32888-2' ).find('th.headerSort').length,
+                       $( '#mw-bug-32888-2' ).find( 'th.headerSort' ).length,
                        0,
                        'The headers of child tables inside a headercell should not be sortable themselves (bug 32888)'
                );
-       });
+       } );
 
 
        var correctDateSorting1 = [
                }
        );
 
-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();
+       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' ).first().text(),
+                       '1',
+                       'Applied correct sorting order'
+               );
+       } );
 
-       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();
+       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(),
-               '4517',
-               'Applied correct sorting order'
-       );
-} );
+               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 1795b95..ce03b69 100644 (file)
         *   params {object} add'l parameters for $().textSelection( 'encapsulateText' )
         */
        function encapsulateTest( options ) {
-               var opt = $.extend({
+               var opt = $.extend( {
                        description: '',
                        before: {},
                        after: {},
                        replace: {}
-               }, options);
+               }, options );
 
-               opt.before = $.extend({
+               opt.before = $.extend( {
                        text: '',
                        start: 0,
                        end: 0
-               }, opt.before);
-               opt.after = $.extend({
+               }, opt.before );
+               opt.after = $.extend( {
                        text: '',
                        selected: null
-               }, opt.after);
+               }, opt.after );
 
                QUnit.test( opt.description, function ( assert ) {
                        /*jshint onevar: false */
                        //$textarea.textSelection( 'setContents', opt.before.text); // this method is actually missing atm...
                        $textarea.val( opt.before.text ); // won't work with the WikiEditor iframe?
 
-                       var     start = opt.before.start,
+                       var start = opt.before.start,
                                end = opt.before.end;
                        if ( window.opera ) {
                                // Compensate for Opera's craziness converting \n to \r\n and counting that as two chars
-                               var     newLinesBefore = opt.before.text.substring( 0, start ).split( '\n' ).length - 1,
+                               var newLinesBefore = opt.before.text.substring( 0, start ).split( '\n' ).length - 1,
                                        newLinesInside = opt.before.text.substring( start, end ).split( '\n' ).length - 1;
                                start += newLinesBefore;
                                end += newLinesBefore + newLinesInside;
@@ -98,7 +98,7 @@
                        splitlines: true
                };
 
-       encapsulateTest({
+       encapsulateTest( {
                description: 'Adding sig to end of text',
                before: {
                        text: 'Wikilove dude! ',
                        selected: ''
                },
                replace: sig
-       });
+       } );
 
-       encapsulateTest({
+       encapsulateTest( {
                description: 'Adding bold to empty',
                before: {
                        text: '',
                        selected: 'Bold text' // selected because it's the default
                },
                replace: bold
-       });
+       } );
 
-       encapsulateTest({
+       encapsulateTest( {
                description: 'Adding bold to existing text',
                before: {
                        text: 'Now is the time for all good men to come to the aid of their country',
                        selected: '' // empty because it's not the default'
                },
                replace: bold
-       });
+       } );
 
-       encapsulateTest({
+       encapsulateTest( {
                description: 'ownline option: adding new h2',
                before: {
-                       text:'Before\nAfter',
+                       text: 'Before\nAfter',
                        start: 7,
                        end: 7
                },
                        selected: 'Heading 2'
                },
                replace: h2
-       });
+       } );
 
-       encapsulateTest({
+       encapsulateTest( {
                description: 'ownline option: turn a whole line into new h2',
                before: {
-                       text:'Before\nMy heading\nAfter',
+                       text: 'Before\nMy heading\nAfter',
                        start: 7,
                        end: 17
                },
                        selected: ''
                },
                replace: h2
-       });
+       } );
 
 
-       encapsulateTest({
+       encapsulateTest( {
                description: 'ownline option: turn a partial line into new h2',
                before: {
-                       text:'BeforeMy headingAfter',
+                       text: 'BeforeMy headingAfter',
                        start: 6,
                        end: 16
                },
                        selected: ''
                },
                replace: h2
-       });
+       } );
 
 
-       encapsulateTest({
+       encapsulateTest( {
                description: 'splitlines option: no selection, insert new list item',
                before: {
                        text: 'Before\nAfter',
                        text: 'Before\n* Bulleted list item\nAfter'
                },
                replace: ulist
-       });
+       } );
 
-       encapsulateTest({
+       encapsulateTest( {
                description: 'splitlines option: single partial line selection, insert new list item',
                before: {
                        text: 'BeforeMy List ItemAfter',
                        text: 'Before\n* My List Item\nAfter'
                },
                replace: ulist
-       });
+       } );
 
-       encapsulateTest({
+       encapsulateTest( {
                description: 'splitlines option: multiple lines',
                before: {
                        text: 'Before\nFirst\nSecond\nThird\nAfter',
                        text: 'Before\n* First\n* Second\n* Third\nAfter'
                },
                replace: ulist
-       });
+       } );
 
 
        function caretTest( options ) {
                        $( '#qunit-fixture' ).append( $textarea );
 
                        if ( options.mode === 'set' ) {
-                               $textarea.textSelection('setSelection', {
+                               $textarea.textSelection( 'setSelection', {
                                        start: options.start,
                                        end: options.end
-                               });
+                               } );
                        }
 
                        function among( actual, expected, message ) {
                                if ( $.isArray( expected ) ) {
-                                       assert.ok( $.inArray( actual, expected ) !== -1 , message + ' (got ' + actual + '; expected one of ' + expected.join(', ') + ')' );
+                                       assert.ok( $.inArray( actual, expected ) !== -1, message + ' (got ' + actual + '; expected one of ' + expected.join( ', ' ) + ')' );
                                } else {
                                        assert.equal( actual, expected, message );
                                }
                        }
 
-                       pos = $textarea.textSelection( 'getCaretPosition', { startAndEnd: true });
-                       among(pos[0], options.start, 'Caret start should be where we set it.');
-                       among(pos[1], options.end, 'Caret end should be where we set it.');
-               });
+                       pos = $textarea.textSelection( 'getCaretPosition', { startAndEnd: true } );
+                       among( pos[0], options.start, 'Caret start should be where we set it.' );
+                       among( pos[1], options.end, 'Caret end should be where we set it.' );
+               } );
        }
 
        caretSample = 'Some big text that we like to work with. Nothing fancy... you know what I mean?';
 
        /*
-       // @broken: Disabled per bug 34820
-       caretTest({
-               description: 'getCaretPosition with original/empty selection - bug 31847 with IE 6/7/8',
-               text: caretSample,
-               start: [0, caretSample.length], // Opera and Firefox (prior to FF 6.0) default caret to the end of the box (caretSample.length)
-               end: [0, caretSample.length], // Other browsers default it to the beginning (0), so check both.
-               mode: 'get'
-       });
-       */
+        // @broken: Disabled per bug 34820
+        caretTest({
+        description: 'getCaretPosition with original/empty selection - bug 31847 with IE 6/7/8',
+        text: caretSample,
+        start: [0, caretSample.length], // Opera and Firefox (prior to FF 6.0) default caret to the end of the box (caretSample.length)
+        end: [0, caretSample.length], // Other browsers default it to the beginning (0), so check both.
+        mode: 'get'
+        });
+        */
 
-       caretTest({
+       caretTest( {
                description: 'set/getCaretPosition with forced empty selection',
                text: caretSample,
                start: 7,
                end: 7,
                mode: 'set'
-       });
+       } );
 
-       caretTest({
+       caretTest( {
                description: 'set/getCaretPosition with small selection',
                text: caretSample,
                start: 6,
                end: 11,
                mode: 'set'
-       });
+       } );
 }( jQuery ) );
index ec7179e..2bed9b9 100644 (file)
@@ -23,6 +23,6 @@
                                assert.equal( $res.find( 'b' ).text(), 'Hello world', 'Bold tag wraps the entire, same, text' );
 
                                QUnit.start();
-                       });
-       });
+                       } );
+       } );
 }( mediaWiki, jQuery ) );
index 50bbfd7..9eda75c 100644 (file)
                d1 = api.get( {} )
                        .done( function ( data ) {
                                assert.deepEqual( data, [], 'If request succeeds without errors, resolve deferred' );
-                       });
+                       } );
 
-               d2 = api.get({
-                               action: 'doesntexist'
-                       })
+               d2 = api.get( {
+                       action: 'doesntexist'
+               )
                        .fail( function ( errorCode ) {
                                assert.equal( errorCode, 'unknown_action', 'API error (e.g. "unknown_action") should reject the deferred' );
-                       });
+                       } );
 
                d3 = api.post( {} )
                        .done( function ( data ) {
                                assert.deepEqual( data, [], 'Simple POST request' );
-                       });
+                       } );
 
                // After all are completed, continue the test suite.
                QUnit.whenPromisesComplete( d1, d2, d3 ).always( function () {
                        QUnit.start();
-               });
-       });
+               } );
+       } );
 
        QUnit.asyncTest( 'Deprecated callback methods', function ( assert ) {
                var api, d1, d2, d3;
 
                d1 = api.get( {}, function () {
                        assert.ok( true, 'Function argument treated as success callback.' );
-               });
+               } );
 
                d2 = api.get( {}, {
                        ok: function () {
                                assert.ok( true, '"ok" property treated as success callback.' );
                        }
-               });
+               } );
 
-               d3 = api.get({
-                               action: 'doesntexist'
-                       }, {
+               d3 = api.get( {
+                       action: 'doesntexist'
+               }, {
                        err: function () {
                                assert.ok( true, '"err" property treated as error callback.' );
                        }
-               });
+               } );
 
                QUnit.whenPromisesComplete( d1, d2, d3 ).always( function () {
                        QUnit.start();
-               });
-       });
+               } );
+       } );
 }( mediaWiki ) );
index d7b0cb7..9389651 100644 (file)
@@ -7,23 +7,21 @@
                var selectHtml, $env, $options;
 
                // from Special:Recentchanges
-               selectHtml =
-               '<select id="namespace" name="namespace" class="namespaceselector">'
-               + '<option value="" selected="selected">all</option>'
-               + '<option value="0">(Main)</option>'
-               + '<option value="1">Talk</option>'
-               + '<option value="2">User</option>'
-               + '<option value="3">User talk</option>'
-               + '<option value="4">ProjectName</option>'
-               + '<option value="5">ProjectName talk</option>'
-               + '</select>'
-               + '<input name="invert" type="checkbox" value="1" id="nsinvert" title="no title" />'
-               + '<label for="nsinvert" title="no title">Invert selection</label>'
-               + '<input name="associated" type="checkbox" value="1" id="nsassociated" title="no title" />'
-               + '<label for="nsassociated" title="no title">Associated namespace</label>'
-               + '<input type="submit" value="Go" />'
-               + '<input type="hidden" value="Special:RecentChanges" name="title" />'
-               ;
+               selectHtml = '<select id="namespace" name="namespace" class="namespaceselector">'
+                       + '<option value="" selected="selected">all</option>'
+                       + '<option value="0">(Main)</option>'
+                       + '<option value="1">Talk</option>'
+                       + '<option value="2">User</option>'
+                       + '<option value="3">User talk</option>'
+                       + '<option value="4">ProjectName</option>'
+                       + '<option value="5">ProjectName talk</option>'
+                       + '</select>'
+                       + '<input name="invert" type="checkbox" value="1" id="nsinvert" title="no title" />'
+                       + '<label for="nsinvert" title="no title">Invert selection</label>'
+                       + '<input name="associated" type="checkbox" value="1" id="nsassociated" title="no title" />'
+                       + '<label for="nsassociated" title="no title">Associated namespace</label>'
+                       + '<input type="submit" value="Go" />'
+                       + '<input type="hidden" value="Special:RecentChanges" name="title" />';
 
                $env = $( '<div>' ).html( selectHtml ).appendTo( 'body' );
 
@@ -42,8 +40,8 @@
 
                // select second option...
                $options = $( '#namespace' ).find( 'option' );
-               $options.eq(0).removeProp( 'selected' );
-               $options.eq(1).prop( 'selected', true );
+               $options.eq( 0 ).removeProp( 'selected' );
+               $options.eq( 1 ).prop( 'selected', true );
                $( '#namespace' ).change();
 
                // ... and checkboxes should be enabled again
@@ -51,8 +49,8 @@
                assert.strictEqual( $( '#nsassociated' ).prop( 'disabled' ), false );
 
                // select first option ( 'all' namespace)...
-               $options.eq(1).removeProp( 'selected' );
-               $options.eq(0).prop( 'selected', true );
+               $options.eq( 1 ).removeProp( 'selected' );
+               $options.eq( 0 ).prop( 'selected', true );
                $( '#namespace' ).change();
 
                // ... and checkboxes should now be disabled
@@ -61,5 +59,5 @@
 
                // DOM cleanup
                $env.remove();
-       });
+       } );
 }( mediaWiki, jQuery ) );
index 52f0538..30a31ef 100644 (file)
 ( function ( mw ) {
+       // mw.Title relies on these three config vars
+       // Restore them after each test run
+       var config = {
+               wgFormattedNamespaces: {
+                       '-2': 'Media',
+                       '-1': 'Special',
+                       0: '',
+                       1: 'Talk',
+                       2: 'User',
+                       3: 'User talk',
+                       4: 'Wikipedia',
+                       5: 'Wikipedia talk',
+                       6: 'File',
+                       7: 'File talk',
+                       8: 'MediaWiki',
+                       9: 'MediaWiki talk',
+                       10: 'Template',
+                       11: 'Template talk',
+                       12: 'Help',
+                       13: 'Help talk',
+                       14: 'Category',
+                       15: 'Category talk',
+                       // testing custom / localized namespace
+                       100: 'Penguins'
+               },
+               wgNamespaceIds: {
+                       /*jshint camelcase: false */
+                       media: -2,
+                       special: -1,
+                       '': 0,
+                       talk: 1,
+                       user: 2,
+                       user_talk: 3,
+                       wikipedia: 4,
+                       wikipedia_talk: 5,
+                       file: 6,
+                       file_talk: 7,
+                       mediawiki: 8,
+                       mediawiki_talk: 9,
+                       template: 10,
+                       template_talk: 11,
+                       help: 12,
+                       help_talk: 13,
+                       category: 14,
+                       category_talk: 15,
+                       image: 6,
+                       image_talk: 7,
+                       project: 4,
+                       project_talk: 5,
+                       /* testing custom / alias */
+                       penguins: 100,
+                       antarctic_waterfowl: 100
+               },
+               wgCaseSensitiveNamespaces: []
+       };
+
+       QUnit.module( 'mediawiki.Title', QUnit.newMwEnvironment( { config: config } ) );
+
+       QUnit.test( 'Transformation', 8, function ( assert ) {
+               var title;
+
+               title = new mw.Title( 'File:quux pif.jpg' );
+               assert.equal( title.getName(), 'Quux_pif' );
+
+               title = new mw.Title( 'File:Glarg_foo_glang.jpg' );
+               assert.equal( title.getNameText(), 'Glarg foo glang' );
+
+               title = new mw.Title( 'User:ABC.DEF' );
+               assert.equal( title.toText(), 'User:ABC.DEF' );
+               assert.equal( title.getNamespaceId(), 2 );
+               assert.equal( title.getNamespacePrefix(), 'User:' );
+
+               title = new mw.Title( 'uSEr:hAshAr' );
+               assert.equal( title.toText(), 'User:HAshAr' );
+               assert.equal( title.getNamespaceId(), 2 );
+
+               title = new mw.Title( '   MediaWiki:  Foo   bar   .js   ' );
+               // Don't ask why, it's the way the backend works. One space is kept of each set
+               assert.equal( title.getName(), 'Foo_bar_.js', 'Merge multiple spaces to a single space.' );
+       } );
+
+       QUnit.test( 'Main text for filename', 8, function ( assert ) {
+               var title = new mw.Title( 'File:foo_bar.JPG' );
+
+               assert.equal( title.getNamespaceId(), 6 );
+               assert.equal( title.getNamespacePrefix(), 'File:' );
+               assert.equal( title.getName(), 'Foo_bar' );
+               assert.equal( title.getNameText(), 'Foo bar' );
+               assert.equal( title.getMain(), 'Foo_bar.JPG' );
+               assert.equal( title.getMainText(), 'Foo bar.JPG' );
+               assert.equal( title.getExtension(), 'JPG' );
+               assert.equal( title.getDotExtension(), '.JPG' );
+       } );
+
+       QUnit.test( 'Namespace detection and conversion', 6, function ( assert ) {
+               var title;
+
+               title = new mw.Title( 'something.PDF', 6 );
+               assert.equal( title.toString(), 'File:Something.PDF' );
+
+               title = new mw.Title( 'NeilK', 3 );
+               assert.equal( title.toString(), 'User_talk:NeilK' );
+               assert.equal( title.toText(), 'User talk:NeilK' );
+
+               title = new mw.Title( 'Frobisher', 100 );
+               assert.equal( title.toString(), 'Penguins:Frobisher' );
+
+               title = new mw.Title( 'antarctic_waterfowl:flightless_yet_cute.jpg' );
+               assert.equal( title.toString(), 'Penguins:Flightless_yet_cute.jpg' );
+
+               title = new mw.Title( 'Penguins:flightless_yet_cute.jpg' );
+               assert.equal( title.toString(), 'Penguins:Flightless_yet_cute.jpg' );
+       } );
+
+       QUnit.test( 'Throw error on invalid title', 1, function ( assert ) {
+               assert.throws( function () {
+                       return new mw.Title( '' );
+               }, 'Throw error on empty string' );
+       } );
+
+       QUnit.test( 'Case-sensivity', 3, function ( assert ) {
+               var title;
+
+               // Default config
+               mw.config.set( 'wgCaseSensitiveNamespaces', [] );
+
+               title = new mw.Title( 'article' );
+               assert.equal( title.toString(), 'Article', 'Default config: No sensitive namespaces by default. First-letter becomes uppercase' );
+
+               // $wgCapitalLinks = false;
+               mw.config.set( 'wgCaseSensitiveNamespaces', [0, -2, 1, 4, 5, 6, 7, 10, 11, 12, 13, 14, 15] );
+
+               title = new mw.Title( 'article' );
+               assert.equal( title.toString(), 'article', '$wgCapitalLinks=false: Article namespace is sensitive, first-letter case stays lowercase' );
+
+               title = new mw.Title( 'john', 2 );
+               assert.equal( title.toString(), 'User:John', '$wgCapitalLinks=false: User namespace is insensitive, first-letter becomes uppercase' );
+       } );
+
+       QUnit.test( 'toString / toText', 2, function ( assert ) {
+               var title = new mw.Title( 'Some random page' );
+
+               assert.equal( title.toString(), title.getPrefixedDb() );
+               assert.equal( title.toText(), title.getPrefixedText() );
+       } );
 
-// mw.Title relies on these three config vars
-// Restore them after each test run
-var config = {
-       wgFormattedNamespaces: {
-               '-2': 'Media',
-               '-1': 'Special',
-               0: '',
-               1: 'Talk',
-               2: 'User',
-               3: 'User talk',
-               4: 'Wikipedia',
-               5: 'Wikipedia talk',
-               6: 'File',
-               7: 'File talk',
-               8: 'MediaWiki',
-               9: 'MediaWiki talk',
-               10: 'Template',
-               11: 'Template talk',
-               12: 'Help',
-               13: 'Help talk',
-               14: 'Category',
-               15: 'Category talk',
-               // testing custom / localized namespace
-               100: 'Penguins'
-       },
-       wgNamespaceIds: {
-               /*jshint camelcase: false */
-               media: -2,
-               special: -1,
-               '': 0,
-               talk: 1,
-               user: 2,
-               user_talk: 3,
-               wikipedia: 4,
-               wikipedia_talk: 5,
-               file: 6,
-               file_talk: 7,
-               mediawiki: 8,
-               mediawiki_talk: 9,
-               template: 10,
-               template_talk: 11,
-               help: 12,
-               help_talk: 13,
-               category: 14,
-               category_talk: 15,
-               image: 6,
-               image_talk: 7,
-               project: 4,
-               project_talk: 5,
-               /* testing custom / alias */
-               penguins: 100,
-               antarctic_waterfowl: 100
-       },
-       wgCaseSensitiveNamespaces: []
-};
-
-QUnit.module( 'mediawiki.Title', QUnit.newMwEnvironment({ config: config }) );
-
-
-QUnit.test( 'Transformation', 8, function ( assert ) {
-       var title;
-
-       title = new mw.Title( 'File:quux pif.jpg' );
-       assert.equal( title.getName(), 'Quux_pif' );
-
-       title = new mw.Title( 'File:Glarg_foo_glang.jpg' );
-       assert.equal( title.getNameText(), 'Glarg foo glang' );
-
-       title = new mw.Title( 'User:ABC.DEF' );
-       assert.equal( title.toText(), 'User:ABC.DEF' );
-       assert.equal( title.getNamespaceId(), 2 );
-       assert.equal( title.getNamespacePrefix(), 'User:' );
-
-       title = new mw.Title( 'uSEr:hAshAr' );
-       assert.equal( title.toText(), 'User:HAshAr' );
-       assert.equal( title.getNamespaceId(), 2 );
-
-       title = new mw.Title( '   MediaWiki:  Foo   bar   .js   ' );
-       // Don't ask why, it's the way the backend works. One space is kept of each set
-       assert.equal( title.getName(), 'Foo_bar_.js', 'Merge multiple spaces to a single space.' );
-});
-
-QUnit.test( 'Main text for filename', 8, function ( assert ) {
-       var title = new mw.Title( 'File:foo_bar.JPG' );
-
-       assert.equal( title.getNamespaceId(), 6 );
-       assert.equal( title.getNamespacePrefix(), 'File:' );
-       assert.equal( title.getName(), 'Foo_bar' );
-       assert.equal( title.getNameText(), 'Foo bar' );
-       assert.equal( title.getMain(), 'Foo_bar.JPG' );
-       assert.equal( title.getMainText(), 'Foo bar.JPG' );
-       assert.equal( title.getExtension(), 'JPG' );
-       assert.equal( title.getDotExtension(), '.JPG' );
-});
-
-QUnit.test( 'Namespace detection and conversion', 6, function ( assert ) {
-       var title;
-
-       title = new mw.Title( 'something.PDF', 6 );
-       assert.equal( title.toString(), 'File:Something.PDF' );
-
-       title = new mw.Title( 'NeilK', 3 );
-       assert.equal( title.toString(), 'User_talk:NeilK' );
-       assert.equal( title.toText(), 'User talk:NeilK' );
-
-       title = new mw.Title( 'Frobisher', 100 );
-       assert.equal( title.toString(), 'Penguins:Frobisher' );
-
-       title = new mw.Title( 'antarctic_waterfowl:flightless_yet_cute.jpg' );
-       assert.equal( title.toString(), 'Penguins:Flightless_yet_cute.jpg' );
-
-       title = new mw.Title( 'Penguins:flightless_yet_cute.jpg' );
-       assert.equal( title.toString(), 'Penguins:Flightless_yet_cute.jpg' );
-});
-
-QUnit.test( 'Throw error on invalid title', 1, function ( assert ) {
-       assert.throws(function () {
-               return new mw.Title( '' );
-       }, 'Throw error on empty string' );
-});
-
-QUnit.test( 'Case-sensivity', 3, function ( assert ) {
-       var title;
-
-       // Default config
-       mw.config.set( 'wgCaseSensitiveNamespaces', [] );
-
-       title = new mw.Title( 'article' );
-       assert.equal( title.toString(), 'Article', 'Default config: No sensitive namespaces by default. First-letter becomes uppercase' );
-
-       // $wgCapitalLinks = false;
-       mw.config.set( 'wgCaseSensitiveNamespaces', [0, -2, 1, 4, 5, 6, 7, 10, 11, 12, 13, 14, 15] );
-
-       title = new mw.Title( 'article' );
-       assert.equal( title.toString(), 'article', '$wgCapitalLinks=false: Article namespace is sensitive, first-letter case stays lowercase' );
-
-       title = new mw.Title( 'john', 2 );
-       assert.equal( title.toString(), 'User:John', '$wgCapitalLinks=false: User namespace is insensitive, first-letter becomes uppercase' );
-});
+       QUnit.test( 'getExtension', 7, function ( assert ) {
+               function extTest( pagename, ext, description ) {
+                       var title = new mw.Title( pagename );
+                       assert.equal( title.getExtension(), ext, description || pagename );
+               }
 
-QUnit.test( 'toString / toText', 2, function ( assert ) {
-       var title = new mw.Title( 'Some random page' );
+               extTest( 'MediaWiki:Vector.js', 'js' );
+               extTest( 'User:Example/common.css', 'css' );
+               extTest( 'File:Example.longextension', 'longextension', 'Extension parsing not limited (bug 36151)' );
+               extTest( 'Example/information.json', 'json', 'Extension parsing not restricted from any namespace' );
+               extTest( 'Foo.', null, 'Trailing dot is not an extension' );
+               extTest( 'Foo..', null, 'Trailing dots are not an extension' );
+               extTest( 'Foo.a.', null, 'Page name with dots and ending in a dot does not have an extension' );
 
-       assert.equal( title.toString(), title.getPrefixedDb() );
-       assert.equal( title.toText(), title.getPrefixedText() );
-});
+               // @broken: Throws an exception
+               // extTest( '.NET', null, 'Leading dot is (or is not?) an extension' );
+       } );
 
-QUnit.test( 'getExtension', 7, function ( assert ) {
+       QUnit.test( 'exists', 3, function ( assert ) {
+               var title;
 
-       function extTest( pagename, ext, description ) {
-               var title = new mw.Title( pagename );
-               assert.equal( title.getExtension(), ext, description || pagename );
-       }
+               // Empty registry, checks default to null
 
-       extTest( 'MediaWiki:Vector.js', 'js' );
-       extTest( 'User:Example/common.css', 'css' );
-       extTest( 'File:Example.longextension', 'longextension', 'Extension parsing not limited (bug 36151)' );
-       extTest( 'Example/information.json', 'json', 'Extension parsing not restricted from any namespace' );
-       extTest( 'Foo.', null, 'Trailing dot is not an extension' );
-       extTest( 'Foo..', null, 'Trailing dots are not an extension' );
-       extTest( 'Foo.a.', null, 'Page name with dots and ending in a dot does not have an extension' );
+               title = new mw.Title( 'Some random page', 4 );
+               assert.strictEqual( title.exists(), null, 'Return null with empty existance registry' );
 
-       // @broken: Throws an exception
-       // extTest( '.NET', null, 'Leading dot is (or is not?) an extension' );
-});
+               // Basic registry, checks default to boolean
+               mw.Title.exist.set( ['Does_exist', 'User_talk:NeilK', 'Wikipedia:Sandbox_rules'], true );
+               mw.Title.exist.set( ['Does_not_exist', 'User:John', 'Foobar'], false );
 
-QUnit.test( 'exists', 3, function ( assert ) {
-       var title;
+               title = new mw.Title( 'Project:Sandbox rules' );
+               assert.assertTrue( title.exists(), 'Return true for page titles marked as existing' );
+               title = new mw.Title( 'Foobar' );
+               assert.assertFalse( title.exists(), 'Return false for page titles marked as nonexistent' );
 
-       // Empty registry, checks default to null
+       } );
 
-       title = new mw.Title( 'Some random page', 4 );
-       assert.strictEqual( title.exists(), null, 'Return null with empty existance registry' );
+       QUnit.test( 'getUrl', 2, function ( assert ) {
+               var title;
 
-       // Basic registry, checks default to boolean
-       mw.Title.exist.set( ['Does_exist', 'User_talk:NeilK', 'Wikipedia:Sandbox_rules'], true );
-       mw.Title.exist.set( ['Does_not_exist', 'User:John', 'Foobar'], false );
+               // Config
+               mw.config.set( 'wgArticlePath', '/wiki/$1' );
 
-       title = new mw.Title( 'Project:Sandbox rules' );
-       assert.assertTrue( title.exists(), 'Return true for page titles marked as existing' );
-       title = new mw.Title( 'Foobar' );
-       assert.assertFalse( title.exists(), 'Return false for page titles marked as nonexistent' );
+               title = new mw.Title( 'Foobar' );
+               assert.equal( title.getUrl(), '/wiki/Foobar', 'Basic functionally, toString passing to wikiGetlink' );
 
-});
+               title = new mw.Title( 'John Doe', 3 );
+               assert.equal( title.getUrl(), '/wiki/User_talk:John_Doe', 'Escaping in title and namespace for urls' );
+       } );
 
-QUnit.test( 'getUrl', 2, function ( assert ) {
-       var title;
-
-       // Config
-       mw.config.set( 'wgArticlePath', '/wiki/$1' );
-
-       title = new mw.Title( 'Foobar' );
-       assert.equal( title.getUrl(), '/wiki/Foobar', 'Basic functionally, toString passing to wikiGetlink' );
-
-       title = new mw.Title( 'John Doe', 3 );
-       assert.equal( title.getUrl(), '/wiki/User_talk:John_Doe', 'Escaping in title and namespace for urls' );
-});
-
-}( mediaWiki ) );
\ No newline at end of file
+}( mediaWiki ) );
index 9eb2efc..9913f5e 100644 (file)
@@ -1,5 +1,5 @@
 ( function ( mw, $ ) {
-       QUnit.module( 'mediawiki.Uri', QUnit.newMwEnvironment({
+       QUnit.module( 'mediawiki.Uri', QUnit.newMwEnvironment( {
                setup: function () {
                        this.mwUriOrg = mw.Uri;
                        mw.Uri = mw.UriRelative( 'http://example.org/w/index.php' );
@@ -8,7 +8,7 @@
                        mw.Uri = this.mwUriOrg;
                        delete this.mwUriOrg;
                }
-       }) );
+       } ) );
 
        $.each( [true, false], function ( i, strictMode ) {
                QUnit.test( 'Basic construction and properties (' + ( strictMode ? '' : 'non-' ) + 'strict mode)', 2, function ( assert ) {
@@ -16,7 +16,7 @@
                        uriString = 'http://www.ietf.org/rfc/rfc2396.txt';
                        uri = new mw.Uri( uriString, {
                                strictMode: strictMode
-                       });
+                       } );
 
                        assert.deepEqual(
                                {
                                },
                                'construct composite components of URI on request'
                        );
-
-               });
-       });
+               } );
+       } );
 
        QUnit.test( 'Constructor( String[, Object ] )', 10, function ( assert ) {
                var uri;
 
                uri = new mw.Uri( 'http://www.example.com/dir/?m=foo&m=bar&n=1', {
                        overrideKeys: true
-               });
+               } );
 
                // Strict comparison to assert that numerical values stay strings
                assert.strictEqual( uri.query.n, '1', 'Simple parameter with overrideKeys:true' );
@@ -73,7 +72,7 @@
 
                uri = new mw.Uri( 'http://www.example.com/dir/?m=foo&m=bar&n=1', {
                        overrideKeys: false
-               });
+               } );
 
                assert.strictEqual( uri.query.n, '1', 'Simple parameter with overrideKeys:false' );
                assert.strictEqual( uri.query.m[0], 'foo', 'Order of multi-value parameters with overrideKeys:true' );
                        function () {
                                return new mw.Uri( 'foo.com/bar/baz', {
                                        strictMode: true
-                               });
+                               } );
                        },
                        function ( e ) {
                                return e.message === 'Bad constructor arguments';
 
                uri = new mw.Uri( 'foo.com/bar/baz', {
                        strictMode: false
-               });
+               } );
                assert.equal( uri.toString(), 'http://foo.com/bar/baz', 'normalize URI without protocol or // in loose mode' );
-       });
+       } );
 
        QUnit.test( 'Constructor( Object )', 3, function ( assert ) {
-               var uri = new mw.Uri({
+               var uri = new mw.Uri( {
                        protocol: 'http',
                        host: 'www.foo.local',
                        path: '/this'
-               });
+               } );
                assert.equal( uri.toString(), 'http://www.foo.local/this', 'Basic properties' );
 
-               uri = new mw.Uri({
+               uri = new mw.Uri( {
                        protocol: 'http',
                        host: 'www.foo.local',
                        path: '/this',
                        query: { hi: 'there' },
                        fragment: 'blah'
-               });
+               } );
                assert.equal( uri.toString(), 'http://www.foo.local/this?hi=there#blah', 'More complex properties' );
 
                assert.throws(
                        function () {
-                               return new mw.Uri({
+                               return new mw.Uri( {
                                        protocol: 'http',
                                        host: 'www.foo.local'
-                               });
+                               } );
                        },
                        function ( e ) {
                                return e.message === 'Bad constructor arguments';
                uri = uriBase.clone();
                uri.query.foo = 'bar';
                assert.equal( uri.toString(), 'http://en.wiki.local/w/api.php?foo=bar', 'extend query arguments' );
-               uri.extend({
+               uri.extend( {
                        foo: 'quux',
                        pif: 'paf'
-               });
+               } );
                assert.ok( uri.toString().indexOf( 'foo=quux' ) >= 0, 'extend query arguments' );
                assert.ok( uri.toString().indexOf( 'foo=bar' ) === -1, 'extend query arguments' );
-               assert.ok( uri.toString().indexOf( 'pif=paf' ) >= 0 , 'extend query arguments' );
+               assert.ok( uri.toString().indexOf( 'pif=paf' ) >= 0, 'extend query arguments' );
        } );
 
        QUnit.test( '.getQueryString()', 2, function ( assert ) {
 
                uri = new mw.Uri( 'http://www.example.com/dir/?m=foo&m=bar&n=1', {
                        overrideKeys: true
-               });
+               } );
 
                uri.query.n = [ 'x', 'y', 'z' ];
 
 
                uri = new mw.Uri( 'http://www.example.com/dir/?m=foo&m=bar&n=1', {
                        overrideKeys: false
-               });
+               } );
 
                // Change query values
                uri.query.n = [ 'x', 'y', 'z' ];
index b745fb4..779a0ed 100644 (file)
                        [ 1, [ 'one', 'other' ], 'one', 'Hungarian plural test- 1 is one' ],
                        [ 2, [ 'one', 'other' ], 'other', 'Hungarian plural test- 2 is other' ]
                ],
+               hy: [
+                       [ 0, [ 'one', 'other' ], 'other', 'Armenian plural test- 0 is other' ],
+                       [ 1, [ 'one', 'other' ], 'one', 'Armenian plural test- 1 is one' ],
+                       [ 2, [ 'one', 'other' ], 'other', 'Armenian plural test- 2 is other' ]
+               ],
                ar: [
                        [ 0, [ 'zero', 'one', 'two', 'few', 'many', 'other' ], 'zero', 'Arabic plural test - 0 is zero' ],
                        [ 1, [ 'zero', 'one', 'two', 'few', 'many', 'other' ], 'one', 'Arabic plural test - 1 is one' ],
index d7c73e5..388f399 100644 (file)
 ( function ( mw, $ ) {
+       var mwLanguageCache = {}, oldGetOuterHtml, formatnumTests, specialCharactersPageName,
+               expectedListUsers, expectedEntrypoints;
 
-var mwLanguageCache = {}, oldGetOuterHtml, formatnumTests;
-
-QUnit.module( 'mediawiki.jqueryMsg', QUnit.newMwEnvironment( {
-       setup: function () {
-               this.orgMwLangauge = mw.language;
-               mw.language = $.extend( true, {}, this.orgMwLangauge );
-               oldGetOuterHtml = $.fn.getOuterHtml;
-               $.fn.getOuterHtml = function () {
-                       var $div = $( '<div>' ), html;
-                       $div.append( $( this ).eq( 0 ).clone() );
-                       html = $div.html();
-                       $div.empty();
-                       $div = undefined;
-                       return html;
-               };
-       },
-       teardown: function () {
-               mw.language = this.orgMwLangauge;
-               $.fn.getOuterHtml = oldGetOuterHtml;
-       }
-}) );
+       QUnit.module( 'mediawiki.jqueryMsg', QUnit.newMwEnvironment( {
+               setup: function () {
+                       this.orgMwLangauge = mw.language;
+                       mw.language = $.extend( true, {}, this.orgMwLangauge );
+                       oldGetOuterHtml = $.fn.getOuterHtml;
+                       $.fn.getOuterHtml = function () {
+                               var $div = $( '<div>' ), html;
+                               $div.append( $( this ).eq( 0 ).clone() );
+                               html = $div.html();
+                               $div.empty();
+                               $div = undefined;
+                               return html;
+                       };
+
+                       // Messages that are reused in multiple tests
+                       mw.messages.set( {
+                               // The values for gender are not significant,
+                               // what matters is which of the values is choosen by the parser
+                               'gender-msg': '$1: {{GENDER:$2|blue|pink|green}}',
+
+                               'plural-msg': 'Found $1 {{PLURAL:$1|item|items}}',
+
+                               // Assume the grammar form grammar_case_foo is not valid in any language
+                               'grammar-msg': 'Przeszukaj {{GRAMMAR:grammar_case_foo|{{SITENAME}}}}',
+
+                               'formatnum-msg': '{{formatnum:$1}}',
+
+                               'portal-url': 'Project:Community portal',
+                               'see-portal-url': '{{Int:portal-url}} is an important community page.',
+
+                               'jquerymsg-test-statistics-users': '注册[[Special:ListUsers|用户]]',
+
+                               'jquerymsg-test-version-entrypoints-index-php': '[https://www.mediawiki.org/wiki/Manual:index.php index.php]',
 
-function getMwLanguage( langCode, cb ) {
-       if ( mwLanguageCache[langCode] !== undefined ) {
+                               'external-link-replace': 'Foo [$1 bar]'
+                       } );
+
+                       specialCharactersPageName = '"Who" wants to be a millionaire & live on \'Exotic Island\'?';
+
+                       expectedListUsers = '注册' + $( '<a>' ).attr( {
+                               title: 'Special:ListUsers',
+                               href: mw.util.wikiGetlink( 'Special:ListUsers' )
+                       } ).text( '用户' ).getOuterHtml();
+
+                       expectedEntrypoints = '<a href="https://www.mediawiki.org/wiki/Manual:index.php">index.php</a>';
+               },
+               teardown: function () {
+                       mw.language = this.orgMwLangauge;
+                       $.fn.getOuterHtml = oldGetOuterHtml;
+               }
+       } ) );
+
+       function getMwLanguage( langCode, cb ) {
+               if ( mwLanguageCache[langCode] !== undefined ) {
+                       mwLanguageCache[langCode].add( cb );
+                       return;
+               }
+               mwLanguageCache[langCode] = $.Callbacks( 'once memory' );
                mwLanguageCache[langCode].add( cb );
-               return;
+               $.ajax( {
+                       url: mw.util.wikiScript( 'load' ),
+                       data: {
+                               skin: mw.config.get( 'skin' ),
+                               lang: langCode,
+                               debug: mw.config.get( 'debug' ),
+                               modules: [
+                                       'mediawiki.language.data',
+                                       'mediawiki.language'
+                               ].join( '|' ),
+                               only: 'scripts'
+                       },
+                       dataType: 'script'
+               } ).done(function () {
+                               mwLanguageCache[langCode].fire( mw.language );
+                       } ).fail( function () {
+                               mwLanguageCache[langCode].fire( false );
+                       } );
        }
-       mwLanguageCache[langCode] = $.Callbacks( 'once memory' );
-       mwLanguageCache[langCode].add( cb );
-       $.ajax({
-               url: mw.util.wikiScript( 'load' ),
-               data: {
-                       skin: mw.config.get( 'skin' ),
-                       lang: langCode,
-                       debug: mw.config.get( 'debug' ),
-                       modules: [
-                               'mediawiki.language.data',
-                               'mediawiki.language'
-                       ].join( '|' ),
-                       only: 'scripts'
-               },
-               dataType: 'script'
-       }).done( function () {
-               mwLanguageCache[langCode].fire( mw.language );
-       }).fail( function () {
-               mwLanguageCache[langCode].fire( false );
-       });
-}
-
-QUnit.test( 'Replace', 9, function ( assert ) {
-       var parser = mw.jqueryMsg.getMessageFunction();
-
-       mw.messages.set( 'simple', 'Foo $1 baz $2' );
-
-       assert.equal( parser( 'simple' ), 'Foo $1 baz $2', 'Replacements with no substitutes' );
-       assert.equal( parser( 'simple', 'bar' ), 'Foo bar baz $2', 'Replacements with less substitutes' );
-       assert.equal( parser( 'simple', 'bar', 'quux' ), 'Foo bar baz quux', 'Replacements with all substitutes' );
-
-       mw.messages.set( 'plain-input', '<foo foo="foo">x$1y&lt;</foo>z' );
-
-       assert.equal(
-               parser( 'plain-input', 'bar' ),
-               '&lt;foo foo="foo"&gt;xbary&amp;lt;&lt;/foo&gt;z',
-               'Input is not considered html'
-       );
-
-       mw.messages.set( 'plain-replace', 'Foo $1' );
-
-       assert.equal(
-               parser( 'plain-replace', '<bar bar="bar">&gt;</bar>' ),
-               'Foo &lt;bar bar="bar"&gt;&amp;gt;&lt;/bar&gt;',
-               'Replacement is not considered html'
-       );
-
-       mw.messages.set( 'object-replace', 'Foo $1' );
-
-       assert.equal(
-               parser( 'object-replace', $( '<div class="bar">&gt;</div>' ) ),
-               'Foo <div class="bar">&gt;</div>',
-               'jQuery objects are preserved as raw html'
-       );
-
-       assert.equal(
-               parser( 'object-replace', $( '<div class="bar">&gt;</div>' ).get( 0 ) ),
-               'Foo <div class="bar">&gt;</div>',
-               'HTMLElement objects are preserved as raw html'
-       );
-
-       assert.equal(
-               parser( 'object-replace', $( '<div class="bar">&gt;</div>' ).toArray() ),
-               'Foo <div class="bar">&gt;</div>',
-               'HTMLElement[] arrays are preserved as raw html'
-       );
-
-       mw.messages.set( 'wikilink-replace', 'Foo [$1 bar]' );
-       assert.equal(
-               parser( 'wikilink-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'
-       );
-} );
-
-QUnit.test( 'Plural', 3, function ( assert ) {
-       var parser = mw.jqueryMsg.getMessageFunction();
-
-       mw.messages.set( 'plural-msg', 'Found $1 {{PLURAL:$1|item|items}}' );
-       assert.equal( parser( 'plural-msg', 0 ), 'Found 0 items', 'Plural test for english with zero as count' );
-       assert.equal( parser( 'plural-msg', 1 ), 'Found 1 item', 'Singular test for english' );
-       assert.equal( parser( 'plural-msg', 2 ), 'Found 2 items', 'Plural test for english' );
-} );
-
-QUnit.test( 'Gender', 11, function ( assert ) {
-       // TODO: These tests should be for mw.msg once mw.msg integrated with mw.jqueryMsg
-       // TODO: English may not be the best language for these tests. Use a language like Arabic or Russian
-       var user = mw.user,
-               parser = mw.jqueryMsg.getMessageFunction();
-
-       // The values here are not significant,
-       // what matters is which of the values is choosen by the parser
-       mw.messages.set( 'gender-msg', '$1: {{GENDER:$2|blue|pink|green}}' );
-
-       user.options.set( 'gender', 'male' );
-       assert.equal(
-               parser( 'gender-msg', 'Bob', 'male' ),
-               'Bob: blue',
-               'Masculine from string "male"'
-       );
-       assert.equal(
-               parser( 'gender-msg', 'Bob', user ),
-               'Bob: blue',
-               'Masculine from mw.user object'
-       );
-
-       user.options.set( 'gender', 'unknown' );
-       assert.equal(
-               parser( 'gender-msg', 'Foo', user ),
-               'Foo: green',
-               'Neutral from mw.user object' );
-       assert.equal(
-               parser( 'gender-msg', 'Alice', 'female' ),
-               'Alice: pink',
-               'Feminine from string "female"' );
-       assert.equal(
-               parser( 'gender-msg', 'User' ),
-               'User: green',
-               'Neutral when no parameter given' );
-       assert.equal(
-               parser( 'gender-msg', 'User', 'unknown' ),
-               'User: green',
-               'Neutral from string "unknown"'
-       );
-
-       mw.messages.set( 'gender-msg-one-form', '{{GENDER:$1|User}}: $2 {{PLURAL:$2|edit|edits}}' );
-
-       assert.equal(
-               parser( 'gender-msg-one-form', 'male', 10 ),
-               'User: 10 edits',
-               'Gender neutral and plural form'
-       );
-       assert.equal(
-               parser( 'gender-msg-one-form', 'female', 1 ),
-               'User: 1 edit',
-               'Gender neutral and singular form'
-       );
-
-       mw.messages.set( 'gender-msg-lowercase', '{{gender:$1|he|she}} is awesome' );
-       assert.equal(
-               parser( 'gender-msg-lowercase', 'male' ),
-               'he is awesome',
-               'Gender masculine'
-       );
-       assert.equal(
-               parser( 'gender-msg-lowercase', 'female' ),
-               'she is awesome',
-               'Gender feminine'
-       );
-
-       mw.messages.set( 'gender-msg-wrong', '{{gender}} test' );
-       assert.equal(
-               parser( 'gender-msg-wrong', 'female' ),
-               ' test',
-               'Invalid syntax should result in {{gender}} simply being stripped away'
-       );
-} );
-
-QUnit.test( 'Grammar', 2, function ( assert ) {
-       var parser = mw.jqueryMsg.getMessageFunction();
-
-       // Assume the grammar form grammar_case_foo is not valid in any language
-       mw.messages.set( 'grammar-msg', 'Przeszukaj {{GRAMMAR:grammar_case_foo|{{SITENAME}}}}' );
-       assert.equal( parser( 'grammar-msg' ), 'Przeszukaj ' + mw.config.get( 'wgSiteName' ), 'Grammar Test with sitename' );
-
-       mw.messages.set( 'grammar-msg-wrong-syntax', 'Przeszukaj {{GRAMMAR:grammar_case_xyz}}' );
-       assert.equal( parser( 'grammar-msg-wrong-syntax' ), 'Przeszukaj ' , 'Grammar Test with wrong grammar template syntax' );
-} );
-
-QUnit.test( 'Match PHP parser', mw.libs.phpParserData.tests.length, function ( assert ) {
-       mw.messages.set( mw.libs.phpParserData.messages );
-       $.each( mw.libs.phpParserData.tests, function ( i, test ) {
-               QUnit.stop();
-               getMwLanguage( test.lang, function ( langClass ) {
-                       QUnit.start();
-                       if ( !langClass ) {
-                               assert.ok( false, 'Language "' + test.lang + '" failed to load' );
-                               return;
-                       }
-                       mw.config.set( 'wgUserLanguage', test.lang ) ;
-                       var parser = new mw.jqueryMsg.parser( { language: langClass } );
-                       assert.equal(
-                               parser.parse( test.key, test.args ).html(),
-                               test.result,
-                               test.name
-                       );
+
+       QUnit.test( 'Replace', 9, function ( assert ) {
+               var parser = mw.jqueryMsg.getMessageFunction();
+
+               mw.messages.set( 'simple', 'Foo $1 baz $2' );
+
+               assert.equal( parser( 'simple' ), 'Foo $1 baz $2', 'Replacements with no substitutes' );
+               assert.equal( parser( 'simple', 'bar' ), 'Foo bar baz $2', 'Replacements with less substitutes' );
+               assert.equal( parser( 'simple', 'bar', 'quux' ), 'Foo bar baz quux', 'Replacements with all substitutes' );
+
+               mw.messages.set( 'plain-input', '<foo foo="foo">x$1y&lt;</foo>z' );
+
+               assert.equal(
+                       parser( 'plain-input', 'bar' ),
+                       '&lt;foo foo="foo"&gt;xbary&amp;lt;&lt;/foo&gt;z',
+                       'Input is not considered html'
+               );
+
+               mw.messages.set( 'plain-replace', 'Foo $1' );
+
+               assert.equal(
+                       parser( 'plain-replace', '<bar bar="bar">&gt;</bar>' ),
+                       'Foo &lt;bar bar="bar"&gt;&amp;gt;&lt;/bar&gt;',
+                       'Replacement is not considered html'
+               );
+
+               mw.messages.set( 'object-replace', 'Foo $1' );
+
+               assert.equal(
+                       parser( 'object-replace', $( '<div class="bar">&gt;</div>' ) ),
+                       'Foo <div class="bar">&gt;</div>',
+                       'jQuery objects are preserved as raw html'
+               );
+
+               assert.equal(
+                       parser( 'object-replace', $( '<div class="bar">&gt;</div>' ).get( 0 ) ),
+                       'Foo <div class="bar">&gt;</div>',
+                       'HTMLElement objects are preserved as raw html'
+               );
+
+               assert.equal(
+                       parser( 'object-replace', $( '<div class="bar">&gt;</div>' ).toArray() ),
+                       'Foo <div class="bar">&gt;</div>',
+                       'HTMLElement[] arrays are preserved as raw html'
+               );
+
+               assert.equal(
+                       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'
+               );
+       } );
+
+       QUnit.test( 'Plural', 3, function ( assert ) {
+               var parser = mw.jqueryMsg.getMessageFunction();
+
+               assert.equal( parser( 'plural-msg', 0 ), 'Found 0 items', 'Plural test for english with zero as count' );
+               assert.equal( parser( 'plural-msg', 1 ), 'Found 1 item', 'Singular test for english' );
+               assert.equal( parser( 'plural-msg', 2 ), 'Found 2 items', 'Plural test for english' );
+       } );
+
+       QUnit.test( 'Gender', 11, function ( assert ) {
+               // TODO: These tests should be for mw.msg once mw.msg integrated with mw.jqueryMsg
+               // TODO: English may not be the best language for these tests. Use a language like Arabic or Russian
+               var user = mw.user,
+                       parser = mw.jqueryMsg.getMessageFunction();
+
+               user.options.set( 'gender', 'male' );
+               assert.equal(
+                       parser( 'gender-msg', 'Bob', 'male' ),
+                       'Bob: blue',
+                       'Masculine from string "male"'
+               );
+               assert.equal(
+                       parser( 'gender-msg', 'Bob', user ),
+                       'Bob: blue',
+                       'Masculine from mw.user object'
+               );
+
+               user.options.set( 'gender', 'unknown' );
+               assert.equal(
+                       parser( 'gender-msg', 'Foo', user ),
+                       'Foo: green',
+                       'Neutral from mw.user object' );
+               assert.equal(
+                       parser( 'gender-msg', 'Alice', 'female' ),
+                       'Alice: pink',
+                       'Feminine from string "female"' );
+               assert.equal(
+                       parser( 'gender-msg', 'User' ),
+                       'User: green',
+                       'Neutral when no parameter given' );
+               assert.equal(
+                       parser( 'gender-msg', 'User', 'unknown' ),
+                       'User: green',
+                       'Neutral from string "unknown"'
+               );
+
+               mw.messages.set( 'gender-msg-one-form', '{{GENDER:$1|User}}: $2 {{PLURAL:$2|edit|edits}}' );
+
+               assert.equal(
+                       parser( 'gender-msg-one-form', 'male', 10 ),
+                       'User: 10 edits',
+                       'Gender neutral and plural form'
+               );
+               assert.equal(
+                       parser( 'gender-msg-one-form', 'female', 1 ),
+                       'User: 1 edit',
+                       'Gender neutral and singular form'
+               );
+
+               mw.messages.set( 'gender-msg-lowercase', '{{gender:$1|he|she}} is awesome' );
+               assert.equal(
+                       parser( 'gender-msg-lowercase', 'male' ),
+                       'he is awesome',
+                       'Gender masculine'
+               );
+               assert.equal(
+                       parser( 'gender-msg-lowercase', 'female' ),
+                       'she is awesome',
+                       'Gender feminine'
+               );
+
+               mw.messages.set( 'gender-msg-wrong', '{{gender}} test' );
+               assert.equal(
+                       parser( 'gender-msg-wrong', 'female' ),
+                       ' test',
+                       'Invalid syntax should result in {{gender}} simply being stripped away'
+               );
+       } );
+
+       QUnit.test( 'Grammar', 2, function ( assert ) {
+               var parser = mw.jqueryMsg.getMessageFunction();
+
+               assert.equal( parser( 'grammar-msg' ), 'Przeszukaj ' + mw.config.get( 'wgSiteName' ), 'Grammar Test with sitename' );
+
+               mw.messages.set( 'grammar-msg-wrong-syntax', 'Przeszukaj {{GRAMMAR:grammar_case_xyz}}' );
+               assert.equal( parser( 'grammar-msg-wrong-syntax' ), 'Przeszukaj ', 'Grammar Test with wrong grammar template syntax' );
+       } );
+
+       QUnit.test( 'Match PHP parser', mw.libs.phpParserData.tests.length, function ( assert ) {
+               mw.messages.set( mw.libs.phpParserData.messages );
+               $.each( mw.libs.phpParserData.tests, function ( i, test ) {
+                       QUnit.stop();
+                       getMwLanguage( test.lang, function ( langClass ) {
+                               QUnit.start();
+                               if ( !langClass ) {
+                                       assert.ok( false, 'Language "' + test.lang + '" failed to load' );
+                                       return;
+                               }
+                               mw.config.set( 'wgUserLanguage', test.lang );
+                               var parser = new mw.jqueryMsg.parser( { language: langClass } );
+                               assert.equal(
+                                       parser.parse( test.key, test.args ).html(),
+                                       test.result,
+                                       test.name
+                               );
+                       } );
                } );
        } );
-});
-
-QUnit.test( 'Wikilink', 6, function ( assert ) {
-       var parser = mw.jqueryMsg.getMessageFunction(),
-               expectedListUsers,
-               expectedDisambiguationsText,
-               expectedMultipleBars,
-               expectedSpecialCharacters,
-               specialCharactersPageName;
-
-       /*
-        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|用户]]' );
-
-       expectedListUsers = '注册' + $( '<a>' ).attr( {
-               title: 'Special:ListUsers',
-               href: mw.util.wikiGetlink( 'Special:ListUsers' )
-       } ).text( '用户' ).getOuterHtml();
-
-       assert.equal(
-               parser( 'statistics-users' ),
-               expectedListUsers,
-               'Piped wikilink'
-       );
-
-       expectedDisambiguationsText = 'The following pages contain at least one link to a disambiguation page.\nThey may have to link to a more appropriate page instead.\nA page is treated as a disambiguation page if it uses a template that is linked from ' +
-               $( '<a>' ).attr( {
-                       title: 'MediaWiki:Disambiguationspage',
-                       href: mw.util.wikiGetlink( 'MediaWiki:Disambiguationspage' )
-               } ).text( 'MediaWiki:Disambiguationspage' ).getOuterHtml() + '.';
-       mw.messages.set( 'disambiguations-text', 'The following pages contain at least one link to a disambiguation page.\nThey may have to link to a more appropriate page instead.\nA page is treated as a disambiguation page if it uses a template that is linked from [[MediaWiki:Disambiguationspage]].' );
-       assert.equal(
-               parser( 'disambiguations-text' ),
-               expectedDisambiguationsText,
-               'Wikilink without pipe'
-       );
-
-       mw.messages.set( 'version-entrypoints-index-php', '[https://www.mediawiki.org/wiki/Manual:index.php index.php]' );
-       assert.equal(
-               parser( 'version-entrypoints-index-php' ),
-               '<a href="https://www.mediawiki.org/wiki/Manual:index.php">index.php</a>',
-               'External link'
-       );
-
-       // Pipe trick is not supported currently, but should not parse as text either.
-       mw.messages.set( 'pipe-trick', '[[Tampa, Florida|]]' );
-       assert.equal(
-               parser( 'pipe-trick' ),
-               'pipe-trick: Parse error at position 0 in input: [[Tampa, Florida|]]',
-               'Pipe trick should return error string.'
-       );
-
-       expectedMultipleBars = $( '<a>' ).attr( {
-               title: 'Main Page',
-               href: mw.util.wikiGetlink( 'Main Page' )
-       } ).text( 'Main|Page' ).getOuterHtml();
-       mw.messages.set( 'multiple-bars', '[[Main Page|Main|Page]]' );
-       assert.equal(
-               parser( 'multiple-bars' ),
-               expectedMultipleBars,
-               'Bar in anchor'
-       );
-
-       specialCharactersPageName = '"Who" wants to be a millionaire & live on \'Exotic Island\'?';
-       expectedSpecialCharacters = $( '<a>' ).attr( {
-               title: specialCharactersPageName,
-               href: mw.util.wikiGetlink( specialCharactersPageName )
-       } ).text( specialCharactersPageName ).getOuterHtml();
-
-       mw.messages.set( 'special-characters', '[[' + specialCharactersPageName + ']]' );
-       assert.equal(
-               parser( 'special-characters' ),
-               expectedSpecialCharacters,
-               'Special characters'
-       );
-});
-
-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.',
-               expectedNewarticletext;
-
-       mw.messages.set( 'helppage', 'Help:Contents' );
-
-       expectedNewarticletext = '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 ' +
-               $( '<a>' ).attr( {
-                       title: mw.msg( 'helppage' ),
-                       href: mw.util.wikiGetlink( mw.msg( 'helppage' ) )
-               } ).text( 'help page' ).getOuterHtml() + ' for more info). If you are here by mistake, click your browser\'s back button.';
-
-       mw.messages.set( 'newarticletext', newarticletextSource );
-
-       assert.equal(
-               parser( 'newarticletext' ),
-               expectedNewarticletext,
-               'Link with nested message'
-       );
-
-       mw.messages.set( 'portal-url', 'Project:Community portal' );
-       mw.messages.set( 'see-portal-url', '{{Int:portal-url}} is an important community page.' );
-       assert.equal(
-               parser( 'see-portal-url' ),
-               'Project:Community portal is an important community page.',
-               'Nested message'
-       );
-
-       mw.messages.set( 'newarticletext-lowercase',
-               newarticletextSource.replace( 'Int:Helppage', 'int:helppage' ) );
-
-       assert.equal(
-               parser( 'newarticletext-lowercase' ),
-               expectedNewarticletext,
-               'Link with nested message, lowercase include'
-       );
-
-       mw.messages.set( 'uses-missing-int', '{{int:doesnt-exist}}' );
-
-       assert.equal(
-               parser( 'uses-missing-int' ),
-               '[doesnt-exist]',
-               'int: where nested message does not exist'
-       );
-});
-
-// 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;
-
-       map = new mw.Map();
-       map.set( {
-               'curly-brace': '{{int:message}}',
-               'single-square-bracket': '[https://www.mediawiki.org/ MediaWiki]',
-               'double-square-bracket': '[[Some page]]',
-               'regular': 'Other message'
+
+       QUnit.test( 'Links', 6, function ( assert ) {
+               var parser = mw.jqueryMsg.getMessageFunction(),
+                       expectedDisambiguationsText,
+                       expectedMultipleBars,
+                       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.
+                */
+
+               assert.equal(
+                       parser( 'jquerymsg-test-statistics-users' ),
+                       expectedListUsers,
+                       'Piped wikilink'
+               );
+
+               expectedDisambiguationsText = 'The following pages contain at least one link to a disambiguation page.\nThey may have to link to a more appropriate page instead.\nA page is treated as a disambiguation page if it uses a template that is linked from ' +
+                       $( '<a>' ).attr( {
+                               title: 'MediaWiki:Disambiguationspage',
+                               href: mw.util.wikiGetlink( 'MediaWiki:Disambiguationspage' )
+                       } ).text( 'MediaWiki:Disambiguationspage' ).getOuterHtml() + '.';
+               mw.messages.set( 'disambiguations-text', 'The following pages contain at least one link to a disambiguation page.\nThey may have to link to a more appropriate page instead.\nA page is treated as a disambiguation page if it uses a template that is linked from [[MediaWiki:Disambiguationspage]].' );
+               assert.equal(
+                       parser( 'disambiguations-text' ),
+                       expectedDisambiguationsText,
+                       'Wikilink without pipe'
+               );
+
+               assert.equal(
+                       parser( 'jquerymsg-test-version-entrypoints-index-php' ),
+                       expectedEntrypoints,
+                       'External link'
+               );
+
+               // Pipe trick is not supported currently, but should not parse as text either.
+               mw.messages.set( 'pipe-trick', '[[Tampa, Florida|]]' );
+               assert.equal(
+                       parser( 'pipe-trick' ),
+                       'pipe-trick: Parse error at position 0 in input: [[Tampa, Florida|]]',
+                       'Pipe trick should return error string.'
+               );
+
+               expectedMultipleBars = $( '<a>' ).attr( {
+                       title: 'Main Page',
+                       href: mw.util.wikiGetlink( 'Main Page' )
+               } ).text( 'Main|Page' ).getOuterHtml();
+               mw.messages.set( 'multiple-bars', '[[Main Page|Main|Page]]' );
+               assert.equal(
+                       parser( 'multiple-bars' ),
+                       expectedMultipleBars,
+                       'Bar in anchor'
+               );
+
+               expectedSpecialCharacters = $( '<a>' ).attr( {
+                       title: specialCharactersPageName,
+                       href: mw.util.wikiGetlink( specialCharactersPageName )
+               } ).text( specialCharactersPageName ).getOuterHtml();
+
+               mw.messages.set( 'special-characters', '[[' + specialCharactersPageName + ']]' );
+               assert.equal(
+                       parser( 'special-characters' ),
+                       expectedSpecialCharacters,
+                       'Special characters'
+               );
        } );
 
-       oldGMF = mw.jqueryMsg.getMessageFunction;
+// Tests that {{-transformation vs. general parsing are done as requested
+       QUnit.test( 'Curly brace transformation', 14, function ( assert ) {
+               var formatText, formatParse, oldUserLang;
+
+               oldUserLang = mw.config.get( 'wgUserLanguage' );
+
+               formatText = mw.jqueryMsg.getMessageFunction( {
+                       format: 'text'
+               } );
+
+               formatParse = mw.jqueryMsg.getMessageFunction( {
+                       format: 'parse'
+               } );
+
+               // When the expected result is the same in both modes
+               function assertBothModes( parserArguments, expectedResult, assertMessage ) {
+                       assert.equal( formatText.apply( null, parserArguments ), expectedResult, assertMessage + ' when format is \'text\'' );
+                       assert.equal( formatParse.apply( null, parserArguments ), expectedResult, assertMessage + ' when format is \'parse\'' );
+               }
+
+               assertBothModes( ['gender-msg', 'Bob', 'male'], 'Bob: blue', 'gender is resolved' );
+
+               assertBothModes( ['plural-msg', 5], 'Found 5 items', 'plural is resolved' );
+
+               assertBothModes( ['grammar-msg'], 'Przeszukaj ' + mw.config.get( 'wgSiteName' ), 'grammar is resolved' );
+
+               mw.config.set( 'wgUserLanguage', 'en' );
+               assertBothModes( ['formatnum-msg', '987654321.654321'], '987654321.654321', 'formatnum is resolved' );
+
+               // Test non-{{ wikitext, where behavior differs
+
+               // Wikilink
+               assert.equal(
+                       formatText( 'jquerymsg-test-statistics-users' ),
+                       mw.messages.get( 'jquerymsg-test-statistics-users' ),
+                       'Internal link message unchanged when format is \'text\''
+               );
+               assert.equal(
+                       formatParse( 'jquerymsg-test-statistics-users' ),
+                       expectedListUsers,
+                       'Internal link message parsed when format is \'parse\''
+               );
+
+               // External link
+               assert.equal(
+                       formatText( 'jquerymsg-test-version-entrypoints-index-php' ),
+                       mw.messages.get( 'jquerymsg-test-version-entrypoints-index-php' ),
+                       'External link message unchanged when format is \'text\''
+               );
+               assert.equal(
+                       formatParse( 'jquerymsg-test-version-entrypoints-index-php' ),
+                       expectedEntrypoints,
+                       'External link message processed when format is \'parse\''
+               );
+
+               // External link with parameter
+               assert.equal(
+                       formatText( 'external-link-replace', 'http://example.com' ),
+                       'Foo [http://example.com bar]',
+                       'External link message only substitutes parameter when format is \'text\''
+               );
+               assert.equal(
+                       formatParse( 'external-link-replace', 'http://example.com' ),
+                       'Foo <a href="http://example.com">bar</a>',
+                       'External link message processed when format is \'parse\''
+               );
+
+               mw.config.set( 'wgUserLanguage', oldUserLang );
+       } );
+
+       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.',
+                       expectedNewarticletext;
+
+               mw.messages.set( 'helppage', 'Help:Contents' );
+
+               expectedNewarticletext = '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 ' +
+                       $( '<a>' ).attr( {
+                               title: mw.msg( 'helppage' ),
+                               href: mw.util.wikiGetlink( mw.msg( 'helppage' ) )
+                       } ).text( 'help page' ).getOuterHtml() + ' for more info). If you are here by mistake, click your browser\'s back button.';
+
+               mw.messages.set( 'newarticletext', newarticletextSource );
+
+               assert.equal(
+                       parser( 'newarticletext' ),
+                       expectedNewarticletext,
+                       'Link with nested message'
+               );
+
+               assert.equal(
+                       parser( 'see-portal-url' ),
+                       'Project:Community portal is an important community page.',
+                       'Nested message'
+               );
+
+               mw.messages.set( 'newarticletext-lowercase',
+                       newarticletextSource.replace( 'Int:Helppage', 'int:helppage' ) );
+
+               assert.equal(
+                       parser( 'newarticletext-lowercase' ),
+                       expectedNewarticletext,
+                       'Link with nested message, lowercase include'
+               );
+
+               mw.messages.set( 'uses-missing-int', '{{int:doesnt-exist}}' );
+
+               assert.equal(
+                       parser( 'uses-missing-int' ),
+                       '[doesnt-exist]',
+                       'int: where nested message does not exist'
+               );
+       } );
+
+// Tests that getMessageFunction is used for non-plain messages with curly braces or
+// square brackets, but not otherwise.
+       QUnit.test( 'mw.Message.prototype.parser monkey-patch', 22, function ( assert ) {
+               var oldGMF, outerCalled, innerCalled;
+
+               mw.messages.set( {
+                       'curly-brace': '{{int:message}}',
+                       'single-square-bracket': '[https://www.mediawiki.org/ MediaWiki]',
+                       'double-square-bracket': '[[Some page]]',
+                       'regular': 'Other message'
+               } );
+
+               oldGMF = mw.jqueryMsg.getMessageFunction;
 
-       mw.jqueryMsg.getMessageFunction = function() {
-               outerCalled = true;
-               return function() {
-                       innerCalled = true;
+               mw.jqueryMsg.getMessageFunction = function () {
+                       outerCalled = true;
+                       return function () {
+                               innerCalled = true;
+                       };
                };
-       };
-
-       function verifyGetMessageFunction( key, shouldCall ) {
-               outerCalled = false;
-               innerCalled = false;
-               ( new mw.Message( map, key ) ).parser();
-               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 );
-
-       mw.jqueryMsg.getMessageFunction = oldGMF;
-} );
-
-formatnumTests = [
-       {
-               lang: 'en',
-               number: 987654321.654321,
-               result: '987654321.654321',
-               description: 'formatnum test for English, decimal seperator'
-       },
-       {
-               lang: 'ar',
-               number: 987654321.654321,
-               result: '٩٨٧٦٥٤٣٢١٫٦٥٤٣٢١',
-               description: 'formatnum test for Arabic, with decimal seperator'
-       },
-       {
-               lang: 'ar',
-               number: '٩٨٧٦٥٤٣٢١٫٦٥٤٣٢١',
-               result: 987654321,
-               integer: true,
-               description: 'formatnum test for Arabic, with decimal seperator, reverse'
-       },
-       {
-               lang: 'ar',
-               number: -12.89,
-               result: '-١٢٫٨٩',
-               description: 'formatnum test for Arabic, negative number'
-       },
-       {
-               lang: 'ar',
-               number: '-١٢٫٨٩',
-               result: -12,
-               integer: true,
-               description: 'formatnum test for Arabic, negative number, reverse'
-       },
-       {
-               lang: 'nl',
-               number: 987654321.654321,
-               result: '987654321,654321',
-               description: 'formatnum test for Nederlands, decimal seperator'
-       },
-       {
-               lang: 'nl',
-               number: -12.89,
-               result: '-12,89',
-               description: 'formatnum test for Nederlands, negative number'
-       },
-       {
-               lang: 'nl',
-               number: 'invalidnumber',
-               result: 'invalidnumber',
-               description: 'formatnum test for Nederlands, invalid number'
-       }
-];
-
-QUnit.test( 'formatnum', formatnumTests.length, function ( assert ) {
-       mw.messages.set( 'formatnum-msg', '{{formatnum:$1}}' );
-       mw.messages.set( 'formatnum-msg-int', '{{formatnum:$1|R}}' );
-       $.each( formatnumTests, function ( i, test ) {
-               QUnit.stop();
-               getMwLanguage( test.lang, function ( langClass ) {
-                       QUnit.start();
-                       if ( !langClass ) {
-                               assert.ok( false, 'Language "' + test.lang + '" failed to load' );
-                               return;
-                       }
-                       mw.messages.set(test.message );
-                       mw.config.set( 'wgUserLanguage', test.lang ) ;
-                       var parser = new mw.jqueryMsg.parser( { language: langClass } );
-                       assert.equal(
-                               parser.parse( test.integer ? 'formatnum-msg-int' : 'formatnum-msg',
-                                       [ test.number ] ).html(),
-                               test.result,
-                               test.description
-                       );
+               function verifyGetMessageFunction( key, format, shouldCall ) {
+                       var message;
+                       outerCalled = false;
+                       innerCalled = false;
+                       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', '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;
+       } );
+
+       formatnumTests = [
+               {
+                       lang: 'en',
+                       number: 987654321.654321,
+                       result: '987654321.654321',
+                       description: 'formatnum test for English, decimal seperator'
+               },
+               {
+                       lang: 'ar',
+                       number: 987654321.654321,
+                       result: '٩٨٧٦٥٤٣٢١٫٦٥٤٣٢١',
+                       description: 'formatnum test for Arabic, with decimal seperator'
+               },
+               {
+                       lang: 'ar',
+                       number: '٩٨٧٦٥٤٣٢١٫٦٥٤٣٢١',
+                       result: 987654321,
+                       integer: true,
+                       description: 'formatnum test for Arabic, with decimal seperator, reverse'
+               },
+               {
+                       lang: 'ar',
+                       number: -12.89,
+                       result: '-١٢٫٨٩',
+                       description: 'formatnum test for Arabic, negative number'
+               },
+               {
+                       lang: 'ar',
+                       number: '-١٢٫٨٩',
+                       result: -12,
+                       integer: true,
+                       description: 'formatnum test for Arabic, negative number, reverse'
+               },
+               {
+                       lang: 'nl',
+                       number: 987654321.654321,
+                       result: '987654321,654321',
+                       description: 'formatnum test for Nederlands, decimal seperator'
+               },
+               {
+                       lang: 'nl',
+                       number: -12.89,
+                       result: '-12,89',
+                       description: 'formatnum test for Nederlands, negative number'
+               },
+               {
+                       lang: 'nl',
+                       number: 'invalidnumber',
+                       result: 'invalidnumber',
+                       description: 'formatnum test for Nederlands, invalid number'
+               }
+       ];
+
+       QUnit.test( 'formatnum', formatnumTests.length, function ( assert ) {
+               mw.messages.set( 'formatnum-msg-int', '{{formatnum:$1|R}}' );
+               $.each( formatnumTests, function ( i, test ) {
+                       QUnit.stop();
+                       getMwLanguage( test.lang, function ( langClass ) {
+                               QUnit.start();
+                               if ( !langClass ) {
+                                       assert.ok( false, 'Language "' + test.lang + '" failed to load' );
+                                       return;
+                               }
+                               mw.messages.set( test.message );
+                               mw.config.set( 'wgUserLanguage', test.lang );
+                               var parser = new mw.jqueryMsg.parser( { language: langClass } );
+                               assert.equal(
+                                       parser.parse( test.integer ? 'formatnum-msg-int' : 'formatnum-msg',
+                                               [ test.number ] ).html(),
+                                       test.result,
+                                       test.description
+                               );
+                       } );
                } );
        } );
-});
 
 }( mediaWiki, jQuery ) );
index bc6fafe..3328ce3 100644 (file)
@@ -14,7 +14,7 @@
                assert.deepEqual( ŝablono, orig, 'ŝablono' );
                assert.deepEqual( \u015dablono, orig, '\\u015dablono' );
                assert.deepEqual( \u015Dablono, orig, '\\u015Dablono' );
-       });
+       } );
 
        /*
        // Not that we need this. ;)
                }
 
                for ( n = 0; n < maxn; n++ ) {
-                       expected = repeat('\n', n) + 'some text';
+                       expected = repeat( '\n', n ) + 'some text';
 
-                       $textarea = $('<textarea>\n' + expected + '</textarea>');
+                       $textarea = $( '<textarea>\n' + expected + '</textarea>' );
                        assert.equal( $textarea.val(), expected, 'Expecting ' + n + ' newlines (HTML contained ' + (n + 1) + ')' );
 
-                       $textarea = $('<textarea>').val( expected );
+                       $textarea = $( '<textarea>' ).val( expected );
                        assert.equal( $textarea.val(), expected, 'Expecting ' + n + ' newlines (from DOM set with ' + n + ')' );
                }
-       });
+       } );
 }( jQuery ) );
index 869ebe4..7cfa46a 100644 (file)
@@ -1,6 +1,6 @@
 ( function ( mw, $ ) {
 
-       QUnit.module( 'mediawiki.language', QUnit.newMwEnvironment({
+       QUnit.module( 'mediawiki.language', QUnit.newMwEnvironment( {
                setup: function () {
                        this.liveLangData = mw.language.data.values;
                        mw.language.data.values = $.extend( true, {}, this.liveLangData );
@@ -8,12 +8,12 @@
                teardown: function () {
                        mw.language.data.values = this.liveLangData;
                }
-       }) );
+       } ) );
 
        QUnit.test( 'mw.language getData and setData', 2, function ( assert ) {
                mw.language.setData( 'en', 'testkey', 'testvalue' );
-               assert.equal(  mw.language.getData( 'en', 'testkey' ), 'testvalue', 'Getter setter test for mw.language' );
-               assert.equal(  mw.language.getData( 'en', 'invalidkey' ), undefined, 'Getter setter test for mw.language with invalid key' );
+               assert.equal( mw.language.getData( 'en', 'testkey' ), 'testvalue', 'Getter setter test for mw.language' );
+               assert.equal( mw.language.getData( 'en', 'invalidkey' ), undefined, 'Getter setter test for mw.language with invalid key' );
        } );
 
        function grammarTest( langCode, test ) {
                QUnit.test( 'Grammar test for lang=' + langCode, function ( assert ) {
                        QUnit.expect( test.length );
 
-                       for ( var i = 0 ; i < test.length; i++ ) {
+                       for ( var i = 0; i < test.length; i++ ) {
                                assert.equal(
                                        mw.language.convertGrammar( test[i].word, test[i].grammarForm ),
                                        test[i].expected,
                                        test[i].description
                                );
                        }
-               });
+               } );
        }
 
        var grammarTests = {
                if ( langCode === mw.config.get( 'wgUserLanguage' ) ) {
                        grammarTest( langCode, test );
                }
-       });
+       } );
 }( mediaWiki, jQuery ) );
index dc7bd0a..9b540a8 100644 (file)
 ( function ( mw, $ ) {
+       var specialCharactersPageName;
+
+       // Since QUnitTestResources.php loads both mediawiki and mediawiki.jqueryMsg as
+       // dependencies, this only tests the monkey-patched behavior with the two of them combined.
+
+       // See mediawiki.jqueryMsg.test.js for unit tests for jqueryMsg-specific functionality.
+
+       QUnit.module( 'mediawiki', QUnit.newMwEnvironment( {
+               setup: function () {
+                       // Messages used in multiple tests
+                       mw.messages.set( {
+                               'other-message': 'Other Message',
+                               'mediawiki-test-pagetriage-del-talk-page-notify-summary': 'Notifying author of deletion nomination for [[$1]]',
+                               'gender-plural-msg': '{{GENDER:$1|he|she|they}} {{PLURAL:$2|is|are}} awesome',
+                               'grammar-msg': 'Przeszukaj {{GRAMMAR:grammar_case_foo|{{SITENAME}}}}',
+                               'formatnum-msg': '{{formatnum:$1}}',
+                               'int-msg': 'Some {{int:other-message}}'
+                       } );
 
-QUnit.module( 'mediawiki', QUnit.newMwEnvironment() );
-
-QUnit.test( 'Initial check', 8, function ( assert ) {
-       assert.ok( window.jQuery, 'jQuery defined' );
-       assert.ok( window.$, '$j defined' );
-       assert.ok( window.$j, '$j defined' );
-       assert.strictEqual( window.$, window.jQuery, '$ alias to jQuery' );
-       assert.strictEqual( window.$j, window.jQuery, '$j alias to jQuery' );
-
-       assert.ok( window.mediaWiki, 'mediaWiki defined' );
-       assert.ok( window.mw, 'mw defined' );
-       assert.strictEqual( window.mw, window.mediaWiki, 'mw alias to mediaWiki' );
-});
-
-QUnit.test( 'mw.Map', 17, function ( assert ) {
-       var arry, conf, funky, globalConf, nummy, someValues;
-
-       assert.ok( mw.Map, 'mw.Map defined' );
-
-       conf = new mw.Map();
-       // Dummy variables
-       funky = function () {};
-       arry = [];
-       nummy = 7;
-
-       // Tests for input validation
-       assert.strictEqual( conf.get( 'inexistantKey' ), null, 'Map.get returns null if selection was a string and the key was not found' );
-       assert.strictEqual( conf.set( 'myKey', 'myValue' ), true, 'Map.set returns boolean true if a value was set for a valid key string' );
-       assert.strictEqual( conf.set( funky, 'Funky' ), false, 'Map.set returns boolean false if key was invalid (Function)' );
-       assert.strictEqual( conf.set( arry, 'Arry' ), false, 'Map.set returns boolean false if key was invalid (Array)' );
-       assert.strictEqual( conf.set( nummy, 'Nummy' ), false, 'Map.set returns boolean false if key was invalid (Number)' );
-       assert.equal( conf.get( 'myKey' ), 'myValue', 'Map.get returns a single value value correctly' );
-       assert.strictEqual( conf.get( nummy ), null, 'Map.get ruturns null if selection was invalid (Number)' );
-       assert.strictEqual( conf.get( funky ), null, 'Map.get ruturns null if selection was invalid (Function)' );
-
-       // Multiple values at once
-       someValues = {
-               'foo': 'bar',
-               'lorem': 'ipsum',
-               'MediaWiki': true
-       };
-       assert.strictEqual( conf.set( someValues ), true, 'Map.set returns boolean true if multiple values were set by passing an object' );
-       assert.deepEqual( conf.get( ['foo', 'lorem'] ), {
-               'foo': 'bar',
-               'lorem': 'ipsum'
-       }, 'Map.get returns multiple values correctly as an object' );
-
-       assert.deepEqual( conf.get( ['foo', 'notExist'] ), {
-               'foo': 'bar',
-               'notExist': null
-       }, 'Map.get return includes keys that were not found as null values' );
-
-       assert.strictEqual( conf.exists( 'foo' ), true, 'Map.exists returns boolean true if a key exists' );
-       assert.strictEqual( conf.exists( 'notExist' ), false, 'Map.exists returns boolean false if a key does not exists' );
-
-       // Interacting with globals and accessing the values object
-       assert.strictEqual( conf.get(), conf.values, 'Map.get returns the entire values object by reference (if called without arguments)' );
-
-       conf.set( 'globalMapChecker', 'Hi' );
-
-       assert.ok( false === 'globalMapChecker' in window, 'new mw.Map did not store its values in the global window object by default' );
-
-       globalConf = new mw.Map( true );
-       globalConf.set( 'anotherGlobalMapChecker', 'Hello' );
-
-       assert.ok( 'anotherGlobalMapChecker' in window, 'new mw.Map( true ) did store its values in the global window object' );
-
-       // Whitelist this global variable for QUnit's 'noglobal' mode
-       if ( QUnit.config.noglobals ) {
-               QUnit.config.pollution.push( 'anotherGlobalMapChecker' );
-       }
-});
-
-QUnit.test( 'mw.config', 1, function ( assert ) {
-       assert.ok( mw.config instanceof mw.Map, 'mw.config instance of mw.Map' );
-});
-
-QUnit.test( 'mw.message & mw.messages', 20, function ( assert ) {
-       var goodbye, hello, pluralMessage;
-
-       assert.ok( mw.messages, 'messages defined' );
-       assert.ok( mw.messages instanceof mw.Map, 'mw.messages instance of mw.Map' );
-       assert.ok( mw.messages.set( 'hello', 'Hello <b>awesome</b> world' ), 'mw.messages.set: Register' );
-
-       hello = mw.message( 'hello' );
-
-       assert.equal( hello.format, 'plain', 'Message property "format" defaults to "plain"' );
-       assert.strictEqual( hello.map, mw.messages, 'Message property "map" defaults to the global instance in mw.messages' );
-       assert.equal( hello.key, 'hello', 'Message property "key" (currect key)' );
-       assert.deepEqual( hello.parameters, [], 'Message property "parameters" defaults to an empty array' );
-
-       // Todo
-       assert.ok( hello.params, 'Message prototype "params"' );
-
-       hello.format = 'plain';
-       assert.equal( hello.toString(), 'Hello <b>awesome</b> world', 'Message.toString returns the message as a string with the current "format"' );
-
-       assert.equal( hello.escaped(), 'Hello &lt;b&gt;awesome&lt;/b&gt; world', 'Message.escaped returns the escaped message' );
-       assert.equal( hello.format, 'escaped', 'Message.escaped correctly updated the "format" property' );
-
-       hello.parse();
-       assert.equal( hello.format, 'parse', 'Message.parse correctly updated the "format" property' );
-
-       hello.plain();
-       assert.equal( hello.format, 'plain', 'Message.plain correctly updated the "format" property' );
-
-       assert.strictEqual( hello.exists(), true, 'Message.exists returns true for existing messages' );
-
-       goodbye = mw.message( 'goodbye' );
-       assert.strictEqual( goodbye.exists(), false, 'Message.exists returns false for nonexistent messages' );
-
-       assert.equal( goodbye.plain(), '<goodbye>', 'Message.toString returns plain <key> if format is "plain" and key does not exist' );
-       // bug 30684
-       assert.equal( goodbye.escaped(), '&lt;goodbye&gt;', 'Message.toString returns properly escaped &lt;key&gt; if format is "escaped" and key does not exist' );
-
-       assert.ok( mw.messages.set( 'pluraltestmsg', 'There {{PLURAL:$1|is|are}} $1 {{PLURAL:$1|result|results}}' ), 'mw.messages.set: Register' );
-       pluralMessage = mw.message( 'pluraltestmsg' , 6 );
-       assert.equal( pluralMessage.plain(), 'There are 6 results', 'plural get resolved when format is plain' );
-       assert.equal( pluralMessage.parse(), 'There are 6 results', 'plural get resolved when format is parse' );
-
-});
-
-QUnit.test( 'mw.msg', 11, function ( assert ) {
-       assert.ok( mw.messages.set( 'hello', 'Hello <b>awesome</b> world' ), 'mw.messages.set: Register' );
-       assert.equal( mw.msg( 'hello' ), 'Hello <b>awesome</b> world', 'Gets message with default options (existing message)' );
-       assert.equal( mw.msg( 'goodbye' ), '<goodbye>', 'Gets message with default options (nonexistent message)' );
-
-       assert.ok( mw.messages.set( 'plural-item' , 'Found $1 {{PLURAL:$1|item|items}}' ) );
-       assert.equal( mw.msg( 'plural-item', 5 ), 'Found 5 items', 'Apply plural for count 5' );
-       assert.equal( mw.msg( 'plural-item', 0 ), 'Found 0 items', 'Apply plural for count 0' );
-       assert.equal( mw.msg( 'plural-item', 1 ), 'Found 1 item', 'Apply plural for count 1' );
-
-       assert.ok( mw.messages.set('gender-plural-msg' , '{{GENDER:$1|he|she|they}} {{PLURAL:$2|is|are}} awesome' ) );
-       assert.equal( mw.msg( 'gender-plural-msg', 'male', 1 ), 'he is awesome', 'Gender test for male, plural count 1' );
-       assert.equal( mw.msg( 'gender-plural-msg', 'female', '1' ), 'she is awesome', 'Gender test for female, plural count 1' );
-       assert.equal( mw.msg( 'gender-plural-msg', 'unknown', 10 ), 'they are awesome', 'Gender test for neutral, plural count 10' );
-
-});
-
-/**
- * The sync style load test (for @import). This is, in a way, also an open bug for
- * ResourceLoader ("execute js after styles are loaded"), but browsers don't offer a
- * way to get a callback from when a stylesheet is loaded (that is, including any
- * @import rules inside). To work around this, we'll have a little time loop to check
- * if the styles apply.
- * Note: This test originally used new Image() and onerror to get a callback
- * when the url is loaded, but that is fragile since it doesn't monitor the
- * same request as the css @import, and Safari 4 has issues with
- * onerror/onload not being fired at all in weird cases like this.
- */
-function assertStyleAsync( assert, $element, prop, val, fn ) {
-       var styleTestStart,
-               el = $element.get( 0 ),
-               styleTestTimeout = ( QUnit.config.testTimeout - 200 ) || 5000;
-
-       function isCssImportApplied() {
-               // Trigger reflow, repaint, redraw, whatever (cross-browser)
-               var x = $element.css( 'height' );
-               x = el.innerHTML;
-               el.className = el.className;
-               x = document.documentElement.clientHeight;
-
-               return $element.css( prop ) === val;
-       }
+                       // For formatnum tests
+                       mw.config.set( 'wgUserLanguage', 'en' );
+
+                       specialCharactersPageName = '"Who" wants to be a millionaire & live on \'Exotic Island\'?';
+               }
+       } ) );
+
+       QUnit.test( 'Initial check', 8, function ( assert ) {
+               assert.ok( window.jQuery, 'jQuery defined' );
+               assert.ok( window.$, '$j defined' );
+               assert.ok( window.$j, '$j defined' );
+               assert.strictEqual( window.$, window.jQuery, '$ alias to jQuery' );
+               assert.strictEqual( window.$j, window.jQuery, '$j alias to jQuery' );
+
+               assert.ok( window.mediaWiki, 'mediaWiki defined' );
+               assert.ok( window.mw, 'mw defined' );
+               assert.strictEqual( window.mw, window.mediaWiki, 'mw alias to mediaWiki' );
+       } );
+
+       QUnit.test( 'mw.Map', 17, function ( assert ) {
+               var arry, conf, funky, globalConf, nummy, someValues;
+
+               assert.ok( mw.Map, 'mw.Map defined' );
+
+               conf = new mw.Map();
+               // Dummy variables
+               funky = function () {};
+               arry = [];
+               nummy = 7;
+
+               // Tests for input validation
+               assert.strictEqual( conf.get( 'inexistantKey' ), null, 'Map.get returns null if selection was a string and the key was not found' );
+               assert.strictEqual( conf.set( 'myKey', 'myValue' ), true, 'Map.set returns boolean true if a value was set for a valid key string' );
+               assert.strictEqual( conf.set( funky, 'Funky' ), false, 'Map.set returns boolean false if key was invalid (Function)' );
+               assert.strictEqual( conf.set( arry, 'Arry' ), false, 'Map.set returns boolean false if key was invalid (Array)' );
+               assert.strictEqual( conf.set( nummy, 'Nummy' ), false, 'Map.set returns boolean false if key was invalid (Number)' );
+               assert.equal( conf.get( 'myKey' ), 'myValue', 'Map.get returns a single value value correctly' );
+               assert.strictEqual( conf.get( nummy ), null, 'Map.get ruturns null if selection was invalid (Number)' );
+               assert.strictEqual( conf.get( funky ), null, 'Map.get ruturns null if selection was invalid (Function)' );
+
+               // Multiple values at once
+               someValues = {
+                       'foo': 'bar',
+                       'lorem': 'ipsum',
+                       'MediaWiki': true
+               };
+               assert.strictEqual( conf.set( someValues ), true, 'Map.set returns boolean true if multiple values were set by passing an object' );
+               assert.deepEqual( conf.get( ['foo', 'lorem'] ), {
+                       'foo': 'bar',
+                       'lorem': 'ipsum'
+               }, 'Map.get returns multiple values correctly as an object' );
+
+               assert.deepEqual( conf.get( ['foo', 'notExist'] ), {
+                       'foo': 'bar',
+                       'notExist': null
+               }, 'Map.get return includes keys that were not found as null values' );
+
+               assert.strictEqual( conf.exists( 'foo' ), true, 'Map.exists returns boolean true if a key exists' );
+               assert.strictEqual( conf.exists( 'notExist' ), false, 'Map.exists returns boolean false if a key does not exists' );
+
+               // Interacting with globals and accessing the values object
+               assert.strictEqual( conf.get(), conf.values, 'Map.get returns the entire values object by reference (if called without arguments)' );
+
+               conf.set( 'globalMapChecker', 'Hi' );
+
+               assert.ok( false === 'globalMapChecker' in window, 'new mw.Map did not store its values in the global window object by default' );
+
+               globalConf = new mw.Map( true );
+               globalConf.set( 'anotherGlobalMapChecker', 'Hello' );
+
+               assert.ok( 'anotherGlobalMapChecker' in window, 'new mw.Map( true ) did store its values in the global window object' );
+
+               // Whitelist this global variable for QUnit's 'noglobal' mode
+               if ( QUnit.config.noglobals ) {
+                       QUnit.config.pollution.push( 'anotherGlobalMapChecker' );
+               }
+       } );
+
+       QUnit.test( 'mw.config', 1, function ( assert ) {
+               assert.ok( mw.config instanceof mw.Map, 'mw.config instance of mw.Map' );
+       } );
 
-       function styleTestLoop() {
-               var styleTestSince = new Date().getTime() - styleTestStart;
-               // If it is passing or if we timed out, run the real test and stop the loop
-               if ( isCssImportApplied() || styleTestSince > styleTestTimeout ) {
-                       assert.equal( $element.css( prop ), val,
-                               'style "' + prop + ': ' + val + '" from url is applied (after ' + styleTestSince + 'ms)'
-                       );
+       QUnit.test( 'mw.message & mw.messages', 54, function ( assert ) {
+               var goodbye, hello;
 
-                       if ( fn ) {
-                               fn();
+               // Convenience method for asserting the same result for multiple formats
+               function assertMultipleFormats( messageArguments, formats, expectedResult, assertMessage ) {
+                       var len = formats.length, format, i;
+                       for ( i = 0; i < len; i++ ) {
+                               format = formats[i];
+                               assert.equal( mw.message.apply( null, messageArguments )[format](), expectedResult, assertMessage + ' when format is ' + format );
                        }
+               }
+
+               assert.ok( mw.messages, 'messages defined' );
+               assert.ok( mw.messages instanceof mw.Map, 'mw.messages instance of mw.Map' );
+               assert.ok( mw.messages.set( 'hello', 'Hello <b>awesome</b> world' ), 'mw.messages.set: Register' );
+
+               hello = mw.message( 'hello' );
+
+               // https://bugzilla.wikimedia.org/show_bug.cgi?id=44459
+               assert.equal( hello.format, 'text', 'Message property "format" defaults to "text"' );
+
+               assert.strictEqual( hello.map, mw.messages, 'Message property "map" defaults to the global instance in mw.messages' );
+               assert.equal( hello.key, 'hello', 'Message property "key" (currect key)' );
+               assert.deepEqual( hello.parameters, [], 'Message property "parameters" defaults to an empty array' );
+
+               // Todo
+               assert.ok( hello.params, 'Message prototype "params"' );
+
+               hello.format = 'plain';
+               assert.equal( hello.toString(), 'Hello <b>awesome</b> world', 'Message.toString returns the message as a string with the current "format"' );
+
+               assert.equal( hello.escaped(), 'Hello &lt;b&gt;awesome&lt;/b&gt; world', 'Message.escaped returns the escaped message' );
+               assert.equal( hello.format, 'escaped', 'Message.escaped correctly updated the "format" property' );
+
+               assert.ok( mw.messages.set( 'escaped-with-curly-brace', '"{{SITENAME}}" is the home of {{int:other-message}}' ) );
+               assert.equal( mw.message( 'escaped-with-curly-brace' ).escaped(), mw.html.escape( '"' + mw.config.get( 'wgSiteName' ) + '" is the home of Other Message' ), 'Escaped format works correctly for curly brace message' );
+
+               assert.ok( mw.messages.set( 'escaped-with-square-brackets', 'Visit the [[Project:Community portal|community portal]] & [[Project:Help desk|help desk]]' ) );
+               assert.equal( mw.message( 'escaped-with-square-brackets' ).escaped(), 'Visit the [[Project:Community portal|community portal]] &amp; [[Project:Help desk|help desk]]', 'Escaped format works correctly for square bracket message' );
+
+               hello.parse();
+               assert.equal( hello.format, 'parse', 'Message.parse correctly updated the "format" property' );
+
+               hello.plain();
+               assert.equal( hello.format, 'plain', 'Message.plain correctly updated the "format" property' );
+
+               hello.text();
+               assert.equal( hello.format, 'text', 'Message.text correctly updated the "format" property' );
+
+               assert.strictEqual( hello.exists(), true, 'Message.exists returns true for existing messages' );
+
+               goodbye = mw.message( 'goodbye' );
+               assert.strictEqual( goodbye.exists(), false, 'Message.exists returns false for nonexistent messages' );
+
+               assertMultipleFormats( ['goodbye'], ['plain', 'text'], '<goodbye>', 'Message.toString returns <key> if key does not exist' );
+               // bug 30684
+               assertMultipleFormats( ['goodbye'], ['parse', 'escaped'], '&lt;goodbye&gt;', 'Message.toString returns properly escaped &lt;key&gt; if key does not exist' );
+
+               assert.ok( mw.messages.set( 'plural-test-msg', 'There {{PLURAL:$1|is|are}} $1 {{PLURAL:$1|result|results}}' ), 'mw.messages.set: Register' );
+               assertMultipleFormats( ['plural-test-msg', 6], ['text', 'parse', 'escaped'], 'There are 6 results', 'plural get resolved' );
+               assert.equal( mw.message( 'plural-test-msg', 6 ).plain(), 'There {{PLURAL:6|is|are}} 6 {{PLURAL:6|result|results}}', 'Parameter is substituted but plural is not resolved in plain' );
+
+               assertMultipleFormats( ['mediawiki-test-pagetriage-del-talk-page-notify-summary'], ['plain', 'text'], mw.messages.get( 'mediawiki-test-pagetriage-del-talk-page-notify-summary' ), 'Double square brackets with no parameters unchanged' );
 
-                       return;
+               assertMultipleFormats( ['mediawiki-test-pagetriage-del-talk-page-notify-summary', specialCharactersPageName], ['plain', 'text'], 'Notifying author of deletion nomination for [[' + specialCharactersPageName + ']]', 'Double square brackets with one parameter' );
+
+               assert.equal( mw.message( 'mediawiki-test-pagetriage-del-talk-page-notify-summary', specialCharactersPageName ).escaped(), 'Notifying author of deletion nomination for [[' + mw.html.escape( specialCharactersPageName ) + ']]', 'Double square brackets with one parameter, when escaped' );
+
+
+               assert.ok( mw.messages.set( 'mediawiki-test-categorytree-collapse-bullet', '[<b>−</b>]' ), 'mw.messages.set: Register' );
+               assert.equal( mw.message( 'mediawiki-test-categorytree-collapse-bullet' ).plain(), mw.messages.get( 'mediawiki-test-categorytree-collapse-bullet' ), 'Single square brackets unchanged in plain mode' );
+
+               assert.ok( mw.messages.set( 'mediawiki-test-wikieditor-toolbar-help-content-signature-result', '<a href=\'#\' title=\'{{#special:mypage}}\'>Username</a> (<a href=\'#\' title=\'{{#special:mytalk}}\'>talk</a>)' ) );
+               assert.equal( mw.message( 'mediawiki-test-wikieditor-toolbar-help-content-signature-result' ).plain(), mw.messages.get( 'mediawiki-test-wikieditor-toolbar-help-content-signature-result' ), 'HTML message with curly braces is not changed in plain mode' );
+
+               assertMultipleFormats( ['gender-plural-msg', 'male', 1], ['text', 'parse', 'escaped'], 'he is awesome', 'Gender and plural are resolved' );
+               assert.equal( mw.message( 'gender-plural-msg', 'male', 1 ).plain(), '{{GENDER:male|he|she|they}} {{PLURAL:1|is|are}} awesome', 'Parameters are substituted, but gender and plural are not resolved in plain mode' );
+
+               assert.equal( mw.message( 'grammar-msg' ).plain(), mw.messages.get( 'grammar-msg' ), 'Grammar is not resolved in plain mode' );
+               assertMultipleFormats( ['grammar-msg'], ['text', 'parse'], 'Przeszukaj ' + mw.config.get( 'wgSiteName' ), 'Grammar is resolved' );
+               assert.equal( mw.message( 'grammar-msg' ).escaped(), 'Przeszukaj ' + mw.html.escape( mw.config.get( 'wgSiteName' ) ), 'Grammar is resolved in escaped mode' );
+
+               assertMultipleFormats( ['formatnum-msg', '987654321.654321'], ['text', 'parse', 'escaped'], '987654321.654321', 'formatnum is resolved' );
+               assert.equal( mw.message( 'formatnum-msg' ).plain(), mw.messages.get( 'formatnum-msg' ), 'formatnum is not resolved in plain mode' );
+
+               assertMultipleFormats( ['int-msg'], ['text', 'parse', 'escaped'], 'Some Other Message', 'int is resolved' );
+               assert.equal( mw.message( 'int-msg' ).plain(), mw.messages.get( 'int-msg' ), 'int is not resolved in plain mode' );
+       } );
+
+       QUnit.test( 'mw.msg', 14, function ( assert ) {
+               assert.ok( mw.messages.set( 'hello', 'Hello <b>awesome</b> world' ), 'mw.messages.set: Register' );
+               assert.equal( mw.msg( 'hello' ), 'Hello <b>awesome</b> world', 'Gets message with default options (existing message)' );
+               assert.equal( mw.msg( 'goodbye' ), '<goodbye>', 'Gets message with default options (nonexistent message)' );
+
+               assert.ok( mw.messages.set( 'plural-item', 'Found $1 {{PLURAL:$1|item|items}}' ) );
+               assert.equal( mw.msg( 'plural-item', 5 ), 'Found 5 items', 'Apply plural for count 5' );
+               assert.equal( mw.msg( 'plural-item', 0 ), 'Found 0 items', 'Apply plural for count 0' );
+               assert.equal( mw.msg( 'plural-item', 1 ), 'Found 1 item', 'Apply plural for count 1' );
+
+               assert.equal( mw.msg( 'mediawiki-test-pagetriage-del-talk-page-notify-summary', specialCharactersPageName ), 'Notifying author of deletion nomination for [[' + specialCharactersPageName + ']]', 'Double square brackets in mw.msg one parameter' );
+
+               assert.equal( mw.msg( 'gender-plural-msg', 'male', 1 ), 'he is awesome', 'Gender test for male, plural count 1' );
+               assert.equal( mw.msg( 'gender-plural-msg', 'female', '1' ), 'she is awesome', 'Gender test for female, plural count 1' );
+               assert.equal( mw.msg( 'gender-plural-msg', 'unknown', 10 ), 'they are awesome', 'Gender test for neutral, plural count 10' );
+
+               assert.equal( mw.msg( 'grammar-msg' ), 'Przeszukaj ' + mw.config.get( 'wgSiteName' ), 'Grammar is resolved' );
+
+               assert.equal( mw.msg( 'formatnum-msg', '987654321.654321' ), '987654321.654321', 'formatnum is resolved' );
+
+               assert.equal( mw.msg( 'int-msg' ), 'Some Other Message', 'int is resolved' );
+       } );
+
+       /**
+        * The sync style load test (for @import). This is, in a way, also an open bug for
+        * ResourceLoader ("execute js after styles are loaded"), but browsers don't offer a
+        * way to get a callback from when a stylesheet is loaded (that is, including any
+        * @import rules inside). To work around this, we'll have a little time loop to check
+        * if the styles apply.
+        * Note: This test originally used new Image() and onerror to get a callback
+        * when the url is loaded, but that is fragile since it doesn't monitor the
+        * same request as the css @import, and Safari 4 has issues with
+        * onerror/onload not being fired at all in weird cases like this.
+        */
+       function assertStyleAsync( assert, $element, prop, val, fn ) {
+               var styleTestStart,
+                       el = $element.get( 0 ),
+                       styleTestTimeout = ( QUnit.config.testTimeout - 200 ) || 5000;
+
+               function isCssImportApplied() {
+                       // Trigger reflow, repaint, redraw, whatever (cross-browser)
+                       var x = $element.css( 'height' );
+                       x = el.innerHTML;
+                       el.className = el.className;
+                       x = document.documentElement.clientHeight;
+
+                       return $element.css( prop ) === val;
                }
-               // Otherwise, keep polling
-               setTimeout( styleTestLoop, 150 );
-       }
 
-       // Start the loop
-       styleTestStart = new Date().getTime();
-       styleTestLoop();
-}
-
-function urlStyleTest( selector, prop, val ) {
-       return QUnit.fixurl(
-               mw.config.get( 'wgScriptPath' ) +
-                       '/tests/qunit/data/styleTest.css.php?' +
-                       $.param( {
-                               selector: selector,
-                               prop: prop,
-                               val: val
-                       } )
-       );
-}
-
-QUnit.asyncTest( 'mw.loader', 2, function ( assert ) {
-       var isAwesomeDone;
-
-       mw.loader.testCallback = function () {
-               QUnit.start();
-               assert.strictEqual( isAwesomeDone, undefined, 'Implementing module is.awesome: isAwesomeDone should still be undefined');
-               isAwesomeDone = true;
-       };
-
-       mw.loader.implement( 'test.callback', [QUnit.fixurl( mw.config.get( 'wgScriptPath' ) + '/tests/qunit/data/callMwLoaderTestCallback.js' )], {}, {} );
-
-       mw.loader.using( 'test.callback', function () {
-
-               // /sample/awesome.js declares the "mw.loader.testCallback" function
-               // which contains a call to start() and ok()
-               assert.strictEqual( isAwesomeDone, true, 'test.callback module should\'ve caused isAwesomeDone to be true' );
-               delete mw.loader.testCallback;
-
-       }, function () {
-               QUnit.start();
-               assert.ok( false, 'Error callback fired while loader.using "test.callback" module' );
-       });
-});
-
-QUnit.test( 'mw.loader.implement( styles={ "css": [text, ..] } )', 2, function ( assert ) {
-       var $element = $( '<div class="mw-test-implement-a"></div>' ).appendTo( '#qunit-fixture' );
-
-       assert.notEqual(
-               $element.css( 'float' ),
-               'right',
-               'style is clear'
-       );
-
-       mw.loader.implement(
-               'test.implement.a',
-               function () {
-                       assert.equal(
-                               $element.css( 'float' ),
-                               'right',
-                               'style is applied'
-                       );
-               },
-               {
-                       'all': '.mw-test-implement-a { float: right; }'
-               },
-               {}
-       );
-
-       mw.loader.load([
-               'test.implement.a'
-       ]);
-} );
-
-QUnit.asyncTest( 'mw.loader.implement( styles={ "url": { <media>: [url, ..] } } )', 7, function ( assert ) {
-       var $element1 = $( '<div class="mw-test-implement-b1"></div>' ).appendTo( '#qunit-fixture' ),
-               $element2 = $( '<div class="mw-test-implement-b2"></div>' ).appendTo( '#qunit-fixture' ),
-               $element3 = $( '<div class="mw-test-implement-b3"></div>' ).appendTo( '#qunit-fixture' );
-
-       assert.notEqual(
-               $element1.css( 'text-align' ),
-               'center',
-               'style is clear'
-       );
-       assert.notEqual(
-               $element2.css( 'float' ),
-               'left',
-               'style is clear'
-       );
-       assert.notEqual(
-               $element3.css( 'text-align' ),
-               'right',
-               'style is clear'
-       );
-
-       mw.loader.implement(
-               'test.implement.b',
-               function () {
-                       // Note: QUnit.start() must only be called when the entire test is
-                       // complete. So, make sure that we don't start until *both*
-                       // assertStyleAsync calls have completed.
-                       var pending = 2;
-                       assertStyleAsync( assert, $element2, 'float', 'left', function () {
-                               assert.notEqual( $element1.css( 'text-align' ), 'center', 'print style is not applied' );
-
-                               pending--;
-                               if ( pending === 0 ) {
-                                       QUnit.start();
-                               }
-                       } );
-                       assertStyleAsync( assert, $element3, 'float', 'right', function () {
-                               assert.notEqual( $element1.css( 'text-align' ), 'center', 'print style is not applied' );
+               function styleTestLoop() {
+                       var styleTestSince = new Date().getTime() - styleTestStart;
+                       // If it is passing or if we timed out, run the real test and stop the loop
+                       if ( isCssImportApplied() || styleTestSince > styleTestTimeout ) {
+                               assert.equal( $element.css( prop ), val,
+                                       'style "' + prop + ': ' + val + '" from url is applied (after ' + styleTestSince + 'ms)'
+                               );
 
-                               pending--;
-                               if ( pending === 0 ) {
-                                       QUnit.start();
+                               if ( fn ) {
+                                       fn();
                                }
-                       } );
-               },
-               {
-                       'url': {
-                               'print': [urlStyleTest( '.mw-test-implement-b1', 'text-align', 'center' )],
-                               'screen': [
-                                       // bug 40834: Make sure it actually works with more than 1 stylesheet reference
-                                       urlStyleTest( '.mw-test-implement-b2', 'float', 'left' ),
-                                       urlStyleTest( '.mw-test-implement-b3', 'float', 'right' )
-                               ]
+
+                               return;
                        }
-               },
-               {}
-       );
+                       // Otherwise, keep polling
+                       setTimeout( styleTestLoop, 150 );
+               }
+
+               // Start the loop
+               styleTestStart = new Date().getTime();
+               styleTestLoop();
+       }
+
+       function urlStyleTest( selector, prop, val ) {
+               return QUnit.fixurl(
+                       mw.config.get( 'wgScriptPath' ) +
+                               '/tests/qunit/data/styleTest.css.php?' +
+                               $.param( {
+                                       selector: selector,
+                                       prop: prop,
+                                       val: val
+                               } )
+               );
+       }
 
-       mw.loader.load([
-               'test.implement.b'
-       ]);
-} );
+       QUnit.asyncTest( 'mw.loader', 2, function ( assert ) {
+               var isAwesomeDone;
+
+               mw.loader.testCallback = function () {
+                       QUnit.start();
+                       assert.strictEqual( isAwesomeDone, undefined, 'Implementing module is.awesome: isAwesomeDone should still be undefined' );
+                       isAwesomeDone = true;
+               };
+
+               mw.loader.implement( 'test.callback', [QUnit.fixurl( mw.config.get( 'wgScriptPath' ) + '/tests/qunit/data/callMwLoaderTestCallback.js' )], {}, {} );
+
+               mw.loader.using( 'test.callback', function () {
+
+                       // /sample/awesome.js declares the "mw.loader.testCallback" function
+                       // which contains a call to start() and ok()
+                       assert.strictEqual( isAwesomeDone, true, 'test.callback module should\'ve caused isAwesomeDone to be true' );
+                       delete mw.loader.testCallback;
+
+               }, function () {
+                       QUnit.start();
+                       assert.ok( false, 'Error callback fired while loader.using "test.callback" module' );
+               } );
+       } );
+
+       QUnit.test( 'mw.loader.implement( styles={ "css": [text, ..] } )', 2, function ( assert ) {
+               var $element = $( '<div class="mw-test-implement-a"></div>' ).appendTo( '#qunit-fixture' );
+
+               assert.notEqual(
+                       $element.css( 'float' ),
+                       'right',
+                       'style is clear'
+               );
+
+               mw.loader.implement(
+                       'test.implement.a',
+                       function () {
+                               assert.equal(
+                                       $element.css( 'float' ),
+                                       'right',
+                                       'style is applied'
+                               );
+                       },
+                       {
+                               'all': '.mw-test-implement-a { float: right; }'
+                       },
+                       {}
+               );
+
+               mw.loader.load( [
+                       'test.implement.a'
+               ] );
+       } );
+
+       QUnit.asyncTest( 'mw.loader.implement( styles={ "url": { <media>: [url, ..] } } )', 7, function ( assert ) {
+               var $element1 = $( '<div class="mw-test-implement-b1"></div>' ).appendTo( '#qunit-fixture' ),
+                       $element2 = $( '<div class="mw-test-implement-b2"></div>' ).appendTo( '#qunit-fixture' ),
+                       $element3 = $( '<div class="mw-test-implement-b3"></div>' ).appendTo( '#qunit-fixture' );
+
+               assert.notEqual(
+                       $element1.css( 'text-align' ),
+                       'center',
+                       'style is clear'
+               );
+               assert.notEqual(
+                       $element2.css( 'float' ),
+                       'left',
+                       'style is clear'
+               );
+               assert.notEqual(
+                       $element3.css( 'text-align' ),
+                       'right',
+                       'style is clear'
+               );
+
+               mw.loader.implement(
+                       'test.implement.b',
+                       function () {
+                               // Note: QUnit.start() must only be called when the entire test is
+                               // complete. So, make sure that we don't start until *both*
+                               // assertStyleAsync calls have completed.
+                               var pending = 2;
+                               assertStyleAsync( assert, $element2, 'float', 'left', function () {
+                                       assert.notEqual( $element1.css( 'text-align' ), 'center', 'print style is not applied' );
+
+                                       pending--;
+                                       if ( pending === 0 ) {
+                                               QUnit.start();
+                                       }
+                               } );
+                               assertStyleAsync( assert, $element3, 'float', 'right', function () {
+                                       assert.notEqual( $element1.css( 'text-align' ), 'center', 'print style is not applied' );
+
+                                       pending--;
+                                       if ( pending === 0 ) {
+                                               QUnit.start();
+                                       }
+                               } );
+                       },
+                       {
+                               'url': {
+                                       'print': [urlStyleTest( '.mw-test-implement-b1', 'text-align', 'center' )],
+                                       'screen': [
+                                               // bug 40834: Make sure it actually works with more than 1 stylesheet reference
+                                               urlStyleTest( '.mw-test-implement-b2', 'float', 'left' ),
+                                               urlStyleTest( '.mw-test-implement-b3', 'float', 'right' )
+                                       ]
+                               }
+                       },
+                       {}
+               );
+
+               mw.loader.load( [
+                       'test.implement.b'
+               ] );
+       } );
 
 // Backwards compatibility
-QUnit.test( 'mw.loader.implement( styles={ <media>: text } ) (back-compat)', 2, function ( assert ) {
-       var $element = $( '<div class="mw-test-implement-c"></div>' ).appendTo( '#qunit-fixture' );
-
-       assert.notEqual(
-               $element.css( 'float' ),
-               'right',
-               'style is clear'
-       );
-
-       mw.loader.implement(
-               'test.implement.c',
-               function () {
-                       assert.equal(
-                               $element.css( 'float' ),
-                               'right',
-                               'style is applied'
-                       );
-               },
-               {
-                       'all': '.mw-test-implement-c { float: right; }'
-               },
-               {}
-       );
-
-       mw.loader.load([
-               'test.implement.c'
-       ]);
-} );
+       QUnit.test( 'mw.loader.implement( styles={ <media>: text } ) (back-compat)', 2, function ( assert ) {
+               var $element = $( '<div class="mw-test-implement-c"></div>' ).appendTo( '#qunit-fixture' );
+
+               assert.notEqual(
+                       $element.css( 'float' ),
+                       'right',
+                       'style is clear'
+               );
+
+               mw.loader.implement(
+                       'test.implement.c',
+                       function () {
+                               assert.equal(
+                                       $element.css( 'float' ),
+                                       'right',
+                                       'style is applied'
+                               );
+                       },
+                       {
+                               'all': '.mw-test-implement-c { float: right; }'
+                       },
+                       {}
+               );
+
+               mw.loader.load( [
+                       'test.implement.c'
+               ] );
+       } );
 
 // Backwards compatibility
-QUnit.asyncTest( 'mw.loader.implement( styles={ <media>: [url, ..] } ) (back-compat)', 4, function ( assert ) {
-       var $element = $( '<div class="mw-test-implement-d"></div>' ).appendTo( '#qunit-fixture' ),
-               $element2 = $( '<div class="mw-test-implement-d2"></div>' ).appendTo( '#qunit-fixture' );
-
-       assert.notEqual(
-               $element.css( 'float' ),
-               'right',
-               'style is clear'
-       );
-       assert.notEqual(
-               $element2.css( 'text-align' ),
-               'center',
-               'style is clear'
-       );
-
-       mw.loader.implement(
-               'test.implement.d',
-               function () {
-                       assertStyleAsync( assert, $element, 'float', 'right', function () {
-
-                               assert.notEqual( $element2.css( 'text-align' ), 'center', 'print style is not applied (bug 40500)' );
+       QUnit.asyncTest( 'mw.loader.implement( styles={ <media>: [url, ..] } ) (back-compat)', 4, function ( assert ) {
+               var $element = $( '<div class="mw-test-implement-d"></div>' ).appendTo( '#qunit-fixture' ),
+                       $element2 = $( '<div class="mw-test-implement-d2"></div>' ).appendTo( '#qunit-fixture' );
+
+               assert.notEqual(
+                       $element.css( 'float' ),
+                       'right',
+                       'style is clear'
+               );
+               assert.notEqual(
+                       $element2.css( 'text-align' ),
+                       'center',
+                       'style is clear'
+               );
+
+               mw.loader.implement(
+                       'test.implement.d',
+                       function () {
+                               assertStyleAsync( assert, $element, 'float', 'right', function () {
+
+                                       assert.notEqual( $element2.css( 'text-align' ), 'center', 'print style is not applied (bug 40500)' );
 
-                               QUnit.start();
-                       } );
-               },
-               {
-                       'all': [urlStyleTest( '.mw-test-implement-d', 'float', 'right' )],
-                       'print': [urlStyleTest( '.mw-test-implement-d2', 'text-align', 'center' )]
-               },
-               {}
-       );
-
-       mw.loader.load([
-               'test.implement.d'
-       ]);
-} );
+                                       QUnit.start();
+                               } );
+                       },
+                       {
+                               'all': [urlStyleTest( '.mw-test-implement-d', 'float', 'right' )],
+                               'print': [urlStyleTest( '.mw-test-implement-d2', 'text-align', 'center' )]
+                       },
+                       {}
+               );
+
+               mw.loader.load( [
+                       'test.implement.d'
+               ] );
+       } );
 
 // @import (bug 31676)
-QUnit.asyncTest( 'mw.loader.implement( styles has @import)', 5, function ( assert ) {
-       var isJsExecuted, $element;
+       QUnit.asyncTest( 'mw.loader.implement( styles has @import)', 5, function ( assert ) {
+               var isJsExecuted, $element;
 
-       mw.loader.implement(
-               'test.implement.import',
-               function () {
-                       assert.strictEqual( isJsExecuted, undefined, 'javascript not executed multiple times' );
-                       isJsExecuted = true;
+               mw.loader.implement(
+                       'test.implement.import',
+                       function () {
+                               assert.strictEqual( isJsExecuted, undefined, 'javascript not executed multiple times' );
+                               isJsExecuted = true;
 
-                       assert.equal( mw.loader.getState( 'test.implement.import' ), 'ready', 'module state is "ready" while implement() is executing javascript' );
+                               assert.equal( mw.loader.getState( 'test.implement.import' ), 'ready', 'module state is "ready" while implement() is executing javascript' );
 
-                       $element = $( '<div class="mw-test-implement-import">Foo bar</div>' ).appendTo( '#qunit-fixture' );
+                               $element = $( '<div class="mw-test-implement-import">Foo bar</div>' ).appendTo( '#qunit-fixture' );
 
-                       assert.equal( mw.msg( 'test-foobar' ), 'Hello Foobar, $1!', 'Messages are loaded before javascript execution' );
+                               assert.equal( mw.msg( 'test-foobar' ), 'Hello Foobar, $1!', 'Messages are loaded before javascript execution' );
 
-                       assertStyleAsync( assert, $element, 'float', 'right', function () {
-                               assert.equal( $element.css( 'text-align' ),'center',
-                                       'CSS styles after the @import rule are working'
-                               );
+                               assertStyleAsync( assert, $element, 'float', 'right', function () {
+                                       assert.equal( $element.css( 'text-align' ), 'center',
+                                               'CSS styles after the @import rule are working'
+                                       );
 
-                               QUnit.start();
-                       } );
-               },
-               {
-                       'css': [
-                               '@import url(\''
-                               + urlStyleTest( '.mw-test-implement-import', 'float', 'right' )
-                               + '\');\n'
-                               + '.mw-test-implement-import { text-align: center; }'
-                       ]
-               },
-               {
-                       'test-foobar': 'Hello Foobar, $1!'
-               }
-       );
-
-       mw.loader.load( 'test.implement' );
-
-});
-
-QUnit.asyncTest( 'mw.loader.implement( only messages )' , 2, function ( assert ) {
-       assert.assertFalse( mw.messages.exists( 'bug_29107' ), 'Verify that the test message doesn\'t exist yet' );
-
-       mw.loader.implement( 'test.implement.msgs', [], {}, { 'bug_29107': 'loaded' } );
-       mw.loader.using( 'test.implement.msgs', function() {
-               QUnit.start();
-               assert.ok( mw.messages.exists( 'bug_29107' ), 'Bug 29107: messages-only module should implement ok' );
-       }, function() {
-               QUnit.start();
-               assert.ok( false, 'Error callback fired while implementing "test.implement.msgs" module' );
-       });
-});
-
-QUnit.test( 'mw.loader erroneous indirect dependency', 3, function ( assert ) {
-       mw.loader.register( [
-               ['test.module1', '0'],
-               ['test.module2', '0', ['test.module1']],
-               ['test.module3', '0', ['test.module2']]
-       ] );
-       mw.loader.implement( 'test.module1', function () { throw new Error( 'expected' ); }, {}, {} );
-       assert.strictEqual( mw.loader.getState( 'test.module1' ), 'error', 'Expected "error" state for test.module1' );
-       assert.strictEqual( mw.loader.getState( 'test.module2' ), 'error', 'Expected "error" state for test.module2' );
-       assert.strictEqual( mw.loader.getState( 'test.module3' ), 'error', 'Expected "error" state for test.module3' );
-} );
-
-QUnit.test( 'mw.loader out-of-order implementation', 9, function ( assert ) {
-       mw.loader.register( [
-               ['test.module4', '0'],
-               ['test.module5', '0', ['test.module4']],
-               ['test.module6', '0', ['test.module5']]
-       ] );
-       mw.loader.implement( 'test.module4', function () {}, {}, {} );
-       assert.strictEqual( mw.loader.getState( 'test.module4' ), 'ready', 'Expected "ready" state for test.module4' );
-       assert.strictEqual( mw.loader.getState( 'test.module5' ), 'registered', 'Expected "registered" state for test.module5' );
-       assert.strictEqual( mw.loader.getState( 'test.module6' ), 'registered', 'Expected "registered" state for test.module6' );
-       mw.loader.implement( 'test.module6', function () {}, {}, {} );
-       assert.strictEqual( mw.loader.getState( 'test.module4' ), 'ready', 'Expected "ready" state for test.module4' );
-       assert.strictEqual( mw.loader.getState( 'test.module5' ), 'registered', 'Expected "registered" state for test.module5' );
-       assert.strictEqual( mw.loader.getState( 'test.module6' ), 'loaded', 'Expected "loaded" state for test.module6' );
-       mw.loader.implement( 'test.module5', function() {}, {}, {} );
-       assert.strictEqual( mw.loader.getState( 'test.module4' ), 'ready', 'Expected "ready" state for test.module4' );
-       assert.strictEqual( mw.loader.getState( 'test.module5' ), 'ready', 'Expected "ready" state for test.module5' );
-       assert.strictEqual( mw.loader.getState( 'test.module6' ), 'ready', 'Expected "ready" state for test.module6' );
-} );
-
-QUnit.test( 'mw.loader missing dependency', 13, function ( assert ) {
-       mw.loader.register( [
-               ['test.module7', '0'],
-               ['test.module8', '0', ['test.module7']],
-               ['test.module9', '0', ['test.module8']]
-       ] );
-       mw.loader.implement( 'test.module8', function () {}, {}, {} );
-       assert.strictEqual( mw.loader.getState( 'test.module7' ), 'registered', 'Expected "registered" state for test.module7' );
-       assert.strictEqual( mw.loader.getState( 'test.module8' ), 'loaded', 'Expected "loaded" state for test.module8' );
-       assert.strictEqual( mw.loader.getState( 'test.module9' ), 'registered', 'Expected "registered" state for test.module9' );
-       mw.loader.state( 'test.module7', 'missing' );
-       assert.strictEqual( mw.loader.getState( 'test.module7' ), 'missing', 'Expected "missing" state for test.module7' );
-       assert.strictEqual( mw.loader.getState( 'test.module8' ), 'error', 'Expected "error" state for test.module8' );
-       assert.strictEqual( mw.loader.getState( 'test.module9' ), 'error', 'Expected "error" state for test.module9' );
-       mw.loader.implement( 'test.module9', function () {}, {}, {} );
-       assert.strictEqual( mw.loader.getState( 'test.module7' ), 'missing', 'Expected "missing" state for test.module7' );
-       assert.strictEqual( mw.loader.getState( 'test.module8' ), 'error', 'Expected "error" state for test.module8' );
-       assert.strictEqual( mw.loader.getState( 'test.module9' ), 'error', 'Expected "error" state for test.module9' );
-       mw.loader.using(
-               ['test.module7'],
-               function () {
-                       assert.ok( false, 'Success fired despite missing dependency' );
-                       assert.ok( true , 'QUnit expected() count dummy' );
-               },
-               function ( e, dependencies ) {
-                       assert.strictEqual( $.isArray( dependencies ), true, 'Expected array of dependencies' );
-                       assert.deepEqual( dependencies, ['test.module7'], 'Error callback called with module test.module7' );
-               }
-       );
-       mw.loader.using(
-               ['test.module9'],
-               function () {
-                       assert.ok( false, 'Success fired despite missing dependency' );
-                       assert.ok( true , 'QUnit expected() count dummy' );
-               },
-               function ( e, dependencies ) {
-                       assert.strictEqual( $.isArray( dependencies ), true, 'Expected array of dependencies' );
-                       dependencies.sort();
-                       assert.deepEqual(
-                               dependencies,
-                               ['test.module7', 'test.module8', 'test.module9'],
-                               'Error callback called with all three modules as dependencies'
-                       );
-               }
-       );
-} );
-
-QUnit.asyncTest( 'mw.loader dependency handling', 5, function ( assert ) {
-       mw.loader.addSource(
-               'testloader',
-               {
-                       loadScript: QUnit.fixurl( mw.config.get( 'wgScriptPath' ) + '/tests/qunit/data/load.mock.php' )
-               }
-       );
-
-       mw.loader.register( [
-               // [module, version, dependencies, group, source]
-               ['testMissing', '1', [], null, 'testloader'],
-               ['testUsesMissing', '1', ['testMissing'], null, 'testloader'],
-               ['testUsesNestedMissing', '1', ['testUsesMissing'], null, 'testloader']
-       ] );
-
-       function verifyModuleStates() {
-               assert.equal( mw.loader.getState( 'testMissing' ), 'missing', 'Module not known to server must have state "missing"' );
-               assert.equal( mw.loader.getState( 'testUsesMissing' ), 'error', 'Module with missing dependency must have state "error"' );
-               assert.equal( mw.loader.getState( 'testUsesNestedMissing' ), 'error', 'Module with indirect missing dependency must have state "error"' );
-       }
-
-       mw.loader.using( ['testUsesNestedMissing'],
-               function () {
-                       assert.ok( false, 'Error handler should be invoked.' );
-                       assert.ok( true ); // Dummy to reach QUnit expect()
+                                       QUnit.start();
+                               } );
+                       },
+                       {
+                               'css': [
+                                       '@import url(\''
+                                               + urlStyleTest( '.mw-test-implement-import', 'float', 'right' )
+                                               + '\');\n'
+                                               + '.mw-test-implement-import { text-align: center; }'
+                               ]
+                       },
+                       {
+                               'test-foobar': 'Hello Foobar, $1!'
+                       }
+               );
 
-                       verifyModuleStates();
+               mw.loader.load( 'test.implement' );
 
-                       QUnit.start();
-               },
-               function ( e, badmodules ) {
-                       assert.ok( true, 'Error handler should be invoked.' );
-                       // As soon as server spits out state('testMissing', 'missing');
-                       // it will bubble up and trigger the error callback.
-                       // Therefor the badmodules array is not testUsesMissing or testUsesNestedMissing.
-                       assert.deepEqual( badmodules, ['testMissing'], 'Bad modules as expected.' );
+       } );
 
-                       verifyModuleStates();
+       QUnit.asyncTest( 'mw.loader.implement( only messages )', 2, function ( assert ) {
+               assert.assertFalse( mw.messages.exists( 'bug_29107' ), 'Verify that the test message doesn\'t exist yet' );
 
+               mw.loader.implement( 'test.implement.msgs', [], {}, { 'bug_29107': 'loaded' } );
+               mw.loader.using( 'test.implement.msgs', function () {
                        QUnit.start();
+                       assert.ok( mw.messages.exists( 'bug_29107' ), 'Bug 29107: messages-only module should implement ok' );
+               }, function () {
+                       QUnit.start();
+                       assert.ok( false, 'Error callback fired while implementing "test.implement.msgs" module' );
+               } );
+       } );
+
+       QUnit.test( 'mw.loader erroneous indirect dependency', 3, function ( assert ) {
+               mw.loader.register( [
+                       ['test.module1', '0'],
+                       ['test.module2', '0', ['test.module1']],
+                       ['test.module3', '0', ['test.module2']]
+               ] );
+               mw.loader.implement( 'test.module1', function () {
+                       throw new Error( 'expected' );
+               }, {}, {} );
+               assert.strictEqual( mw.loader.getState( 'test.module1' ), 'error', 'Expected "error" state for test.module1' );
+               assert.strictEqual( mw.loader.getState( 'test.module2' ), 'error', 'Expected "error" state for test.module2' );
+               assert.strictEqual( mw.loader.getState( 'test.module3' ), 'error', 'Expected "error" state for test.module3' );
+       } );
+
+       QUnit.test( 'mw.loader out-of-order implementation', 9, function ( assert ) {
+               mw.loader.register( [
+                       ['test.module4', '0'],
+                       ['test.module5', '0', ['test.module4']],
+                       ['test.module6', '0', ['test.module5']]
+               ] );
+               mw.loader.implement( 'test.module4', function () {
+               }, {}, {} );
+               assert.strictEqual( mw.loader.getState( 'test.module4' ), 'ready', 'Expected "ready" state for test.module4' );
+               assert.strictEqual( mw.loader.getState( 'test.module5' ), 'registered', 'Expected "registered" state for test.module5' );
+               assert.strictEqual( mw.loader.getState( 'test.module6' ), 'registered', 'Expected "registered" state for test.module6' );
+               mw.loader.implement( 'test.module6', function () {
+               }, {}, {} );
+               assert.strictEqual( mw.loader.getState( 'test.module4' ), 'ready', 'Expected "ready" state for test.module4' );
+               assert.strictEqual( mw.loader.getState( 'test.module5' ), 'registered', 'Expected "registered" state for test.module5' );
+               assert.strictEqual( mw.loader.getState( 'test.module6' ), 'loaded', 'Expected "loaded" state for test.module6' );
+               mw.loader.implement( 'test.module5', function () {
+               }, {}, {} );
+               assert.strictEqual( mw.loader.getState( 'test.module4' ), 'ready', 'Expected "ready" state for test.module4' );
+               assert.strictEqual( mw.loader.getState( 'test.module5' ), 'ready', 'Expected "ready" state for test.module5' );
+               assert.strictEqual( mw.loader.getState( 'test.module6' ), 'ready', 'Expected "ready" state for test.module6' );
+       } );
+
+       QUnit.test( 'mw.loader missing dependency', 13, function ( assert ) {
+               mw.loader.register( [
+                       ['test.module7', '0'],
+                       ['test.module8', '0', ['test.module7']],
+                       ['test.module9', '0', ['test.module8']]
+               ] );
+               mw.loader.implement( 'test.module8', function () {
+               }, {}, {} );
+               assert.strictEqual( mw.loader.getState( 'test.module7' ), 'registered', 'Expected "registered" state for test.module7' );
+               assert.strictEqual( mw.loader.getState( 'test.module8' ), 'loaded', 'Expected "loaded" state for test.module8' );
+               assert.strictEqual( mw.loader.getState( 'test.module9' ), 'registered', 'Expected "registered" state for test.module9' );
+               mw.loader.state( 'test.module7', 'missing' );
+               assert.strictEqual( mw.loader.getState( 'test.module7' ), 'missing', 'Expected "missing" state for test.module7' );
+               assert.strictEqual( mw.loader.getState( 'test.module8' ), 'error', 'Expected "error" state for test.module8' );
+               assert.strictEqual( mw.loader.getState( 'test.module9' ), 'error', 'Expected "error" state for test.module9' );
+               mw.loader.implement( 'test.module9', function () {
+               }, {}, {} );
+               assert.strictEqual( mw.loader.getState( 'test.module7' ), 'missing', 'Expected "missing" state for test.module7' );
+               assert.strictEqual( mw.loader.getState( 'test.module8' ), 'error', 'Expected "error" state for test.module8' );
+               assert.strictEqual( mw.loader.getState( 'test.module9' ), 'error', 'Expected "error" state for test.module9' );
+               mw.loader.using(
+                       ['test.module7'],
+                       function () {
+                               assert.ok( false, 'Success fired despite missing dependency' );
+                               assert.ok( true, 'QUnit expected() count dummy' );
+                       },
+                       function ( e, dependencies ) {
+                               assert.strictEqual( $.isArray( dependencies ), true, 'Expected array of dependencies' );
+                               assert.deepEqual( dependencies, ['test.module7'], 'Error callback called with module test.module7' );
+                       }
+               );
+               mw.loader.using(
+                       ['test.module9'],
+                       function () {
+                               assert.ok( false, 'Success fired despite missing dependency' );
+                               assert.ok( true, 'QUnit expected() count dummy' );
+                       },
+                       function ( e, dependencies ) {
+                               assert.strictEqual( $.isArray( dependencies ), true, 'Expected array of dependencies' );
+                               dependencies.sort();
+                               assert.deepEqual(
+                                       dependencies,
+                                       ['test.module7', 'test.module8', 'test.module9'],
+                                       'Error callback called with all three modules as dependencies'
+                               );
+                       }
+               );
+       } );
+
+       QUnit.asyncTest( 'mw.loader dependency handling', 5, function ( assert ) {
+               mw.loader.addSource(
+                       'testloader',
+                       {
+                               loadScript: QUnit.fixurl( mw.config.get( 'wgScriptPath' ) + '/tests/qunit/data/load.mock.php' )
+                       }
+               );
+
+               mw.loader.register( [
+                       // [module, version, dependencies, group, source]
+                       ['testMissing', '1', [], null, 'testloader'],
+                       ['testUsesMissing', '1', ['testMissing'], null, 'testloader'],
+                       ['testUsesNestedMissing', '1', ['testUsesMissing'], null, 'testloader']
+               ] );
+
+               function verifyModuleStates() {
+                       assert.equal( mw.loader.getState( 'testMissing' ), 'missing', 'Module not known to server must have state "missing"' );
+                       assert.equal( mw.loader.getState( 'testUsesMissing' ), 'error', 'Module with missing dependency must have state "error"' );
+                       assert.equal( mw.loader.getState( 'testUsesNestedMissing' ), 'error', 'Module with indirect missing dependency must have state "error"' );
                }
-       );
-} );
 
-QUnit.asyncTest( 'mw.loader( "//protocol-relative" ) (bug 30825)', 2, function ( assert ) {
-       // This bug was actually already fixed in 1.18 and later when discovered in 1.17.
-       // Test is for regressions!
+               mw.loader.using( ['testUsesNestedMissing'],
+                       function () {
+                               assert.ok( false, 'Error handler should be invoked.' );
+                               assert.ok( true ); // Dummy to reach QUnit expect()
 
-       // Forge an URL to the test callback script
-       var target = QUnit.fixurl(
-               mw.config.get( 'wgServer' ) + mw.config.get( 'wgScriptPath' ) + '/tests/qunit/data/qunitOkCall.js'
-       );
+                               verifyModuleStates();
 
-       // Confirm that mw.loader.load() works with protocol-relative URLs
-       target = target.replace( /https?:/, '' );
+                               QUnit.start();
+                       },
+                       function ( e, badmodules ) {
+                               assert.ok( true, 'Error handler should be invoked.' );
+                               // As soon as server spits out state('testMissing', 'missing');
+                               // it will bubble up and trigger the error callback.
+                               // Therefor the badmodules array is not testUsesMissing or testUsesNestedMissing.
+                               assert.deepEqual( badmodules, ['testMissing'], 'Bad modules as expected.' );
 
-       assert.equal( target.substr( 0, 2 ), '//',
-               'URL must be relative to test relative URLs!'
-       );
+                               verifyModuleStates();
 
-       // Async!
-       // The target calls QUnit.start
-       mw.loader.load( target );
-});
+                               QUnit.start();
+                       }
+               );
+       } );
 
-QUnit.test( 'mw.html', 13, function ( assert ) {
-       assert.throws( function () {
-               mw.html.escape();
-       }, TypeError, 'html.escape throws a TypeError if argument given is not a string' );
+       QUnit.asyncTest( 'mw.loader( "//protocol-relative" ) (bug 30825)', 2, function ( assert ) {
+               // This bug was actually already fixed in 1.18 and later when discovered in 1.17.
+               // Test is for regressions!
 
-       assert.equal( mw.html.escape( '<mw awesome="awesome" value=\'test\' />' ),
-               '&lt;mw awesome=&quot;awesome&quot; value=&#039;test&#039; /&gt;', 'escape() escapes special characters to html entities' );
+               // Forge an URL to the test callback script
+               var target = QUnit.fixurl(
+                       mw.config.get( 'wgServer' ) + mw.config.get( 'wgScriptPath' ) + '/tests/qunit/data/qunitOkCall.js'
+               );
 
-       assert.equal( mw.html.element(),
-               '<undefined/>', 'element() always returns a valid html string (even without arguments)' );
+               // Confirm that mw.loader.load() works with protocol-relative URLs
+               target = target.replace( /https?:/, '' );
 
-       assert.equal( mw.html.element( 'div' ), '<div/>', 'element() Plain DIV (simple)' );
+               assert.equal( target.substr( 0, 2 ), '//',
+                       'URL must be relative to test relative URLs!'
+               );
 
-       assert.equal( mw.html.element( 'div', {}, '' ), '<div></div>', 'element() Basic DIV (simple)' );
+               // Async!
+               // The target calls QUnit.start
+               mw.loader.load( target );
+       } );
 
-       assert.equal(
-               mw.html.element(
-                       'div', {
-                               id: 'foobar'
-                       }
-               ),
-               '<div id="foobar"/>',
-               'html.element DIV (attribs)' );
-
-       assert.equal( mw.html.element( 'p', null, 12 ), '<p>12</p>', 'Numbers are valid content and should be casted to a string' );
-
-       assert.equal( mw.html.element( 'p', { title: 12 }, '' ), '<p title="12"></p>', 'Numbers are valid attribute values' );
-
-       // Example from https://www.mediawiki.org/wiki/ResourceLoader/Default_modules#mediaWiki.html
-       assert.equal(
-               mw.html.element(
-                       'div',
-                       {},
-                       new mw.html.Raw(
-                               mw.html.element( 'img', { src: '<' } )
-                       )
-               ),
-               '<div><img src="&lt;"/></div>',
-               'Raw inclusion of another element'
-       );
-
-       assert.equal(
-               mw.html.element(
-                       'option', {
-                               selected: true
-                       }, 'Foo'
-               ),
-               '<option selected="selected">Foo</option>',
-               'Attributes may have boolean values. True copies the attribute name to the value.'
-       );
-
-       assert.equal(
-               mw.html.element(
-                       'option', {
-                               value: 'foo',
-                               selected: false
-                       }, 'Foo'
-               ),
-               '<option value="foo">Foo</option>',
-               'Attributes may have boolean values. False keeps the attribute from output.'
-       );
-
-       assert.equal( mw.html.element( 'div',
+       QUnit.test( 'mw.html', 13, function ( assert ) {
+               assert.throws( function () {
+                       mw.html.escape();
+               }, TypeError, 'html.escape throws a TypeError if argument given is not a string' );
+
+               assert.equal( mw.html.escape( '<mw awesome="awesome" value=\'test\' />' ),
+                       '&lt;mw awesome=&quot;awesome&quot; value=&#039;test&#039; /&gt;', 'escape() escapes special characters to html entities' );
+
+               assert.equal( mw.html.element(),
+                       '<undefined/>', 'element() always returns a valid html string (even without arguments)' );
+
+               assert.equal( mw.html.element( 'div' ), '<div/>', 'element() Plain DIV (simple)' );
+
+               assert.equal( mw.html.element( 'div', {}, '' ), '<div></div>', 'element() Basic DIV (simple)' );
+
+               assert.equal(
+                       mw.html.element(
+                               'div', {
+                                       id: 'foobar'
+                               }
+                       ),
+                       '<div id="foobar"/>',
+                       'html.element DIV (attribs)' );
+
+               assert.equal( mw.html.element( 'p', null, 12 ), '<p>12</p>', 'Numbers are valid content and should be casted to a string' );
+
+               assert.equal( mw.html.element( 'p', { title: 12 }, '' ), '<p title="12"></p>', 'Numbers are valid attribute values' );
+
+               // Example from https://www.mediawiki.org/wiki/ResourceLoader/Default_modules#mediaWiki.html
+               assert.equal(
+                       mw.html.element(
+                               'div',
+                               {},
+                               new mw.html.Raw(
+                                       mw.html.element( 'img', { src: '<' } )
+                               )
+                       ),
+                       '<div><img src="&lt;"/></div>',
+                       'Raw inclusion of another element'
+               );
+
+               assert.equal(
+                       mw.html.element(
+                               'option', {
+                                       selected: true
+                               }, 'Foo'
+                       ),
+                       '<option selected="selected">Foo</option>',
+                       'Attributes may have boolean values. True copies the attribute name to the value.'
+               );
+
+               assert.equal(
+                       mw.html.element(
+                               'option', {
+                                       value: 'foo',
+                                       selected: false
+                               }, 'Foo'
+                       ),
+                       '<option value="foo">Foo</option>',
+                       'Attributes may have boolean values. False keeps the attribute from output.'
+               );
+
+               assert.equal( mw.html.element( 'div',
                        null, 'a' ),
-               '<div>a</div>',
-               'html.element DIV (content)' );
+                       '<div>a</div>',
+                       'html.element DIV (content)' );
 
-       assert.equal( mw.html.element( 'a',
+               assert.equal( mw.html.element( 'a',
                        { href: 'http://mediawiki.org/w/index.php?title=RL&action=history' }, 'a' ),
-               '<a href="http://mediawiki.org/w/index.php?title=RL&amp;action=history">a</a>',
-               'html.element DIV (attribs + content)' );
+                       '<a href="http://mediawiki.org/w/index.php?title=RL&amp;action=history">a</a>',
+                       'html.element DIV (attribs + content)' );
 
-});
+       } );
 
 }( mediaWiki, jQuery ) );
index a9bbbf7..875ab91 100644 (file)
@@ -1,55 +1,53 @@
 ( function ( mw, $ ) {
-
-QUnit.module( 'mediawiki.user', QUnit.newMwEnvironment() );
-
-QUnit.test( 'options', 1, function ( assert ) {
-       assert.ok( mw.user.options instanceof mw.Map, 'options instance of mw.Map' );
-});
-
-QUnit.test( 'user status', 9, function ( assert ) {
-       /**
-        * Tests can be run under three different conditions:
-        *   1) From tests/qunit/index.html, user will be anonymous.
-        *   2) Logged in on [[Special:JavaScriptTest/qunit]]
-        *   3) Anonymously at the same special page.
-        */
-
-       // Forge an anonymous user:
-       mw.config.set( 'wgUserName', null );
-
-       assert.strictEqual( mw.user.getName(), null, 'user.getName() returns null when anonymous' );
-       assert.strictEqual( mw.user.name(), null, 'user.name() compatibility' );
-       assert.assertTrue( mw.user.isAnon(), 'user.isAnon() returns true when anonymous' );
-       assert.assertTrue( mw.user.anonymous(), 'user.anonymous() compatibility' );
-
-       // Not part of startUp module
-       mw.config.set( 'wgUserName', 'John' );
-
-       assert.equal( mw.user.getName(), 'John', 'user.getName() returns username when logged-in' );
-       assert.equal( mw.user.name(), 'John', 'user.name() compatibility' );
-       assert.assertFalse( mw.user.isAnon(), 'user.isAnon() returns false when logged-in' );
-       assert.assertFalse( mw.user.anonymous(), 'user.anonymous() compatibility' );
-
-       assert.equal( mw.user.id(), 'John', 'user.id Returns username when logged-in' );
-});
-
-QUnit.asyncTest( 'getGroups', 3, function ( assert ) {
-       mw.user.getGroups( function ( groups ) {
-               // First group should always be '*'
-               assert.equal( $.type( groups ), 'array', 'Callback gets an array' );
-               assert.notStrictEqual( $.inArray( '*', groups ), -1, '"*"" is in the list' );
-               // Sort needed because of different methods if creating the arrays,
-               // only the content matters.
-               assert.deepEqual( groups.sort(), mw.config.get( 'wgUserGroups' ).sort(), 'Array contains all groups, just like wgUserGroups' );
-               QUnit.start();
-       });
-});
-
-QUnit.asyncTest( 'getRights', 1, function ( assert ) {
-       mw.user.getRights( function ( rights ) {
-               assert.equal( $.type( rights ), 'array', 'Callback gets an array' );
-               QUnit.start();
-       });
-});
-
+       QUnit.module( 'mediawiki.user', QUnit.newMwEnvironment() );
+
+       QUnit.test( 'options', 1, function ( assert ) {
+               assert.ok( mw.user.options instanceof mw.Map, 'options instance of mw.Map' );
+       } );
+
+       QUnit.test( 'user status', 9, function ( assert ) {
+               /**
+                * Tests can be run under three different conditions:
+                *   1) From tests/qunit/index.html, user will be anonymous.
+                *   2) Logged in on [[Special:JavaScriptTest/qunit]]
+                *   3) Anonymously at the same special page.
+                */
+
+               // Forge an anonymous user:
+               mw.config.set( 'wgUserName', null );
+
+               assert.strictEqual( mw.user.getName(), null, 'user.getName() returns null when anonymous' );
+               assert.strictEqual( mw.user.name(), null, 'user.name() compatibility' );
+               assert.assertTrue( mw.user.isAnon(), 'user.isAnon() returns true when anonymous' );
+               assert.assertTrue( mw.user.anonymous(), 'user.anonymous() compatibility' );
+
+               // Not part of startUp module
+               mw.config.set( 'wgUserName', 'John' );
+
+               assert.equal( mw.user.getName(), 'John', 'user.getName() returns username when logged-in' );
+               assert.equal( mw.user.name(), 'John', 'user.name() compatibility' );
+               assert.assertFalse( mw.user.isAnon(), 'user.isAnon() returns false when logged-in' );
+               assert.assertFalse( mw.user.anonymous(), 'user.anonymous() compatibility' );
+
+               assert.equal( mw.user.id(), 'John', 'user.id Returns username when logged-in' );
+       } );
+
+       QUnit.asyncTest( 'getGroups', 3, function ( assert ) {
+               mw.user.getGroups( function ( groups ) {
+                       // First group should always be '*'
+                       assert.equal( $.type( groups ), 'array', 'Callback gets an array' );
+                       assert.notStrictEqual( $.inArray( '*', groups ), -1, '"*"" is in the list' );
+                       // Sort needed because of different methods if creating the arrays,
+                       // only the content matters.
+                       assert.deepEqual( groups.sort(), mw.config.get( 'wgUserGroups' ).sort(), 'Array contains all groups, just like wgUserGroups' );
+                       QUnit.start();
+               } );
+       } );
+
+       QUnit.asyncTest( 'getRights', 1, function ( assert ) {
+               mw.user.getRights( function ( rights ) {
+                       assert.equal( $.type( rights ), 'array', 'Callback gets an array' );
+                       QUnit.start();
+               } );
+       } );
 }( mediaWiki, jQuery ) );
index c4212df..bba3160 100644 (file)
@@ -3,11 +3,11 @@
 
        QUnit.test( 'rawurlencode', 1, function ( assert ) {
                assert.equal( mw.util.rawurlencode( 'Test:A & B/Here' ), 'Test%3AA%20%26%20B%2FHere' );
-       });
+       } );
 
        QUnit.test( 'wikiUrlencode', 1, function ( assert ) {
                assert.equal( mw.util.wikiUrlencode( 'Test:A & B/Here' ), 'Test:A_%26_B/Here' );
-       });
+       } );
 
        QUnit.test( 'wikiGetlink', 3, function ( assert ) {
                // Not part of startUp module
 
                href = mw.util.wikiGetlink();
                assert.equal( href, '/wiki/Foobar', 'Default title; Get link for current page ("Foobar")' );
-       });
+       } );
 
        QUnit.test( 'wikiScript', 4, function ( assert ) {
-               mw.config.set({
+               mw.config.set( {
                        'wgScript': '/w/i.php', // customized wgScript for bug 39103
                        'wgLoadScript': '/w/l.php', // customized wgLoadScript for bug 39103
                        'wgScriptPath': '/w',
                        'wgScriptExtension': '.php'
-               });
+               } );
 
                assert.equal( mw.util.wikiScript(), mw.config.get( 'wgScript' ),
                        'wikiScript() returns wgScript'
@@ -43,7 +43,7 @@
                        'wikiScript( load ) returns wgLoadScript'
                );
                assert.equal( mw.util.wikiScript( 'api' ), '/w/api.php', 'API path' );
-       });
+       } );
 
        QUnit.test( 'addCSS', 3, function ( assert ) {
                var $el, style;
@@ -57,7 +57,7 @@
 
                // Clean up
                $( style.ownerNode ).remove();
-       });
+       } );
 
        QUnit.asyncTest( 'toggleToc', 4, function ( assert ) {
                var tocHtml, $toggleLink;
 
                assert.strictEqual( mw.util.toggleToc(), null, 'Return null if there is no table of contents on the page.' );
 
-               tocHtml =
-                       '<table id="toc" class="toc"><tr><td>' +
-                               '<div id="toctitle">' +
-                                       '<h2>Contents</h2>' +
-                                       '<span class="toctoggle">&nbsp;[<a href="#" class="internal" id="togglelink">Hide</a>&nbsp;]</span>' +
-                               '</div>' +
-                               '<ul><li></li></ul>' +
+               tocHtml = '<table id="toc" class="toc"><tr><td>' +
+                       '<div id="toctitle">' +
+                       '<h2>Contents</h2>' +
+                       '<span class="toctoggle">&nbsp;[<a href="#" class="internal" id="togglelink">Hide</a>&nbsp;]</span>' +
+                       '</div>' +
+                       '<ul><li></li></ul>' +
                        '</td></tr></table>';
-               $(tocHtml).appendTo( '#qunit-fixture' ),
-               $toggleLink = $( '#togglelink' );
+               $( tocHtml ).appendTo( '#qunit-fixture' ),
+                       $toggleLink = $( '#togglelink' );
 
                assert.strictEqual( $toggleLink.length, 1, 'Toggle link is appended to the page.' );
 
                actionA();
-       });
+       } );
 
        QUnit.test( 'getParamValue', 5, function ( assert ) {
-               var     url;
+               var url;
 
                url = 'http://example.org/?foo=wrong&foo=right#&foo=bad';
                assert.equal( mw.util.getParamValue( 'foo', url ), 'right', 'Use latest one, ignore hash' );
                url = 'http://example.org/#&foo=bad';
                assert.strictEqual( mw.util.getParamValue( 'foo', url ), null, 'Ignore hash if param is not in querystring but in hash (bug 27427)' );
 
-               url = 'example.org?' + $.param({ 'TEST': 'a b+c' });
+               url = 'example.org?' + $.param( { 'TEST': 'a b+c' } );
                assert.strictEqual( mw.util.getParamValue( 'TEST', url ), 'a b+c', 'Bug 30441: getParamValue must understand "+" encoding of space' );
 
-               url = 'example.org?' + $.param({ 'TEST': 'a b+c d' }); // check for sloppy code from r95332 :)
+               url = 'example.org?' + $.param( { 'TEST': 'a b+c d' } ); // check for sloppy code from r95332 :)
                assert.strictEqual( mw.util.getParamValue( 'TEST', url ), 'a b+c d', 'Bug 30441: getParamValue must understand "+" encoding of space (multiple spaces)' );
-       });
+       } );
 
        QUnit.test( 'tooltipAccessKey', 3, function ( assert ) {
                assert.equal( typeof mw.util.tooltipAccessKeyPrefix, 'string', 'mw.util.tooltipAccessKeyPrefix must be a string' );
                assert.ok( mw.util.tooltipAccessKeyRegexp instanceof RegExp, 'mw.util.tooltipAccessKeyRegexp instance of RegExp' );
                assert.ok( mw.util.updateTooltipAccessKeys, 'mw.util.updateTooltipAccessKeys' );
-       });
+       } );
 
        QUnit.test( '$content', 2, function ( assert ) {
                assert.ok( mw.util.$content instanceof jQuery, 'mw.util.$content instance of jQuery' );
                assert.strictEqual( mw.util.$content.length, 1, 'mw.util.$content must have length of 1' );
-       });
-
+       } );
 
        /**
         * Portlet names are prefixed with 'p-test' to avoid conflict with core
                assert.equal( $tbMW.next().attr( 'id' ), 't-rl', 'Link is in the correct position (by passing nextnode)' );
 
                cuQuux = mw.util.addPortletLink( 'p-test-custom', '#', 'Quux' );
-               $cuQuux = $(cuQuux);
+               $cuQuux = $( cuQuux );
 
                assert.equal(
                        $( '#p-test-custom #c-barmenu ul li' ).length,
 
                caFoo = mw.util.addPortletLink( 'p-test-views', '#', 'Foo' );
 
-               assert.strictEqual( $tbMW.find( 'span').length, 0, 'No <span> element should be added for porlets without vectorTabs class.' );
-               assert.strictEqual( $( caFoo ).find( 'span').length, 1, 'A <span> element should be added for porlets with vectorTabs class.' );
-       });
+               assert.strictEqual( $tbMW.find( 'span' ).length, 0, 'No <span> element should be added for porlets without vectorTabs class.' );
+               assert.strictEqual( $( caFoo ).find( 'span' ).length, 1, 'A <span> element should be added for porlets with vectorTabs class.' );
+       } );
 
        QUnit.test( 'jsMessage', 1, function ( assert ) {
                var a = mw.util.jsMessage( 'MediaWiki is <b>Awesome</b>.' );
 
                // Clean up
                $( '#mw-js-message' ).remove();
-       });
+       } );
 
        QUnit.test( 'validateEmail', 6, function ( assert ) {
                assert.strictEqual( mw.util.validateEmail( '' ), null, 'Should return null for empty string ' );
                // testEmailWithHyphens
                assert.strictEqual( mw.util.validateEmail( 'user-foo@example.org' ), true, 'Emails may contain a hyphen' );
                assert.strictEqual( mw.util.validateEmail( 'userfoo@ex-ample.org' ), true, 'Emails may contain a hyphen' );
-       });
+       } );
 
        QUnit.test( 'isIPv6Address', 40, function ( assert ) {
                // Shortcuts
                function assertFalseIPv6( addy, summary ) {
                        return assert.strictEqual( mw.util.isIPv6Address( addy ), false, summary );
                }
+
                function assertTrueIPv6( addy, summary ) {
                        return assert.strictEqual( mw.util.isIPv6Address( addy ), true, summary );
                }
                assertFalseIPv6( 'fc:100:300', 'IPv6 with only 3 words' );
 
                $.each(
-               ['fc:100::',
-               'fc:100:a::',
-               'fc:100:a:d::',
-               'fc:100:a:d:1::',
-               'fc:100:a:d:1:e::',
-               'fc:100:a:d:1:e:ac::'], function ( i, addy ){
-                       assertTrueIPv6( addy, addy + ' is a valid IP' );
-               });
+                       ['fc:100::',
+                               'fc:100:a::',
+                               'fc:100:a:d::',
+                               'fc:100:a:d:1::',
+                               'fc:100:a:d:1:e::',
+                               'fc:100:a:d:1:e:ac::'], function ( i, addy ) {
+                               assertTrueIPv6( addy, addy + ' is a valid IP' );
+                       } );
 
                assertFalseIPv6( 'fc:100:a:d:1:e:ac:0::', 'IPv6 with 8 words ending with "::"' );
                assertFalseIPv6( 'fc:100:a:d:1:e:ac:0:1::', 'IPv6 with 9 words ending with "::"' );
 
                assertTrueIPv6( '::', 'IPv6 zero address' );
                $.each(
-               ['::0',
-               '::fc',
-               '::fc:100',
-               '::fc:100:a',
-               '::fc:100:a:d',
-               '::fc:100:a:d:1',
-               '::fc:100:a:d:1:e',
-               '::fc:100:a:d:1:e:ac',
-
-               'fc:100:a:d:1:e:ac:0'], function ( i, addy ){
-                       assertTrueIPv6( addy, addy + ' is a valid IP' );
-               });
+                       ['::0',
+                               '::fc',
+                               '::fc:100',
+                               '::fc:100:a',
+                               '::fc:100:a:d',
+                               '::fc:100:a:d:1',
+                               '::fc:100:a:d:1:e',
+                               '::fc:100:a:d:1:e:ac',
+
+                               'fc:100:a:d:1:e:ac:0'], function ( i, addy ) {
+                               assertTrueIPv6( addy, addy + ' is a valid IP' );
+                       } );
 
                assertFalseIPv6( '::fc:100:a:d:1:e:ac:0', 'IPv6 with "::" and 8 words' );
                assertFalseIPv6( '::fc:100:a:d:1:e:ac:0:1', 'IPv6 with 9 words' );
 
                assertFalseIPv6( 'fc::100:a:d:1:e:ac:0', 'IPv6 with "::" and 8 words' );
                assertFalseIPv6( 'fc::100:a:d:1:e:ac:0:1', 'IPv6 with 9 words' );
-       });
+       } );
 
        QUnit.test( 'isIPv4Address', 11, function ( assert ) {
                // Shortcuts
                function assertFalseIPv4( addy, summary ) {
                        assert.strictEqual( mw.util.isIPv4Address( addy ), false, summary );
                }
+
                function assertTrueIPv4( addy, summary ) {
                        assert.strictEqual( mw.util.isIPv4Address( addy ), true, summary );
                }
                assertTrueIPv4( '124.24.52.13', '124.24.52.134 is a valid IP' );
                assertTrueIPv4( '1.24.52.13', '1.24.52.13 is a valid IP' );
                assertFalseIPv4( '74.24.52.13/20', 'IPv4 ranges are not recogzized as valid IPs' );
-       });
+       } );
 }( mediaWiki, jQuery ) );
index ecf7f9e..5a067c2 100644 (file)
@@ -47,7 +47,9 @@ class Selenium {
        public function start() {
                $this->tester = new Testing_Selenium( $this->browser, self::$url, $this->host,
                        $this->port, $this->timeout );
-               if ( method_exists( $this->tester, "setVerbose" ) ) $this->tester->setVerbose( $this->verbose );
+               if ( method_exists( $this->tester, "setVerbose" ) ) {
+                       $this->tester->setVerbose( $this->verbose );
+               }
 
                $this->tester->start();
                $this->isStarted = true;
@@ -94,7 +96,7 @@ class Selenium {
                $this->logger = $logger;
        }
 
-       public function getLogger( ) {
+       public function getLogger() {
                return $this->logger;
        }
 
@@ -122,22 +124,21 @@ class Selenium {
                $this->user = $user;
        }
 
-        // Function to get username
-        public function getUser() {
+       // Function to get username
+       public function getUser() {
                return $this->user;
        }
-        
+
 
        public function setPass( $pass ) {
                $this->pass = $pass;
        }
 
-    //add function to get password    
-       public function getPass(  ) {
+       //add function to get password
+       public function getPass() {
                return $this->pass;
        }
-       
-       
+
        public function setHost( $host ) {
                $this->host = $host;
        }
@@ -154,7 +155,7 @@ class Selenium {
                $this->junitlogfile = $junitlogfile;
        }
 
-       public function getJUnitLogfile( ) {
+       public function getJUnitLogfile() {
                return $this->junitlogfile;
        }
 
@@ -163,7 +164,7 @@ class Selenium {
        }
 
        public function setBrowser( $b ) {
-               if ($this->runagainstgrid) {
+               if ( $this->runagainstgrid ) {
                        $this->browser = $b;
                        return true;
                }
@@ -184,7 +185,7 @@ class Selenium {
        }
 
        // Prevent external cloning
-       protected function __clone() { }
+       protected function __clone() {}
        // Prevent external construction
        // protected function __construct() {}
 }
index 04cf8d8..0823275 100644 (file)
@@ -10,14 +10,15 @@ class SeleniumConfig {
         * See sample config file in selenium_settings.ini.sample
         *
         */
-
-       public static function getSeleniumSettings ( &$seleniumSettings,
-                       &$seleniumBrowsers,
-                       &$seleniumTestSuites,
-                       $seleniumConfigFile = null ) {
+       public static function getSeleniumSettings( &$seleniumSettings,
+                                                                                               &$seleniumBrowsers,
+                                                                                               &$seleniumTestSuites,
+                                                                                               $seleniumConfigFile = null ) {
                if ( strlen( $seleniumConfigFile ) == 0 ) {
                        global $wgSeleniumConfigFile;
-                       if ( isset( $wgSeleniumConfigFile ) ) $seleniumConfigFile =  $wgSeleniumConfigFile ;
+                       if ( isset( $wgSeleniumConfigFile ) ) {
+                               $seleniumConfigFile = $wgSeleniumConfigFile;
+                       }
                }
 
                if ( strlen( $seleniumConfigFile ) == 0 || !file_exists( $seleniumConfigFile ) ) {
@@ -29,7 +30,7 @@ class SeleniumConfig {
                        throw new MWException( "Error parsing " . $seleniumConfigFile . "\n" );
                }
 
-               if ( array_key_exists( 'SeleniumSettings', $configArray ) {
+               if ( array_key_exists( 'SeleniumSettings', $configArray ) ) {
                        wfSuppressWarnings();
                        //we may need to change how this is set. But for now leave it in the ini file
                        $seleniumBrowsers = $configArray['SeleniumSettings']['browsers'];
@@ -48,7 +49,7 @@ class SeleniumConfig {
 
                        wfRestoreWarnings();
                }
-               if ( array_key_exists( 'SeleniumTests', $configArray ) {
+               if ( array_key_exists( 'SeleniumTests', $configArray ) ) {
                        wfSuppressWarnings();
                        $seleniumTestSuites = $configArray['SeleniumTests']['testSuite'];
                        wfRestoreWarnings();
index 9e2d4aa..3fbc831 100644 (file)
@@ -34,15 +34,22 @@ class SeleniumServerManager {
        private $SeleniumServerExecPath;
 
        public function __construct( $startServer,
-                                        $serverPort,
-                                        $serverExecPath ) {
-               $this->OS = (string) PHP_OS;
-               if ( isset( $startServer ) )
+                                                                $serverPort,
+                                                                $serverExecPath ) {
+               $this->OS = (string)PHP_OS;
+
+               if ( isset( $startServer ) ) {
                        $this->SeleniumStartServer = $startServer;
-               if ( isset( $serverPort ) )
+               }
+
+               if ( isset( $serverPort ) ) {
                        $this->SeleniumServerPort = $serverPort;
-               if ( isset( $serverExecPath ) )
+               }
+
+               if ( isset( $serverExecPath ) ) {
                        $this->SeleniumServerExecPath = $serverExecPath;
+               }
+
                return;
        }
 
@@ -66,7 +73,9 @@ class SeleniumServerManager {
        // to true, since after server is started, it is shut down by stop().
 
        public function setSeleniumStartServer( $startServer ) {
-               if ( $startServer == true ) $this->SeleniumStartServer = true;
+               if ( $startServer == true ) {
+                       $this->SeleniumStartServer = true;
+               }
        }
 
        // return values are: 1) started - server started, 2) failed -
@@ -75,7 +84,9 @@ class SeleniumServerManager {
 
        public function start() {
 
-               if ( !$this->SeleniumStartServer ) return 'failed';
+               if ( !$this->SeleniumStartServer ) {
+                       return 'failed';
+               }
 
                // commented out cases are untested
 
@@ -142,15 +153,15 @@ class SeleniumServerManager {
                $output = array();
                $user = $_ENV['USER'];
                // @todo FIXME: This should be a little more generalized :)
-               if (PHP_OS == 'Darwin') {
+               if ( PHP_OS == 'Darwin' ) {
                        // Mac OS X's ps barfs on the 'w' param, but doesn't need it.
                        $ps = "ps -U %s";
                } else {
                        // Good on Linux
                        $ps = "ps -U %s w";
                }
-               $psCommand = sprintf($ps, escapeshellarg($user));
-               exec($psCommand . " | grep -i selenium-server", $output);
+               $psCommand = sprintf( $ps, escapeshellarg( $user ) );
+               exec( $psCommand . " | grep -i selenium-server", $output );
 
                // Start server. If there is already a server running,
                // return running.
@@ -170,16 +181,16 @@ class SeleniumServerManager {
                                // The echo guarentees it is put into $op when
                                // the exec command is run.
 
-                               $commandSuffix = ' > /dev/null 2>&1'. ' & echo $!';
+                               $commandSuffix = ' > /dev/null 2>&1' . ' & echo $!';
                                $portText = ' -port ' . $this->SeleniumServerPort;
                                $command = "java -jar " .
-                                       escapeshellarg($this->SeleniumServerExecPath) .
+                                       escapeshellarg( $this->SeleniumServerExecPath ) .
                                        $portText . $commandSuffix;
-                               exec($command ,$op);
+                               exec( $command, $op );
                                $pid = (int)$op[0];
-                               if ( $pid != "" )
+                               if ( $pid != "" ) {
                                        $this->SeleniumServerPid = $pid;
-                               else {
+                               else {
                                        $this->SeleniumServerPid = 'NaN';
                                        // Server start failed.
                                        return 'failed';
@@ -192,27 +203,29 @@ class SeleniumServerManager {
                                for ( $cnt = 1;
                                          $cnt <= $this->SeleniumServerStartTimeout;
                                          $cnt++ ) {
-                                       $fp = fsockopen ( 'localhost',
+                                       $fp = fsockopen( 'localhost',
                                                $this->SeleniumServerPort,
                                                $errno, $errstr, 0 );
                                        if ( !$fp ) {
                                                sleep( 1 );
                                                continue;
-                                         // Server start succeeded.
+                                               // Server start succeeded.
                                        } else {
-                                               fclose ( $fp );
+                                               fclose( $fp );
                                                return 'started';
                                        }
                                }
                                wfRestoreWarnings();
                                echo ( "Starting Selenium server timed out.\n" );
                                return 'failed';
+                       } else {
+                               // server already running.
+                               return 'running';
                        }
-                       // server already running.
-                       else return 'running';
 
                }
-                               // No Server execution path defined.
+
+               // No Server execution path defined.
                return 'failed';
        }
 
@@ -224,11 +237,13 @@ class SeleniumServerManager {
        private function stopServerOnUnix() {
 
                if ( !empty( $this->SeleniumServerPid ) &&
-                        $this->SeleniumServerPid != 'NaN' ) {
+                       $this->SeleniumServerPid != 'NaN'
+               ) {
                        exec( "kill -9 " . $this->SeleniumServerPid );
                        return 'stopped';
+               } else {
+                       return 'failed';
                }
-               else return 'failed';
        }
 
        private function stopServerOnWindows() {
index 7976c16..5346b1b 100644 (file)
@@ -1,5 +1,5 @@
 <?php
-include("SeleniumTestConstants.php");
+include( "SeleniumTestConstants.php" );
 
 class SeleniumTestCase extends PHPUnit_Framework_TestCase { // PHPUnit_Extensions_SeleniumTestCase
        protected $selenium;
@@ -35,93 +35,93 @@ class SeleniumTestCase extends PHPUnit_Framework_TestCase { // PHPUnit_Extension
         */
        function createTestPageIfMissing( $pageName = null ) {
                if ( $pageName == null ) {
-                       $pageName = SeleniumTestConstants::WIKI_INTERNAL_LINK;          
+                       $pageName = SeleniumTestConstants::WIKI_INTERNAL_LINK;
                }
-               $this->type( SeleniumTestConstants::INPUT_SEARCH_BOX, $pageName  );
+               $this->type( SeleniumTestConstants::INPUT_SEARCH_BOX, $pageName );
                $this->click( SeleniumTestConstants::BUTTON_SEARCH );
                $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME );
                $this->click( SeleniumTestConstants::LINK_START . $pageName );
                $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME );
-               $location =  $this->getLocation() . "\n";
-               if ( strpos( $location, '&redlink=1') !== false  ) {
-                       $this->type( SeleniumTestConstants::TEXT_EDITOR,  "Test fixture page. No real content here" );
+               $location = $this->getLocation() . "\n";
+               if ( strpos( $location, '&redlink=1' ) !== false ) {
+                       $this->type( SeleniumTestConstants::TEXT_EDITOR, "Test fixture page. No real content here" );
                        $this->click( SeleniumTestConstants::BUTTON_SAVE );
                        $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME );
                        $this->assertTrue( $this->isTextPresent( $pageName ),
-                       $this->getText( SeleniumTestConstants::TEXT_PAGE_HEADING ) );
+                               $this->getText( SeleniumTestConstants::TEXT_PAGE_HEADING ) );
                }
        }
-       
+
        /**
         * Create a test page using date as part of the name so that it is unique
         * @param $pagePrefix The prefix to use for the page name. The current date will be appended to this to make it unique
         * @param $watchThis Whether to add the page to my watchlist. Defaults to false.
         */
        function createNewTestPage( $pagePrefix, $watchThis = false ) {
-               $pageName = $pagePrefix . date("Ymd-His");
-               $this->type( SeleniumTestConstants::INPUT_SEARCH_BOX, $pageName  );
+               $pageName = $pagePrefix . date( "Ymd-His" );
+               $this->type( SeleniumTestConstants::INPUT_SEARCH_BOX, $pageName );
                $this->click( SeleniumTestConstants::BUTTON_SEARCH );
                $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME );
                $this->click( SeleniumTestConstants::LINK_START . $pageName );
                $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME );
-               $location =  $this->getLocation() . "\n";
-               $this->assertContains( '&redlink=1', $location ).
-               $this->type( SeleniumTestConstants::TEXT_EDITOR,  "Test fixture page. No real content here" );
+               $location = $this->getLocation() . "\n";
+               $this->assertContains( '&redlink=1', $location ) .
+                       $this->type( SeleniumTestConstants::TEXT_EDITOR, "Test fixture page. No real content here" );
                if ( $watchThis ) {
                        $this->click( "wpWatchthis" );
                }
                $this->click( SeleniumTestConstants::BUTTON_SAVE );
                $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME );
                $this->assertTrue( $this->isTextPresent( $pageName ),
-               $this->getText( SeleniumTestConstants::TEXT_PAGE_HEADING ) );
+                       $this->getText( SeleniumTestConstants::TEXT_PAGE_HEADING ) );
                return $pageName;
        }
 
-       public function getExistingPage(){
+       public function getExistingPage() {
                $this->open( $this->getUrl() .
                        '/index.php?title=Main_Page&action=edit' );
-               $this->type("searchInput", "new" );
-               $this->click("searchGoButton");
-               $this->waitForPageToLoad("30000");
+               $this->type( "searchInput", "new" );
+               $this->click( "searchGoButton" );
+               $this->waitForPageToLoad( "30000" );
        }
 
-       public function getNewPage($pageName){
+       public function getNewPage( $pageName ) {
 
                $this->open( $this->getUrl() .
                        '/index.php?title=Main_Page&action=edit' );
-               $this->type("searchInput", $pageName );
-               $this->click("searchGoButton");
-               $this->waitForPageToLoad("30000");
-               $this->click("link=".$pageName);
-               $this->waitForPageToLoad("600000");
+               $this->type( "searchInput", $pageName );
+               $this->click( "searchGoButton" );
+               $this->waitForPageToLoad( "30000" );
+               $this->click( "link=" . $pageName );
+               $this->waitForPageToLoad( "600000" );
 
 
        }
+
        // Loading the mediawiki editor
-       public function loadWikiEditor(){
+       public function loadWikiEditor() {
                $this->open( $this->getUrl() .
                        '/index.php?title=Main_Page&action=edit' );
        }
 
        // Clear the content of the mediawiki editor
-       public function clearWikiEditor(){
-               $this->type("wpTextbox1", "");
+       public function clearWikiEditor() {
+               $this->type( "wpTextbox1", "" );
        }
 
        // Click on the 'Show preview' button of the mediawiki editor
-       public function clickShowPreviewBtn(){
-               $this->click("wpPreview");
+       public function clickShowPreviewBtn() {
+               $this->click( "wpPreview" );
        }
 
        // Click on the 'Save Page' button of the mediawiki editor
-       public function clickSavePageBtn(){
-               $this->click("wpSave");
+       public function clickSavePageBtn() {
+               $this->click( "wpSave" );
        }
 
        // Click on the 'Edit' link
-       public function clickEditLink(){
-               $this->click("link=Edit");
-               $this->waitForPageToLoad("30000");
+       public function clickEditLink() {
+               $this->click( "link=Edit" );
+               $this->waitForPageToLoad( "30000" );
        }
-
 }
index 9436f67..dc0ac66 100644 (file)
@@ -14,20 +14,17 @@ class SeleniumTestListener implements PHPUnit_Framework_TestListener {
                $this->tests_failed++;
        }
 
-       public function addFailure( PHPUnit_Framework_Test $test, PHPUnit_Framework_AssertionFailedError $e, $time )
-       {
+       public function addFailure( PHPUnit_Framework_Test $test, PHPUnit_Framework_AssertionFailedError $e, $time ) {
                $this->logger->write( 'Failed: ' . $e->getMessage() );
                $this->tests_failed++;
        }
 
-       public function addIncompleteTest( PHPUnit_Framework_Test $test, Exception $e, $time )
-       {
+       public function addIncompleteTest( PHPUnit_Framework_Test $test, Exception $e, $time ) {
                $this->logger->write( 'Incomplete.' );
                $this->tests_failed++;
        }
 
-       public function addSkippedTest( PHPUnit_Framework_Test $test, Exception $e, $time )
-       {
+       public function addSkippedTest( PHPUnit_Framework_Test $test, Exception $e, $time ) {
                $this->logger->write( 'Skipped.' );
                $this->tests_failed++;
        }
@@ -53,7 +50,7 @@ class SeleniumTestListener implements PHPUnit_Framework_TestListener {
        }
 
        public function endTestSuite( PHPUnit_Framework_TestSuite $suite ) {
-               $this->logger->write('Testsuite ' . $suite->getName() . ' ended.' );
+               $this->logger->write( 'Testsuite ' . $suite->getName() . ' ended.' );
                if ( $this->tests_ok > 0 || $this->tests_failed > 0 ) {
                        $this->logger->write( ' OK: ' . $this->tests_ok . ' Failed: ' . $this->tests_failed );
                }
index 81a630f..6cbc1c7 100644 (file)
@@ -25,7 +25,7 @@ abstract class SeleniumTestSuite extends PHPUnit_Framework_TestSuite {
                if ( $this->triggerClientTestResources ) {
                        $this->selenium->open( $this->selenium->getUrl() . '/index.php?setupTestSuite=' . $this->getName() );
                        //wait a little longer for the db operation
-                       $this->selenium->waitForPageToLoad( 6000  );
+                       $this->selenium->waitForPageToLoad( 6000 );
                }
                if ( $this->loginBeforeTests ) {
                        $this->login();
@@ -50,7 +50,7 @@ abstract class SeleniumTestSuite extends PHPUnit_Framework_TestSuite {
        protected function setLoginBeforeTests( $loginBeforeTests = true ) {
                $this->loginBeforeTests = $loginBeforeTests;
        }
-       
+
        protected function setTriggerClientTestResources( $triggerClientTestResources = true ) {
                $this->triggerClientTestResources = $triggerClientTestResources;
        }
index 8bca4b0..341b316 100644 (file)
  */
 
 
-require_once (__DIR__.'/'.'MediaWikiInstallationCommonFunction.php');
+require_once ( __DIR__ . '/' . 'MediaWikiInstallationCommonFunction.php' );
 
 /**
  * Test Case ID   : 30 (http://www.mediawiki.org/wiki/New_installer/Test_plan)
  * Test Case Name :'Back' and 'Continue' button availability
  * Version        : MediaWiki 1.18alpha
-*/
-
+ */
 
 class MediaWikiButtonsAvailabilityTestCase extends MediaWikiInstallationCommonFunction {
-
-    function setUp() {
-        parent::setUp();
-    }
-
-
-    // Verify only 'Continue' button available on 'Language' page
-    public function testOnlyContinueButtonAvailability() {
-
-        parent::navigateLanguagePage();
-
-        // Verify only 'Continue' button avaialble
-        $this->assertTrue( $this->isElementPresent( "submit-continue" ));
-
-        // 'Back' button is not avaialble
-        $this->assertElementNotPresent( "submit-back" );
-    }
-
-
-    // Verify 'Continue' and 'Back' buttons availability
-    public function testBothButtonsAvailability() {
-
-        // Verify buttons availability on 'Welcome to MediaWiki' page
-        parent::navigateWelcometoMediaWikiPage();
-        $this->assertTrue( $this->isElementPresent( "submit-back" ));
-        $this->assertTrue( $this->isElementPresent( "submit-continue" ));
-        parent::restartInstallation();
-
-        // Verify buttons availability on 'Connect to Database' page
-        parent::navigateConnetToDatabasePage();
-        $this->assertTrue( $this->isElementPresent( "submit-back" ));
-        $this->assertTrue( $this->isElementPresent( "submit-continue" ));
-        parent::restartInstallation();
-
-        // Verify buttons availability on 'Database settings' page
-        $databaseName = DB_NAME_PREFIX."_db_settings";
-        parent::navigateDatabaseSettingsPage( $databaseName );
-        $this->assertTrue( $this->isElementPresent( "submit-back" ));
-        $this->assertTrue( $this->isElementPresent( "submit-continue" ));
-        parent::restartInstallation();
-
-        // Verify buttons availability on 'Name' page
-        $databaseName = DB_NAME_PREFIX."_name";
-        parent::navigateNamePage( $databaseName );
-        $this->assertTrue( $this->isElementPresent( "submit-back" ));
-        $this->assertTrue( $this->isElementPresent( "submit-continue" ));
-        parent::restartInstallation();
-
-        // Verify buttons availability on 'Options' page
-        $databaseName = DB_NAME_PREFIX."_options";
-        parent::navigateOptionsPage( $databaseName );
-        $this->assertTrue( $this->isElementPresent( "submit-back" ));
-        $this->assertTrue( $this->isElementPresent( "submit-continue" ));
-        parent::restartInstallation();
-
-        // Verify buttons availability on 'Install' page
-        $databaseName = DB_NAME_PREFIX."_install";
-        parent::navigateInstallPage($databaseName);
-        $this->assertTrue( $this->isElementPresent( "submit-back" ));
-        $this->assertTrue( $this->isElementPresent( "submit-continue" ));
-    }
+       function setUp() {
+               parent::setUp();
+       }
+
+       // Verify only 'Continue' button available on 'Language' page
+       public function testOnlyContinueButtonAvailability() {
+               parent::navigateLanguagePage();
+
+               // Verify only 'Continue' button avaialble
+               $this->assertTrue( $this->isElementPresent( "submit-continue" ) );
+
+               // 'Back' button is not avaialble
+               $this->assertElementNotPresent( "submit-back" );
+       }
+
+       // Verify 'Continue' and 'Back' buttons availability
+       public function testBothButtonsAvailability() {
+               // Verify buttons availability on 'Welcome to MediaWiki' page
+               parent::navigateWelcometoMediaWikiPage();
+               $this->assertTrue( $this->isElementPresent( "submit-back" ) );
+               $this->assertTrue( $this->isElementPresent( "submit-continue" ) );
+               parent::restartInstallation();
+
+               // Verify buttons availability on 'Connect to Database' page
+               parent::navigateConnetToDatabasePage();
+               $this->assertTrue( $this->isElementPresent( "submit-back" ) );
+               $this->assertTrue( $this->isElementPresent( "submit-continue" ) );
+               parent::restartInstallation();
+
+               // Verify buttons availability on 'Database settings' page
+               $databaseName = DB_NAME_PREFIX . "_db_settings";
+               parent::navigateDatabaseSettingsPage( $databaseName );
+               $this->assertTrue( $this->isElementPresent( "submit-back" ) );
+               $this->assertTrue( $this->isElementPresent( "submit-continue" ) );
+               parent::restartInstallation();
+
+               // Verify buttons availability on 'Name' page
+               $databaseName = DB_NAME_PREFIX . "_name";
+               parent::navigateNamePage( $databaseName );
+               $this->assertTrue( $this->isElementPresent( "submit-back" ) );
+               $this->assertTrue( $this->isElementPresent( "submit-continue" ) );
+               parent::restartInstallation();
+
+               // Verify buttons availability on 'Options' page
+               $databaseName = DB_NAME_PREFIX . "_options";
+               parent::navigateOptionsPage( $databaseName );
+               $this->assertTrue( $this->isElementPresent( "submit-back" ) );
+               $this->assertTrue( $this->isElementPresent( "submit-continue" ) );
+               parent::restartInstallation();
+
+               // Verify buttons availability on 'Install' page
+               $databaseName = DB_NAME_PREFIX . "_install";
+               parent::navigateInstallPage( $databaseName );
+               $this->assertTrue( $this->isElementPresent( "submit-back" ) );
+               $this->assertTrue( $this->isElementPresent( "submit-continue" ) );
+       }
 }
index 8e2afe7..76a794c 100644 (file)
@@ -34,49 +34,46 @@ require_once ( __DIR__ . '/MediaWikiInstallationCommonFunction.php' );
  * Test Case ID   : 04 (http://www.mediawiki.org/wiki/New_installer/Test_plan)
  * Test Case Name : Install MediaWiki with different Database accounts for web access.
  * Version        : MediaWiki 1.18alpha
-*/
+ */
 
 class MediaWikiDifferentDatabaseAccountTestCase extends MediaWikiInstallationCommonFunction {
+       function setUp() {
+               parent::setUp();
+       }
 
-    function setUp() {
-        parent::setUp();
-    }
-
-
-    // Install Mediawiki using 'MySQL' database type.
-    public function testDifferentDatabaseAccount() {
-
-        $databaseName = DB_NAME_PREFIX."_dif_accounts";
+       // Install Mediawiki using 'MySQL' database type.
+       public function testDifferentDatabaseAccount() {
+               $databaseName = DB_NAME_PREFIX . "_dif_accounts";
 
-        // Navigate to the 'Database settings' page
-        parent::navigateDatabaseSettingsPage( $databaseName );
+               // Navigate to the 'Database settings' page
+               parent::navigateDatabaseSettingsPage( $databaseName );
 
-        // Click on the 'Use the same account as for installation' check box
-        $this->click( "mysql__SameAccount" );
+               // Click on the 'Use the same account as for installation' check box
+               $this->click( "mysql__SameAccount" );
 
-        // Change the 'Database username'
-        $this->type( "mysql_wgDBuser", DB_WEB_USER );
+               // Change the 'Database username'
+               $this->type( "mysql_wgDBuser", DB_WEB_USER );
 
-        // Enter 'Database password:'
-        $this->type( "mysql_wgDBpassword", DB_WEB_USER_PASSWORD );
+               // Enter 'Database password:'
+               $this->type( "mysql_wgDBpassword", DB_WEB_USER_PASSWORD );
 
-        // Select 'Create the account if it does not already exist' check box
-        $this->click( "mysql__CreateDBAccount" );
-        parent::clickContinueButton();
+               // Select 'Create the account if it does not already exist' check box
+               $this->click( "mysql__CreateDBAccount" );
+               parent::clickContinueButton();
 
-        // 'Name' page
-        parent::completeNamePage();
+               // 'Name' page
+               parent::completeNamePage();
 
-        // 'Options' page
-        parent::clickContinueButton();
+               // 'Options' page
+               parent::clickContinueButton();
 
-        // 'Install' page
-        $this->assertEquals("Creating database user... done",
-                $this->getText( LINK_FORM."ul/li[3]"));
-        parent::clickContinueButton();
+               // 'Install' page
+               $this->assertEquals( "Creating database user... done",
+                       $this->getText( LINK_FORM . "ul/li[3]" ) );
+               parent::clickContinueButton();
 
-        // 'Complete' page
-        parent::completePageSuccessfull();
-        $this->chooseCancelOnNextConfirmation();
-    }
+               // 'Complete' page
+               parent::completePageSuccessfull();
+               $this->chooseCancelOnNextConfirmation();
+       }
 }
index 55ad461..2c879c3 100644 (file)
@@ -34,62 +34,60 @@ require_once ( __DIR__ . '/MediaWikiInstallationCommonFunction.php' );
  * Test Case Name : Install MediaWiki with the same database and the different
  *                  database prefixes(Share one database between multiple wikis).
  * Version        : MediaWiki 1.18alpha
-*/
+ */
 
 class MediaWikiDifferntDatabasePrefixTestCase extends MediaWikiInstallationCommonFunction {
+       function setUp() {
+               parent::setUp();
+       }
 
-    function setUp() {
-        parent::setUp();
-    }
-
-    // Install Mediawiki using 'MySQL' database type.
-    public function testDifferentDatabasePrefix() {
-
-        $databaseName = DB_NAME_PREFIX."_db_prefix";
-        parent::navigateInstallPage( $databaseName );
+       // Install Mediawiki using 'MySQL' database type.
+       public function testDifferentDatabasePrefix() {
+               $databaseName = DB_NAME_PREFIX . "_db_prefix";
+               parent::navigateInstallPage( $databaseName );
 
-        // To 'Options' page
-        parent::clickBackButton();
+               // To 'Options' page
+               parent::clickBackButton();
 
-        // To 'Name' page
-        parent::clickBackButton();
+               // To 'Name' page
+               parent::clickBackButton();
 
-        // To 'Database settings' page
-        parent::clickBackButton();
+               // To 'Database settings' page
+               parent::clickBackButton();
 
-        // To 'Connect to database' page
-        parent::clickBackButton();
+               // To 'Connect to database' page
+               parent::clickBackButton();
 
-        // From 'Connect to database' page without database prefix
-        parent::clickContinueButton();
+               // From 'Connect to database' page without database prefix
+               parent::clickContinueButton();
 
-        // Verify upgrade existing message
-        $this->assertEquals( "Upgrade existing installation",
-                $this->getText( LINK_DIV."h2" ));
+               // Verify upgrade existing message
+               $this->assertEquals( "Upgrade existing installation",
+                       $this->getText( LINK_DIV . "h2" ) );
 
-        // To 'Connect to database' page
-        parent::clickBackButton();
+               // To 'Connect to database' page
+               parent::clickBackButton();
 
-        // Input the database prefix
-        $this->type( "mysql_wgDBprefix", DATABASE_PREFIX );
+               // Input the database prefix
+               $this->type( "mysql_wgDBprefix", DATABASE_PREFIX );
 
-        // From 'Connect to database' page with database prefix
-        parent::clickContinueButton();
+               // From 'Connect to database' page with database prefix
+               parent::clickContinueButton();
 
-        // To 'Complete' page
-        parent::clickContinueButton();
-        parent::completeNamePage();
-        parent::clickContinueButton();
+               // To 'Complete' page
+               parent::clickContinueButton();
+               parent::completeNamePage();
+               parent::clickContinueButton();
 
-        // Verify already installed warning message
-        $this->assertEquals( "Install",
-                $this->getText( LINK_DIV."h2" ));
-        $this->assertEquals( "Warning: You seem to have already installed MediaWiki and are trying to install it again. Please proceed to the next page.",
-                $this->getText( LINK_FORM."div[1]" ));
+               // Verify already installed warning message
+               $this->assertEquals( "Install",
+                       $this->getText( LINK_DIV . "h2" ) );
+               $this->assertEquals( "Warning: You seem to have already installed MediaWiki and are trying to install it again. Please proceed to the next page.",
+                       $this->getText( LINK_FORM . "div[1]" ) );
 
-        parent::clickContinueButton();
-        parent::completePageSuccessfull();
-        $this->chooseCancelOnNextConfirmation();
-        parent::restartInstallation();
-    }
+               parent::clickContinueButton();
+               parent::completePageSuccessfull();
+               $this->chooseCancelOnNextConfirmation();
+               parent::restartInstallation();
+       }
 }
index 825ca42..7eb6d38 100644 (file)
@@ -34,103 +34,102 @@ require_once ( __DIR__ . '/MediaWikiInstallationCommonFunction.php' );
  * Test Case ID   : 09 (http://www.mediawiki.org/wiki/New_installer/Test_plan)
  * Test Case Name : Invalid/ blank values for fields in 'Connect to database' page.
  * Version        : MediaWiki 1.18alpha
-*/
+ */
 
 class MediaWikiErrorsConnectToDatabasePageTestCase extends MediaWikiInstallationCommonFunction {
 
-    function setUp() {
-        parent::setUp();
-    }
-
-    // Verify warning messages for the 'Connet to database' page
-    public function testErrorsConnectToDatabasePage() {
-
-        parent::navigateConnetToDatabasePage();
-
-        // Verify warning mesage for invalid database host
-        $this->type( "mysql_wgDBserver", INVALID_DB_HOST );
-        parent::clickContinueButton();
-        $this->assertEquals( "DB connection error: php_network_getaddresses: getaddrinfo failed: No such host is known. (".INVALID_DB_HOST.").",
-                $this->getText( LINK_DIV."div[2]/div[2]/p[1]" ));
-        $this->assertEquals( "Check the host, username and password below and try again.",
-                $this->getText( LINK_DIV."div[2]/div[2]/p[2]" ));
-        // Verify warning message for the blank database host
-        $this->type( "mysql_wgDBserver", "" );
-        parent::clickContinueButton();
-        $this->assertEquals( "MySQL 4.0.14 or later is required, you have .",
-                $this->getText( LINK_DIV."div[2]/div[2]" ));
-
-        // Valid Database Host
-        $this->type( "mysql_wgDBserver", VALID_DB_HOST );
-
-        // Verify warning message for the invalid database name
-        $this->type( "mysql_wgDBname", INVALID_DB_NAME );
-        parent::clickContinueButton();
-        $this->assertEquals( "Invalid database name \"".INVALID_DB_NAME."\". Use only ASCII letters (a-z, A-Z), numbers (0-9) and underscores (_).",
-                $this->getText( LINK_DIV."div[2]/div[2]/p" ));
-
-        // Verify warning message for the blank database name
-        $this->type( "mysql_wgDBname", "");
-        parent::clickContinueButton();
-        $this->assertEquals( "You must enter a value for \"Database name\"",
-                $this->getText( LINK_DIV."div[2]/div[2]" ));
-
-        // valid Database name
-        $this->type( "mysql_wgDBname", VALID_DB_NAME);
-
-        // Verify warning message for the invalid databaase prefix
-        $this->type( "mysql_wgDBprefix", INVALID_DB_PREFIX );
-        parent::clickContinueButton();
-        $this->assertEquals( "Invalid database prefix \"".INVALID_DB_PREFIX."\". Use only ASCII letters (a-z, A-Z), numbers (0-9) and underscores (_).",
-                $this->getText( LINK_DIV."div[2]/div[2]" ));
-
-        // Valid Database prefix
-        $this->type( "mysql_wgDBprefix", VALID_DB_PREFIX );
-
-        // Verify warning message for the invalid database user name
-        $this->type( "mysql__InstallUser", INVALID_DB_USER_NAME );
-        parent::clickContinueButton();
-        $this->assertEquals( "DB connection error: Access denied for user '".INVALID_DB_USER_NAME."'@'localhost' (using password: NO) (localhost).",
-                $this->getText( LINK_DIV."div[2]/div[2]/p[1]" ));
-        $this->assertEquals( "Check the host, username and password below and try again.",
-                $this->getText( LINK_DIV."div[2]/div[2]/p[2]"));
-
-        // Verify warning message for the blank database user name
-        $this->type( "mysql__InstallUser", "" );
-        parent::clickContinueButton();
-        $this->assertEquals( "DB connection error: Access denied for user 'SYSTEM'@'localhost' (using password: NO) (localhost).",
-                $this->getText( LINK_DIV."div[2]/div[2]/p[1]" ));
-        $this->assertEquals( "Check the host, username and password below and try again.",
-                $this->getText( LINK_DIV."div[2]/div[2]/p[2]" ));
-
-        // Valid Database username
-        $this->type( "mysql__InstallUser",  VALID_DB_USER_NAME );
-
-        // Verify warning message for the invalid password
-        $this->type( "mysql__InstallPassword", INVALID_DB_PASSWORD );
-        parent::clickContinueButton();
-
-        $this->assertEquals( "DB connection error: Access denied for user 'root'@'localhost' (using password: YES) (localhost).",
-                $this->getText( LINK_DIV."div[2]/div[2]/p[1]" ));
-        $this->assertEquals( "Check the host, username and password below and try again.",
-                $this->getText( LINK_DIV."div[2]/div[2]/p[2]" ));
-
-        // Verify warning message for the invalid username and password
-        $this->type( "mysql__InstallUser", INVALID_DB_USER_NAME );
-        $this->type( "mysql__InstallPassword", INVALID_DB_PASSWORD );
-        parent::clickContinueButton();
-        $this->assertEquals( "DB connection error: Access denied for user '".INVALID_DB_USER_NAME."'@'localhost' (using password: YES) (localhost).",
-                $this->getText( LINK_DIV."div[2]/div[2]/p[1]" ));
-        $this->assertEquals( "Check the host, username and password below and try again.",
-                $this->getText( LINK_DIV."div[2]/div[2]/p[2]" ));
-
-        // Valid username and valid password
-        $this->type( "mysql__InstallUser", VALID_DB_USER_NAME );
-        $this->type( "mysql__InstallPassword", "" );
-        parent::clickContinueButton();
-
-        // successfully completes the 'Connect to database' page
-        $this->assertEquals( "Database settings",
-                $this->getText( LINK_DIV."h2" ));
-    }
+       function setUp() {
+               parent::setUp();
+       }
+
+       // Verify warning messages for the 'Connet to database' page
+       public function testErrorsConnectToDatabasePage() {
+               parent::navigateConnetToDatabasePage();
+
+               // Verify warning mesage for invalid database host
+               $this->type( "mysql_wgDBserver", INVALID_DB_HOST );
+               parent::clickContinueButton();
+               $this->assertEquals( "DB connection error: php_network_getaddresses: getaddrinfo failed: No such host is known. (" . INVALID_DB_HOST . ").",
+                       $this->getText( LINK_DIV . "div[2]/div[2]/p[1]" ) );
+               $this->assertEquals( "Check the host, username and password below and try again.",
+                       $this->getText( LINK_DIV . "div[2]/div[2]/p[2]" ) );
+               // Verify warning message for the blank database host
+               $this->type( "mysql_wgDBserver", "" );
+               parent::clickContinueButton();
+               $this->assertEquals( "MySQL 4.0.14 or later is required, you have .",
+                       $this->getText( LINK_DIV . "div[2]/div[2]" ) );
+
+               // Valid Database Host
+               $this->type( "mysql_wgDBserver", VALID_DB_HOST );
+
+               // Verify warning message for the invalid database name
+               $this->type( "mysql_wgDBname", INVALID_DB_NAME );
+               parent::clickContinueButton();
+               $this->assertEquals( "Invalid database name \"" . INVALID_DB_NAME . "\". Use only ASCII letters (a-z, A-Z), numbers (0-9) and underscores (_).",
+                       $this->getText( LINK_DIV . "div[2]/div[2]/p" ) );
+
+               // Verify warning message for the blank database name
+               $this->type( "mysql_wgDBname", "" );
+               parent::clickContinueButton();
+               $this->assertEquals( "You must enter a value for \"Database name\"",
+                       $this->getText( LINK_DIV . "div[2]/div[2]" ) );
+
+               // valid Database name
+               $this->type( "mysql_wgDBname", VALID_DB_NAME );
+
+               // Verify warning message for the invalid databaase prefix
+               $this->type( "mysql_wgDBprefix", INVALID_DB_PREFIX );
+               parent::clickContinueButton();
+               $this->assertEquals( "Invalid database prefix \"" . INVALID_DB_PREFIX . "\". Use only ASCII letters (a-z, A-Z), numbers (0-9) and underscores (_).",
+                       $this->getText( LINK_DIV . "div[2]/div[2]" ) );
+
+               // Valid Database prefix
+               $this->type( "mysql_wgDBprefix", VALID_DB_PREFIX );
+
+               // Verify warning message for the invalid database user name
+               $this->type( "mysql__InstallUser", INVALID_DB_USER_NAME );
+               parent::clickContinueButton();
+               $this->assertEquals( "DB connection error: Access denied for user '" . INVALID_DB_USER_NAME . "'@'localhost' (using password: NO) (localhost).",
+                       $this->getText( LINK_DIV . "div[2]/div[2]/p[1]" ) );
+               $this->assertEquals( "Check the host, username and password below and try again.",
+                       $this->getText( LINK_DIV . "div[2]/div[2]/p[2]" ) );
+
+               // Verify warning message for the blank database user name
+               $this->type( "mysql__InstallUser", "" );
+               parent::clickContinueButton();
+               $this->assertEquals( "DB connection error: Access denied for user 'SYSTEM'@'localhost' (using password: NO) (localhost).",
+                       $this->getText( LINK_DIV . "div[2]/div[2]/p[1]" ) );
+               $this->assertEquals( "Check the host, username and password below and try again.",
+                       $this->getText( LINK_DIV . "div[2]/div[2]/p[2]" ) );
+
+               // Valid Database username
+               $this->type( "mysql__InstallUser", VALID_DB_USER_NAME );
+
+               // Verify warning message for the invalid password
+               $this->type( "mysql__InstallPassword", INVALID_DB_PASSWORD );
+               parent::clickContinueButton();
+
+               $this->assertEquals( "DB connection error: Access denied for user 'root'@'localhost' (using password: YES) (localhost).",
+                       $this->getText( LINK_DIV . "div[2]/div[2]/p[1]" ) );
+               $this->assertEquals( "Check the host, username and password below and try again.",
+                       $this->getText( LINK_DIV . "div[2]/div[2]/p[2]" ) );
+
+               // Verify warning message for the invalid username and password
+               $this->type( "mysql__InstallUser", INVALID_DB_USER_NAME );
+               $this->type( "mysql__InstallPassword", INVALID_DB_PASSWORD );
+               parent::clickContinueButton();
+               $this->assertEquals( "DB connection error: Access denied for user '" . INVALID_DB_USER_NAME . "'@'localhost' (using password: YES) (localhost).",
+                       $this->getText( LINK_DIV . "div[2]/div[2]/p[1]" ) );
+               $this->assertEquals( "Check the host, username and password below and try again.",
+                       $this->getText( LINK_DIV . "div[2]/div[2]/p[2]" ) );
+
+               // Valid username and valid password
+               $this->type( "mysql__InstallUser", VALID_DB_USER_NAME );
+               $this->type( "mysql__InstallPassword", "" );
+               parent::clickContinueButton();
+
+               // successfully completes the 'Connect to database' page
+               $this->assertEquals( "Database settings",
+                       $this->getText( LINK_DIV . "h2" ) );
+       }
 }
index c2b3505..e3d4266 100644 (file)
  * Test Case ID   : 10 (http://www.mediawiki.org/wiki/New_installer/Test_plan)
  * Test Case Name : Invalid/ blank values for fields in 'Name' page.
  * Version        : MediaWiki 1.18alpha
-*/
+ */
 
 require_once ( __DIR__ . '/MediaWikiInstallationCommonFunction.php' );
 
 class MediaWikiErrorsNamepageTestCase extends MediaWikiInstallationCommonFunction {
-
-    function setUp() {
-        parent::setUp();
-    }
-
-    // Verify warning message for the 'Name' page
-    public function testErrorsNamePage() {
-
-        $databaseName  = DB_NAME_PREFIX."_error_name";
-
-        parent::navigateNamePage( $databaseName );
-
-        // Verify warning message for all blank fields
-        parent::clickContinueButton();
-        $this->assertEquals( "Enter a site name.",
-                $this->getText( LINK_DIV."div[2]/div[2]" ));
-        $this->assertEquals( "Enter an administrator username.",
-                $this->getText( LINK_DIV."div[3]/div[2]" ));
-        $this->assertEquals( "Enter a password for the administrator account.",
-                $this->getText( LINK_DIV."div[4]/div[2]" ));
-
-        // Verify warning message for the blank 'Site name'
-        $this->type( "config__AdminName", VALID_YOUR_NAME );
-        $this->type( "config__AdminPassword", VALID_PASSWORD );
-        $this->type( "config__AdminPassword2", VALID_PASSWORD_AGAIN );
-        parent::clickContinueButton();
-        $this->assertEquals( "Enter a site name.",
-                $this->getText( LINK_DIV."div[2]/div[2]" ));
-
-        // Input valid 'Site name'
-        $this->type( "config_wgSitename", VALID_WIKI_NAME );
-
-
-        // Verify warning message for the invalid "Project namespace'
-        $this->click( "config__NamespaceType_other" );
-        $this->type( "config_wgMetaNamespace", INVALID_NAMESPACE );
-        parent::clickContinueButton();
-        $this->assertEquals( "The specified namespace \"\" is invalid. Specify a different project namespace.",
-                $this->getText( LINK_DIV."div[2]/div[2]" ));
-
-
-        // Verify warning message for the blank 'Project namespace'
-        $this->type( "config_wgSitename",  VALID_WIKI_NAME );
-        $this->click( "config__NamespaceType_other" );
-        $this->type( "config_wgMetaNamespace" , "" );
-        parent::clickContinueButton();
-        $this->assertEquals( "The specified namespace \"\" is invalid. Specify a different project namespace.",
-                $this->getText( LINK_DIV."div[2]/div[2]" ));
-
-
-        // Valid 'Project namespace'
-        $this->click( "config__NamespaceType_other" );
-        $this->type( "config_wgMetaNamespace", VALID_NAMESPACE );
-        parent::clickContinueButton();
-
-
-        // Valid 'Site name'
-        $this->click( "config__NamespaceType_site-name" );
-        $this->type( "config_wgSitename", VALID_WIKI_NAME );
-
-
-        // Verify warning message for blank 'Your name'
-        $this->type( "config__AdminName", " " );
-        parent::clickContinueButton();
-        $this->assertEquals( "Enter an administrator username.",
-                $this->getText( LINK_DIV."div[2]/div[2]" ));
-
-        $this->type( "config_wgSitename", VALID_WIKI_NAME );
-        // Verify warning message for blank 'Password'
-        $this->type( "config__AdminName", VALID_YOUR_NAME );
-        $this->type( "config__AdminPassword", " " );
-        parent::clickContinueButton();
-        $this->assertEquals( "Enter a password for the administrator account.",
-                $this->getText( LINK_DIV."div[2]/div[2]" ));
-
-
-        // Verify warning message for the blank 'Password again'
-        $this->type( "config_wgSitename", VALID_WIKI_NAME );
-        $this->type( "config__AdminPassword", VALID_PASSWORD );
-        $this->type( "config__AdminPassword2", " " );
-        parent::clickContinueButton();
-        $this->assertEquals( "The two passwords you entered do not match.",
-                $this->getText( LINK_DIV."div[2]/div[2]" ));
-
-
-        // Verify warning message for the different'Password' and 'Password again'
-        $this->type( "config_wgSitename", VALID_WIKI_NAME );
-        $this->type( "config__AdminPassword", VALID_PASSWORD );
-        $this->type( "config__AdminPassword2", INVALID_PASSWORD_AGAIN );
-        parent::clickContinueButton();
-        $this->assertEquals( "The two passwords you entered do not match.",
-                $this->getText( LINK_DIV."div[2]/div[2]" ));
-    }
+       function setUp() {
+               parent::setUp();
+       }
+
+       // Verify warning message for the 'Name' page
+       public function testErrorsNamePage() {
+
+               $databaseName = DB_NAME_PREFIX . "_error_name";
+
+               parent::navigateNamePage( $databaseName );
+
+               // Verify warning message for all blank fields
+               parent::clickContinueButton();
+               $this->assertEquals( "Enter a site name.",
+                       $this->getText( LINK_DIV . "div[2]/div[2]" ) );
+               $this->assertEquals( "Enter an administrator username.",
+                       $this->getText( LINK_DIV . "div[3]/div[2]" ) );
+               $this->assertEquals( "Enter a password for the administrator account.",
+                       $this->getText( LINK_DIV . "div[4]/div[2]" ) );
+
+               // Verify warning message for the blank 'Site name'
+               $this->type( "config__AdminName", VALID_YOUR_NAME );
+               $this->type( "config__AdminPassword", VALID_PASSWORD );
+               $this->type( "config__AdminPassword2", VALID_PASSWORD_AGAIN );
+               parent::clickContinueButton();
+               $this->assertEquals( "Enter a site name.",
+                       $this->getText( LINK_DIV . "div[2]/div[2]" ) );
+
+               // Input valid 'Site name'
+               $this->type( "config_wgSitename", VALID_WIKI_NAME );
+
+               // Verify warning message for the invalid "Project namespace'
+               $this->click( "config__NamespaceType_other" );
+               $this->type( "config_wgMetaNamespace", INVALID_NAMESPACE );
+               parent::clickContinueButton();
+               $this->assertEquals( "The specified namespace \"\" is invalid. Specify a different project namespace.",
+                       $this->getText( LINK_DIV . "div[2]/div[2]" ) );
+
+               // Verify warning message for the blank 'Project namespace'
+               $this->type( "config_wgSitename", VALID_WIKI_NAME );
+               $this->click( "config__NamespaceType_other" );
+               $this->type( "config_wgMetaNamespace", "" );
+               parent::clickContinueButton();
+               $this->assertEquals( "The specified namespace \"\" is invalid. Specify a different project namespace.",
+                       $this->getText( LINK_DIV . "div[2]/div[2]" ) );
+
+               // Valid 'Project namespace'
+               $this->click( "config__NamespaceType_other" );
+               $this->type( "config_wgMetaNamespace", VALID_NAMESPACE );
+               parent::clickContinueButton();
+
+               // Valid 'Site name'
+               $this->click( "config__NamespaceType_site-name" );
+               $this->type( "config_wgSitename", VALID_WIKI_NAME );
+
+               // Verify warning message for blank 'Your name'
+               $this->type( "config__AdminName", " " );
+               parent::clickContinueButton();
+               $this->assertEquals( "Enter an administrator username.",
+                       $this->getText( LINK_DIV . "div[2]/div[2]" ) );
+
+               $this->type( "config_wgSitename", VALID_WIKI_NAME );
+               // Verify warning message for blank 'Password'
+               $this->type( "config__AdminName", VALID_YOUR_NAME );
+               $this->type( "config__AdminPassword", " " );
+               parent::clickContinueButton();
+               $this->assertEquals( "Enter a password for the administrator account.",
+                       $this->getText( LINK_DIV . "div[2]/div[2]" ) );
+
+               // Verify warning message for the blank 'Password again'
+               $this->type( "config_wgSitename", VALID_WIKI_NAME );
+               $this->type( "config__AdminPassword", VALID_PASSWORD );
+               $this->type( "config__AdminPassword2", " " );
+               parent::clickContinueButton();
+               $this->assertEquals( "The two passwords you entered do not match.",
+                       $this->getText( LINK_DIV . "div[2]/div[2]" ) );
+
+               // Verify warning message for the different'Password' and 'Password again'
+               $this->type( "config_wgSitename", VALID_WIKI_NAME );
+               $this->type( "config__AdminPassword", VALID_PASSWORD );
+               $this->type( "config__AdminPassword2", INVALID_PASSWORD_AGAIN );
+               parent::clickContinueButton();
+               $this->assertEquals( "The two passwords you entered do not match.",
+                       $this->getText( LINK_DIV . "div[2]/div[2]" ) );
+       }
 }
index 78205cf..961f692 100644 (file)
  * Test Case ID   : 29 (http://www.mediawiki.org/wiki/New_installer/Test_plan)
  * Test Case Name : Help field hint availability for the fields.
  * Version        : MediaWiki 1.18alpha
-*/
+ */
 
 require_once ( __DIR__ . '/MediaWikiInstallationCommonFunction.php' );
 
 class MediaWikiHelpFieldHintTestCase extends MediaWikiInstallationCommonFunction {
-
-    function setUp() {
-        parent::setUp();
-    }
-
-
-    // Verify help field availability for the fields
-    public function testMySQLConnectToDatabaseFieldHint() {
-
-        parent::navigateConnetToDatabasePage();
-
-        // Verify help field for 'Database host'
-        $this->click( "//div[@id='DB_wrapper_mysql']/div/div[1]/div/span[1]" );
-        $this->assertEquals( MYSQL_DATABASE_HOST_HELP,
-                $this->getText( "//div[@id='DB_wrapper_mysql']/div/div[1]/div/span[2]" ) );
-
-        // Verify help field for 'Database name'
-        $this->click( "//div[@id='DB_wrapper_mysql']/fieldset[1]/div[1]/div[1]/div/span[1]" );
-        $this->assertEquals( MYSQL_DATABASE_NAME_HELP,
-                $this->getText( "//div[@id='DB_wrapper_mysql']/fieldset[1]/div[1]/div[1]/div/span[2]" ));
-
-
-        // Verify help field for 'Database table prefix'
-        $this->click("//div[@id='DB_wrapper_mysql']/fieldset[1]/div[2]/div[1]/div/span[1]" );
-        $this->assertEquals(MYSQL_DATABASE_TABLE_PREFIX_HELP,
-                $this->getText("//div[@id='DB_wrapper_mysql']/fieldset[1]/div[1]/div[1]/div/span[2]/p[1]" ));
-
-        // Verify help field for 'Database username'
-        $this->click( "//div[@id='DB_wrapper_mysql']/fieldset[2]/div[1]/div[1]/div/span[1]" );
-        $this->assertEquals( MYSQL_DATBASE_USERNAME_HELP,
-                $this->getText( "//div[@id='DB_wrapper_mysql']/fieldset[2]/div[1]/div[1]/div/span[2]" ));
-
-        // Verify help field for 'Database password'
-        $this->click( "//div[@id='DB_wrapper_mysql']/fieldset[2]/div[2]/div[1]/div/span[1]" );
-        $this->assertEquals( MYSQL_DATABASE_PASSWORD_HELP,
-                $this->getText( "//div[@id='DB_wrapper_mysql']/fieldset[2]/div[2]/div[1]/div/span[2]/p" ));
-    }
-
-
-    public function testSQLiteConnectToDatabaseFieldHint() {
-
-        parent::navigateConnetToDatabasePage();
-        $this->click( "DBType_sqlite" );
-
-        //  Verify help field for 'SQLite data directory'
-        $this->click( "//div[@id='DB_wrapper_sqlite']/div[1]/div[1]/div/span[1]" );
-        $this->assertEquals( SQLITE_DATA_DIRECTORY_HELP,
-                $this->getText( "//div[@id='DB_wrapper_sqlite']/div[1]/div[1]/div/span[2]" ));
-
-        // Verify help field for 'Database name'
-        $this->click( "//div[@id='DB_wrapper_sqlite']/div[2]/div[1]/div/span[1]" );
-        $this->assertEquals( SQLITE_DATABASE_NAME_HELP , $this->getText( "//div[@id='DB_wrapper_sqlite']/div[2]/div[1]/div/span[2]/p" ));
-    }
-
-
-    public function testDatabaseSettingsFieldHint() {
-
-        $databaseName = DB_NAME_PREFIX."_db_field";
-        parent::navigateDatabaseSettingsPage($databaseName);
-
-        // Verify help field for 'Search engine'
-        $this->click( LINK_FORM."div[2]/span[1]" );
-        $this->assertEquals( SEARCH_ENGINE_HELP,
-                $this->getText( LINK_FORM."div[2]/span[2]" ));
-
-        // Verify help field for 'Database character set'
-        $this->click( LINK_FORM."div[4]/span[1]" );
-        $this->assertEquals( DATABASE_CHARACTER_SET_HELP,
-                $this->getText( LINK_FORM."div[4]/span[2]"));
-        parent::restartInstallation();
-    }
-
-
-    public function testNameFieldHint() {
-
-        $databaseName = DB_NAME_PREFIX."_name_field";
-        parent::navigateNamePage( $databaseName );
-
-        // Verify help field for 'Name of Wiki'
-        $this->click( LINK_FORM."div[1]/div[1]/div/span[1]" );
-        $this->assertEquals( NAME_OF_WIKI_HELP,
-                $this->getText( LINK_FORM."div[1]/div[1]/div/span[2]/p" ));
-
-        // Verify help field for 'Project namespace'
-        $this->click( LINK_FORM."div[2]/div[1]/div/span[1]" );
-        $this->assertEquals( PROJECT_NAMESPACE_HELP,
-                $this->getText( LINK_FORM."div[2]/div[1]/div/span[2]/p"));
-
-        // Verify help field for 'Your Name'
-        $this->click( LINK_FORM."fieldset/div[1]/div[1]/div/span[1]" );
-        $this->assertEquals( USER_NAME_HELP,
-                $this->getText( LINK_FORM."fieldset/div[1]/div[1]/div/span[2]/p" ));
-
-        // Verify help field for 'E mail address'
-        $this->click( LINK_FORM."fieldset/div[4]/div[1]/div/span[1]" );
-        $this->assertEquals( EMAIL_ADDRESS_HELP,
-                $this->getText( LINK_FORM."fieldset/div[4]/div[1]/div/span[2]/p" ));
-
-        parent::restartInstallation();
-    }
+       function setUp() {
+               parent::setUp();
+       }
+
+       // Verify help field availability for the fields
+       public function testMySQLConnectToDatabaseFieldHint() {
+
+               parent::navigateConnetToDatabasePage();
+
+               // Verify help field for 'Database host'
+               $this->click( "//div[@id='DB_wrapper_mysql']/div/div[1]/div/span[1]" );
+               $this->assertEquals( MYSQL_DATABASE_HOST_HELP,
+                       $this->getText( "//div[@id='DB_wrapper_mysql']/div/div[1]/div/span[2]" ) );
+
+               // Verify help field for 'Database name'
+               $this->click( "//div[@id='DB_wrapper_mysql']/fieldset[1]/div[1]/div[1]/div/span[1]" );
+               $this->assertEquals( MYSQL_DATABASE_NAME_HELP,
+                       $this->getText( "//div[@id='DB_wrapper_mysql']/fieldset[1]/div[1]/div[1]/div/span[2]" ) );
+
+
+               // Verify help field for 'Database table prefix'
+               $this->click( "//div[@id='DB_wrapper_mysql']/fieldset[1]/div[2]/div[1]/div/span[1]" );
+               $this->assertEquals( MYSQL_DATABASE_TABLE_PREFIX_HELP,
+                       $this->getText( "//div[@id='DB_wrapper_mysql']/fieldset[1]/div[1]/div[1]/div/span[2]/p[1]" ) );
+
+               // Verify help field for 'Database username'
+               $this->click( "//div[@id='DB_wrapper_mysql']/fieldset[2]/div[1]/div[1]/div/span[1]" );
+               $this->assertEquals( MYSQL_DATBASE_USERNAME_HELP,
+                       $this->getText( "//div[@id='DB_wrapper_mysql']/fieldset[2]/div[1]/div[1]/div/span[2]" ) );
+
+               // Verify help field for 'Database password'
+               $this->click( "//div[@id='DB_wrapper_mysql']/fieldset[2]/div[2]/div[1]/div/span[1]" );
+               $this->assertEquals( MYSQL_DATABASE_PASSWORD_HELP,
+                       $this->getText( "//div[@id='DB_wrapper_mysql']/fieldset[2]/div[2]/div[1]/div/span[2]/p" ) );
+       }
+
+       public function testSQLiteConnectToDatabaseFieldHint() {
+               parent::navigateConnetToDatabasePage();
+               $this->click( "DBType_sqlite" );
+
+               //  Verify help field for 'SQLite data directory'
+               $this->click( "//div[@id='DB_wrapper_sqlite']/div[1]/div[1]/div/span[1]" );
+               $this->assertEquals( SQLITE_DATA_DIRECTORY_HELP,
+                       $this->getText( "//div[@id='DB_wrapper_sqlite']/div[1]/div[1]/div/span[2]" ) );
+
+               // Verify help field for 'Database name'
+               $this->click( "//div[@id='DB_wrapper_sqlite']/div[2]/div[1]/div/span[1]" );
+               $this->assertEquals( SQLITE_DATABASE_NAME_HELP, $this->getText( "//div[@id='DB_wrapper_sqlite']/div[2]/div[1]/div/span[2]/p" ) );
+       }
+
+       public function testDatabaseSettingsFieldHint() {
+
+               $databaseName = DB_NAME_PREFIX . "_db_field";
+               parent::navigateDatabaseSettingsPage( $databaseName );
+
+               // Verify help field for 'Search engine'
+               $this->click( LINK_FORM . "div[2]/span[1]" );
+               $this->assertEquals( SEARCH_ENGINE_HELP,
+                       $this->getText( LINK_FORM . "div[2]/span[2]" ) );
+
+               // Verify help field for 'Database character set'
+               $this->click( LINK_FORM . "div[4]/span[1]" );
+               $this->assertEquals( DATABASE_CHARACTER_SET_HELP,
+                       $this->getText( LINK_FORM . "div[4]/span[2]" ) );
+               parent::restartInstallation();
+       }
+
+       public function testNameFieldHint() {
+               $databaseName = DB_NAME_PREFIX . "_name_field";
+               parent::navigateNamePage( $databaseName );
+
+               // Verify help field for 'Name of Wiki'
+               $this->click( LINK_FORM . "div[1]/div[1]/div/span[1]" );
+               $this->assertEquals( NAME_OF_WIKI_HELP,
+                       $this->getText( LINK_FORM . "div[1]/div[1]/div/span[2]/p" ) );
+
+               // Verify help field for 'Project namespace'
+               $this->click( LINK_FORM . "div[2]/div[1]/div/span[1]" );
+               $this->assertEquals( PROJECT_NAMESPACE_HELP,
+                       $this->getText( LINK_FORM . "div[2]/div[1]/div/span[2]/p" ) );
+
+               // Verify help field for 'Your Name'
+               $this->click( LINK_FORM . "fieldset/div[1]/div[1]/div/span[1]" );
+               $this->assertEquals( USER_NAME_HELP,
+                       $this->getText( LINK_FORM . "fieldset/div[1]/div[1]/div/span[2]/p" ) );
+
+               // Verify help field for 'E mail address'
+               $this->click( LINK_FORM . "fieldset/div[4]/div[1]/div/span[1]" );
+               $this->assertEquals( EMAIL_ADDRESS_HELP,
+                       $this->getText( LINK_FORM . "fieldset/div[4]/div[1]/div/span[2]/p" ) );
+
+               parent::restartInstallation();
+       }
 }
 
index 353fa2e..06bad30 100644 (file)
 require_once 'PHPUnit/Extensions/SeleniumTestCase.php';
 require_once ( __DIR__ . '/MediaWikiInstallationConfig.php' );
 require_once ( __DIR__ . '/MediaWikiInstallationMessage.php' );
-require_once ( __DIR__ . '/MediaWikiInstallationVariables.php');
-
+require_once ( __DIR__ . '/MediaWikiInstallationVariables.php' );
 
 class MediaWikiInstallationCommonFunction extends PHPUnit_Extensions_SeleniumTestCase {
-
-    function setUp() {
-        $this->setBrowser( TEST_BROWSER );
-        $this->setBrowserUrl("http://".HOST_NAME.":".PORT."/".DIRECTORY_NAME."/");
-    }
-
-
-    public function navigateInitialpage() {
-        $this->open( "http://".HOST_NAME.":".PORT."/".DIRECTORY_NAME."/" );
-    }
-
-
-    // Navigate to the 'Language' page
-    public function navigateLanguagePage() {
-        $this->open( "http://".HOST_NAME.":".PORT."/".DIRECTORY_NAME."/config/index.php" );
-    }
-
-
-    // Navigate to the 'Welcome to MediaWiki' page
-    public function navigateWelcometoMediaWikiPage() {
-        $this->open( "http://".HOST_NAME.":".PORT."/".DIRECTORY_NAME."/config/index.php" );
-        $this->click( "submit-continue ");
-        $this->waitForPageToLoad( PAGE_LOAD_TIME );
-    }
-
-
-    // Navigate yo 'Connect to Database' page
-    public function navigateConnetToDatabasePage() {
-        $this->open( "http://".HOST_NAME.":".PORT."/".DIRECTORY_NAME."/config/index.php" );
-
-        // 'Welcome to MediaWiki!' page
-        $this->click( "submit-continue" );
-        $this->waitForPageToLoad( PAGE_LOAD_TIME );
-
-        // 'Connect to Database' page
-        $this->click("submit-continue");
-        $this->waitForPageToLoad( PAGE_LOAD_TIME );
-    }
-
-
-    // Navigate to the 'Database Settings' page
-    public function navigateDatabaseSettingsPage( $databaseName ) {
-
-        $this->open( "http://".HOST_NAME.":".PORT."/".DIRECTORY_NAME."/config/index.php" );
-
-        // 'Welcome to MediaWiki!' page
-        $this->click("submit-continue");
-        $this->waitForPageToLoad( PAGE_LOAD_TIME );
-
-        // 'Connect to Database' page
-        $this->click("submit-continue");
-        $this->waitForPageToLoad( PAGE_LOAD_TIME );
-
-        $this->type("mysql_wgDBname", $databaseName );
-        $this->click( "submit-continue" );
-        $this->waitForPageToLoad( PAGE_LOAD_TIME );
-    }
-
-
-    // Navigate to the 'Name' page
-    public function navigateNamePage( $databaseName ) {
-        $this->open( "http://".HOST_NAME.":".PORT."/".DIRECTORY_NAME."/config/index.php" );
-
-        // 'Welcome to MediaWiki!' page
-        $this->click( "submit-continue" );
-        $this->waitForPageToLoad( PAGE_LOAD_TIME );
-
-        // 'Connect to Database' page
-        $this->click( "submit-continue" );
-        $this->waitForPageToLoad( PAGE_LOAD_TIME );
-
-        $this->type( "mysql_wgDBname",  $databaseName );
-        $this->click( "submit-continue" );
-        $this->waitForPageToLoad( PAGE_LOAD_TIME );
-
-        // Database settings
-        $this->click( "submit-continue" );
-        $this->waitForPageToLoad( PAGE_LOAD_TIME );
-    }
-
-
-    // Navigate 'Options' page
-    public function navigateOptionsPage( $databaseName ) {
-
-        $this->open( "http://".HOST_NAME.":".PORT."/".DIRECTORY_NAME."/config/index.php" );
-
-        // 'Welcome to MediaWiki!' page
-        $this->click( "submit-continue" );
-        $this->waitForPageToLoad( PAGE_LOAD_TIME );
-
-        // 'Connect to Database' page
-        $this->click( "submit-continue" );
-        $this->waitForPageToLoad( PAGE_LOAD_TIME );
-
-        $this->type( "mysql_wgDBname",  $databaseName );
-        $this->click( "submit-continue" );
-        $this->waitForPageToLoad( PAGE_LOAD_TIME );
-
-        // Database settings
-        $this->click( "submit-continue" );
-        $this->waitForPageToLoad( PAGE_LOAD_TIME );
-
-        // Name
-        $this->type( "config_wgSitename", NAME_OF_WIKI );
-        $this->type( "config__AdminName", ADMIN_USER_NAME);
-        $this->type( "config__AdminPassword", ADMIN_PASSWORD );
-        $this->type( "config__AdminPassword2", ADMIN_RETYPE_PASSWORD );
-        $this->type( "config__AdminEmail", ADMIN_EMAIL_ADDRESS );
-
-        $this->click( "submit-continue" );
-        $this->waitForPageToLoad( PAGE_LOAD_TIME );
-    }
-
-
-    // Navigate 'Install' page
-    public function navigateInstallPage( $databaseName ) {
-
-        $this->open( "http://".HOST_NAME.":".PORT."/".DIRECTORY_NAME."/config/index.php" );
-
-        // 'Welcome to MediaWiki!' page
-        $this->click( "submit-continue" );
-        $this->waitForPageToLoad( PAGE_LOAD_TIME );
-
-        // 'Connect to Database' page
-        $this->click( "submit-continue" );
-        $this->waitForPageToLoad( PAGE_LOAD_TIME );
-
-        $this->type( "mysql_wgDBname",  $databaseName );
-        $this->click( "submit-continue" );
-        $this->waitForPageToLoad( PAGE_LOAD_TIME );
-
-        // Database settings
-        $this->click( "submit-continue" );
-        $this->waitForPageToLoad( PAGE_LOAD_TIME );
-
-        // Name
-        $this->type( "config_wgSitename", NAME_OF_WIKI );
-        $this->type( "config__AdminName", ADMIN_USER_NAME);
-        $this->type( "config__AdminPassword", ADMIN_PASSWORD );
-        $this->type( "config__AdminPassword2", ADMIN_RETYPE_PASSWORD );
-        $this->type( "config__AdminEmail", ADMIN_EMAIL_ADDRESS );
-
-        $this->click( "submit-continue" );
-        $this->waitForPageToLoad( PAGE_LOAD_TIME );
-
-        // Options page
-        $this->click( "submit-continue" );
-        $this->waitForPageToLoad( PAGE_LOAD_TIME );
-    }
-
-
-    // Navigate to 'Complete' page
-    public function navigateCompletePage( $databaseName ) {
-        $this->open( "http://".HOST_NAME.":".PORT."/".DIRECTORY_NAME."/config/index.php" );
-
-        // 'Welcome to MediaWiki!' page
-        $this->click( "submit-continue" );
-        $this->waitForPageToLoad( PAGE_LOAD_TIME );
-
-        // 'Connect to Database' page
-        $this->click( "submit-continue" );
-        $this->waitForPageToLoad( PAGE_LOAD_TIME );
-
-        $this->type( "mysql_wgDBname",  $databaseName );
-        $this->click( "submit-continue" );
-        $this->waitForPageToLoad( PAGE_LOAD_TIME );
-
-        // Database settings
-        $this->click( "submit-continue" );
-        $this->waitForPageToLoad( PAGE_LOAD_TIME );
-
-        // Name
-        $this->type( "config_wgSitename", NAME_OF_WIKI );
-        $this->type( "config__AdminName", ADMIN_USER_NAME);
-        $this->type( "config__AdminPassword", ADMIN_PASSWORD );
-        $this->type( "config__AdminPassword2", ADMIN_RETYPE_PASSWORD );
-        $this->type( "config__AdminEmail", ADMIN_EMAIL_ADDRESS );
-
-        $this->click( "submit-continue" );
-        $this->waitForPageToLoad( PAGE_LOAD_TIME );
-
-        // Options page
-        $this->click( "submit-continue" );
-        $this->waitForPageToLoad( PAGE_LOAD_TIME );
-
-        // Install page
-        $this->click( "submit-continue" );
-        $this->waitForPageToLoad( PAGE_LOAD_TIME );
-        $this->chooseCancelOnNextConfirmation();
-    }
-
-
-    // Complete the Name page fields
-    public function completeNamePage() {
-        $this->type( "config_wgSitename", NAME_OF_WIKI );
-        $this->type( "config__AdminName", ADMIN_USER_NAME);
-        $this->type( "config__AdminPassword", ADMIN_PASSWORD );
-        $this->type( "config__AdminPassword2", ADMIN_RETYPE_PASSWORD );
-        $this->type( "config__AdminEmail", ADMIN_EMAIL_ADDRESS );
-        $this->click( "submit-continue" );
-        $this->waitForPageToLoad( PAGE_LOAD_TIME);
-    }
-
-
-    // Clicking on the 'Continue' button in any MediaWiki page
-    public function clickContinueButton() {
-        $this->click( "submit-continue" );
-        $this->waitForPageToLoad( PAGE_LOAD_TIME );
-    }
-
-
-    // Clicking on the 'Back' button in any MediaWiki page
-    public function clickBackButton() {
-        $this->click( "submit-back" );
-        $this->waitForPageToLoad( PAGE_LOAD_TIME );
-    }
-
-
-    // Restarting the installation
-    public function restartInstallation() {
-        $this->click( "link=Restart installation" );
-        $this->waitForPageToLoad( PAGE_LOAD_TIME );
-        $this->click( "submit-restart" );
-        $this->waitForPageToLoad( PAGE_LOAD_TIME );
-    }
-
-
-    // Verify 'MediaWiki' logo available in the initial screen
-    public function mediaWikiLogoPresentInitialScreen() {
-        $this->assertTrue( $this->isElementPresent( "//img[@alt='The MediaWiki logo']" ));
-    }
-
-
-    // Verify 'MediaWiki' logo available
-    public function mediaWikiLogoPresent() {
-        $this->assertTrue( $this->isElementPresent( "//div[@id='p-logo']/a" ));
-    }
-
-
-    public function completePageSuccessfull() {
-        $this->assertEquals( "Complete!",
-                $this->getText( "//div[@id='bodyContent']/div/div/h2" ));
-
-        // 'Congratulations!' text should be available in the 'Complete!' page.
-        $this->assertEquals( "Congratulations!",
-                $this->getText( "//div[@id='bodyContent']/div/div/div[2]/form/div[1]/div[2]/p[1]/b" ));
-    }
+       function setUp() {
+               $this->setBrowser( TEST_BROWSER );
+               $this->setBrowserUrl( "http://" . HOST_NAME . ":" . PORT . "/" . DIRECTORY_NAME . "/" );
+       }
+
+       public function navigateInitialpage() {
+               $this->open( "http://" . HOST_NAME . ":" . PORT . "/" . DIRECTORY_NAME . "/" );
+       }
+
+       // Navigate to the 'Language' page
+       public function navigateLanguagePage() {
+               $this->open( "http://" . HOST_NAME . ":" . PORT . "/" . DIRECTORY_NAME . "/config/index.php" );
+       }
+
+       // Navigate to the 'Welcome to MediaWiki' page
+       public function navigateWelcometoMediaWikiPage() {
+               $this->open( "http://" . HOST_NAME . ":" . PORT . "/" . DIRECTORY_NAME . "/config/index.php" );
+               $this->click( "submit-continue " );
+               $this->waitForPageToLoad( PAGE_LOAD_TIME );
+       }
+
+       // Navigate yo 'Connect to Database' page
+       public function navigateConnetToDatabasePage() {
+               $this->open( "http://" . HOST_NAME . ":" . PORT . "/" . DIRECTORY_NAME . "/config/index.php" );
+
+               // 'Welcome to MediaWiki!' page
+               $this->click( "submit-continue" );
+               $this->waitForPageToLoad( PAGE_LOAD_TIME );
+
+               // 'Connect to Database' page
+               $this->click( "submit-continue" );
+               $this->waitForPageToLoad( PAGE_LOAD_TIME );
+       }
+
+       // Navigate to the 'Database Settings' page
+       public function navigateDatabaseSettingsPage( $databaseName ) {
+               $this->open( "http://" . HOST_NAME . ":" . PORT . "/" . DIRECTORY_NAME . "/config/index.php" );
+
+               // 'Welcome to MediaWiki!' page
+               $this->click( "submit-continue" );
+               $this->waitForPageToLoad( PAGE_LOAD_TIME );
+
+               // 'Connect to Database' page
+               $this->click( "submit-continue" );
+               $this->waitForPageToLoad( PAGE_LOAD_TIME );
+
+               $this->type( "mysql_wgDBname", $databaseName );
+               $this->click( "submit-continue" );
+               $this->waitForPageToLoad( PAGE_LOAD_TIME );
+       }
+
+       // Navigate to the 'Name' page
+       public function navigateNamePage( $databaseName ) {
+               $this->open( "http://" . HOST_NAME . ":" . PORT . "/" . DIRECTORY_NAME . "/config/index.php" );
+
+               // 'Welcome to MediaWiki!' page
+               $this->click( "submit-continue" );
+               $this->waitForPageToLoad( PAGE_LOAD_TIME );
+
+               // 'Connect to Database' page
+               $this->click( "submit-continue" );
+               $this->waitForPageToLoad( PAGE_LOAD_TIME );
+
+               $this->type( "mysql_wgDBname", $databaseName );
+               $this->click( "submit-continue" );
+               $this->waitForPageToLoad( PAGE_LOAD_TIME );
+
+               // Database settings
+               $this->click( "submit-continue" );
+               $this->waitForPageToLoad( PAGE_LOAD_TIME );
+       }
+
+       // Navigate 'Options' page
+       public function navigateOptionsPage( $databaseName ) {
+               $this->open( "http://" . HOST_NAME . ":" . PORT . "/" . DIRECTORY_NAME . "/config/index.php" );
+
+               // 'Welcome to MediaWiki!' page
+               $this->click( "submit-continue" );
+               $this->waitForPageToLoad( PAGE_LOAD_TIME );
+
+               // 'Connect to Database' page
+               $this->click( "submit-continue" );
+               $this->waitForPageToLoad( PAGE_LOAD_TIME );
+
+               $this->type( "mysql_wgDBname", $databaseName );
+               $this->click( "submit-continue" );
+               $this->waitForPageToLoad( PAGE_LOAD_TIME );
+
+               // Database settings
+               $this->click( "submit-continue" );
+               $this->waitForPageToLoad( PAGE_LOAD_TIME );
+
+               // Name
+               $this->type( "config_wgSitename", NAME_OF_WIKI );
+               $this->type( "config__AdminName", ADMIN_USER_NAME );
+               $this->type( "config__AdminPassword", ADMIN_PASSWORD );
+               $this->type( "config__AdminPassword2", ADMIN_RETYPE_PASSWORD );
+               $this->type( "config__AdminEmail", ADMIN_EMAIL_ADDRESS );
+
+               $this->click( "submit-continue" );
+               $this->waitForPageToLoad( PAGE_LOAD_TIME );
+       }
+
+       // Navigate 'Install' page
+       public function navigateInstallPage( $databaseName ) {
+               $this->open( "http://" . HOST_NAME . ":" . PORT . "/" . DIRECTORY_NAME . "/config/index.php" );
+
+               // 'Welcome to MediaWiki!' page
+               $this->click( "submit-continue" );
+               $this->waitForPageToLoad( PAGE_LOAD_TIME );
+
+               // 'Connect to Database' page
+               $this->click( "submit-continue" );
+               $this->waitForPageToLoad( PAGE_LOAD_TIME );
+
+               $this->type( "mysql_wgDBname", $databaseName );
+               $this->click( "submit-continue" );
+               $this->waitForPageToLoad( PAGE_LOAD_TIME );
+
+               // Database settings
+               $this->click( "submit-continue" );
+               $this->waitForPageToLoad( PAGE_LOAD_TIME );
+
+               // Name
+               $this->type( "config_wgSitename", NAME_OF_WIKI );
+               $this->type( "config__AdminName", ADMIN_USER_NAME );
+               $this->type( "config__AdminPassword", ADMIN_PASSWORD );
+               $this->type( "config__AdminPassword2", ADMIN_RETYPE_PASSWORD );
+               $this->type( "config__AdminEmail", ADMIN_EMAIL_ADDRESS );
+
+               $this->click( "submit-continue" );
+               $this->waitForPageToLoad( PAGE_LOAD_TIME );
+
+               // Options page
+               $this->click( "submit-continue" );
+               $this->waitForPageToLoad( PAGE_LOAD_TIME );
+       }
+
+       // Navigate to 'Complete' page
+       public function navigateCompletePage( $databaseName ) {
+               $this->open( "http://" . HOST_NAME . ":" . PORT . "/" . DIRECTORY_NAME . "/config/index.php" );
+
+               // 'Welcome to MediaWiki!' page
+               $this->click( "submit-continue" );
+               $this->waitForPageToLoad( PAGE_LOAD_TIME );
+
+               // 'Connect to Database' page
+               $this->click( "submit-continue" );
+               $this->waitForPageToLoad( PAGE_LOAD_TIME );
+
+               $this->type( "mysql_wgDBname", $databaseName );
+               $this->click( "submit-continue" );
+               $this->waitForPageToLoad( PAGE_LOAD_TIME );
+
+               // Database settings
+               $this->click( "submit-continue" );
+               $this->waitForPageToLoad( PAGE_LOAD_TIME );
+
+               // Name
+               $this->type( "config_wgSitename", NAME_OF_WIKI );
+               $this->type( "config__AdminName", ADMIN_USER_NAME );
+               $this->type( "config__AdminPassword", ADMIN_PASSWORD );
+               $this->type( "config__AdminPassword2", ADMIN_RETYPE_PASSWORD );
+               $this->type( "config__AdminEmail", ADMIN_EMAIL_ADDRESS );
+
+               $this->click( "submit-continue" );
+               $this->waitForPageToLoad( PAGE_LOAD_TIME );
+
+               // Options page
+               $this->click( "submit-continue" );
+               $this->waitForPageToLoad( PAGE_LOAD_TIME );
+
+               // Install page
+               $this->click( "submit-continue" );
+               $this->waitForPageToLoad( PAGE_LOAD_TIME );
+               $this->chooseCancelOnNextConfirmation();
+       }
+
+       // Complete the Name page fields
+       public function completeNamePage() {
+               $this->type( "config_wgSitename", NAME_OF_WIKI );
+               $this->type( "config__AdminName", ADMIN_USER_NAME );
+               $this->type( "config__AdminPassword", ADMIN_PASSWORD );
+               $this->type( "config__AdminPassword2", ADMIN_RETYPE_PASSWORD );
+               $this->type( "config__AdminEmail", ADMIN_EMAIL_ADDRESS );
+               $this->click( "submit-continue" );
+               $this->waitForPageToLoad( PAGE_LOAD_TIME );
+       }
+
+       // Clicking on the 'Continue' button in any MediaWiki page
+       public function clickContinueButton() {
+               $this->click( "submit-continue" );
+               $this->waitForPageToLoad( PAGE_LOAD_TIME );
+       }
+
+       // Clicking on the 'Back' button in any MediaWiki page
+       public function clickBackButton() {
+               $this->click( "submit-back" );
+               $this->waitForPageToLoad( PAGE_LOAD_TIME );
+       }
+
+       // Restarting the installation
+       public function restartInstallation() {
+               $this->click( "link=Restart installation" );
+               $this->waitForPageToLoad( PAGE_LOAD_TIME );
+               $this->click( "submit-restart" );
+               $this->waitForPageToLoad( PAGE_LOAD_TIME );
+       }
+
+       // Verify 'MediaWiki' logo available in the initial screen
+       public function mediaWikiLogoPresentInitialScreen() {
+               $this->assertTrue( $this->isElementPresent( "//img[@alt='The MediaWiki logo']" ) );
+       }
+
+       // Verify 'MediaWiki' logo available
+       public function mediaWikiLogoPresent() {
+               $this->assertTrue( $this->isElementPresent( "//div[@id='p-logo']/a" ) );
+       }
+
+       public function completePageSuccessfull() {
+               $this->assertEquals( "Complete!",
+                       $this->getText( "//div[@id='bodyContent']/div/div/h2" ) );
+
+               // 'Congratulations!' text should be available in the 'Complete!' page.
+               $this->assertEquals( "Congratulations!",
+                       $this->getText( "//div[@id='bodyContent']/div/div/div[2]/form/div[1]/div[2]/p[1]/b" ) );
+       }
 }
index d86bcb8..2663f65 100644 (file)
@@ -33,9 +33,9 @@
  * with current value of the 'DB_NAME_PREFIX'.
  * If you wish to run the suite more than one time, you need to change
  * the value of the 'DB_NAME_PREFIX'.
-*/
-define('DB_NAME_PREFIX', "database_name" );
-define('DIRECTORY_NAME', "mediawiki" );
+ */
+define( 'DB_NAME_PREFIX', "database_name" );
+define( 'DIRECTORY_NAME', "mediawiki" );
 define( 'PORT', "8080" );
 define( 'HOST_NAME', "localhost" );
 
@@ -45,5 +45,5 @@ define( 'HOST_NAME', "localhost" );
  *  IE :  *iexplore
  *  Google chrome : *googlechrome
  *  Opera :  *opera
-*/
+ */
 define ( 'TEST_BROWSER', "*firefox" );
index a348b54..f63c2eb 100644 (file)
 // 'MySQL' database type help field hint
 define( 'MYSQL_DATABASE_HOST_HELP', "If your database server is on different server, enter the host name or IP address here. \nIf you are using shared web hosting, your hosting provider should give you the correct host name in their documentation. \nIf you are installing on a Windows server and using MySQL, using \"localhost\" may not work for the server name. If it does not, try \"127.0.0.1\" for the local IP address." );
 define( 'MYSQL_DATABASE_NAME_HELP', "Choose a name that identifies your wiki. It should not contain spaces or hyphens. \nIf you are using shared web hosting, your hosting provider will either give you a specific database name to use or let you create databases via a control panel." );
-define( 'MYSQL_DATABASE_TABLE_PREFIX_HELP', "Choose a name that identifies your wiki. It should not contain spaces or hyphens.");
+define( 'MYSQL_DATABASE_TABLE_PREFIX_HELP', "Choose a name that identifies your wiki. It should not contain spaces or hyphens." );
 define( 'MYSQL_DATBASE_USERNAME_HELP', "Enter the username that will be used to connect to the database during the installation process. This is not the username of the MediaWiki account; this is the username for your database." );
 define( 'MYSQL_DATABASE_PASSWORD_HELP', "Enter the password that will be used to connect to the database during the installation process. This is not the password for the MediaWiki account; this is the password for your database." );
 
 
 // 'SQLite' database type help field hint
 define( 'SQLITE_DATA_DIRECTORY_HELP', "SQLite stores all data in a single file. \nThe directory you provide must be writable by the webserver during installation. \nIt should not be accessible via the web, this is why we're not putting it where your PHP files are. \nThe installer will write a .htaccess file along with it, but if that fails someone can gain access to your raw database. That includes raw user data (e-mail addresses, hashed passwords) as well as deleted revisions and other restricted data on the wiki. \nConsider putting the database somewhere else altogether, for example in /var/lib/mediawiki/yourwiki." );
-define( 'SQLITE_DATABASE_NAME_HELP', "Choose a name that identifies your wiki. Do not use spaces or hyphens. This will be used for the SQLite data file name.");
+define( 'SQLITE_DATABASE_NAME_HELP', "Choose a name that identifies your wiki. Do not use spaces or hyphens. This will be used for the SQLite data file name." );
 
 
 // 'Database settings' page hel0p field hint
@@ -47,7 +47,7 @@ define( 'DATABASE_CHARACTER_SET_HELP', "In binary mode, MediaWiki stores UTF-8 t
 
 
 // 'Name' page help field hint
-define( 'NAME_OF_WIKI_HELP', "This will appear in the title bar of the browser and in various other places.");
+define( 'NAME_OF_WIKI_HELP', "This will appear in the title bar of the browser and in various other places." );
 define( 'PROJECT_NAMESPACE_HELP', "Following Wikipedia's example, many wikis keep their policy pages separate from their content pages, in a \"project namespace\". All page titles in this namespace start with a certain prefix, which you can specify here. Traditionally, this prefix is derived from the name of the wiki, but it cannot contain punctuation characters such as \"#\" or \":\"." );
 define( 'USER_NAME_HELP', "Enter your preferred username here, for example \"Joe Bloggs\". This is the name you will use to log in to the wiki." );
 define( 'EMAIL_ADDRESS_HELP', "Enter an e-mail address here to allow you to receive e-mail from other users on the wiki, reset your password, and be notified of changes to pages on your watchlist." );
index bb11d02..b271c7e 100644 (file)
 
 
 // Common variables
-define('PAGE_LOAD_TIME', "80000" );
+define( 'PAGE_LOAD_TIME', "80000" );
 
 // Common links
-define( 'LINK_DIV', "//div[@id='bodyContent']/div/div/");
+define( 'LINK_DIV', "//div[@id='bodyContent']/div/div/" );
 define( 'LINK_FORM', "//div[@id='bodyContent']/div/div/div[2]/form/" );
-define( 'LINK_RIGHT_FRAMEWORK', "//div[@id='bodyContent']/div/div/div[1]/ul[1]/");
+define( 'LINK_RIGHT_FRAMEWORK', "//div[@id='bodyContent']/div/div/div[1]/ul[1]/" );
 
 // 'Name' page input values
 define( 'NAME_OF_WIKI', "Site Name" );
@@ -48,30 +48,30 @@ define ( 'ADMIN_EMAIL_ADDRESS', "admin@example.com" );
 define( 'VALID_WIKI_NAME', "MyWiki" );
 define( 'VALID_YOUR_NAME', "FirstName LastName" );
 define( 'VALID_PASSWORD', "12345" );
-define( 'VALID_PASSWORD_AGAIN', "12345"  );
+define( 'VALID_PASSWORD_AGAIN', "12345" );
 define( 'INVALID_PASSWORD_AGAIN', "123" );
-define( 'VALID_NAMESPACE', "Mynamespace"  );
+define( 'VALID_NAMESPACE', "Mynamespace" );
 define( 'INVALID_NAMESPACE', "##..##" );
 
 
 // 'Database settings' page input values
 define( 'DB_WEB_USER', "different" );
-define('DB_WEB_USER_PASSWORD', "12345" );
+define( 'DB_WEB_USER_PASSWORD', "12345" );
 
 
 // 'Connet to database' page input values
-define( 'DATABASE_PREFIX',"databaseprefix" );
+define( 'DATABASE_PREFIX', "databaseprefix" );
 
 
 // 'Connet to database' page input values for warning messages
 define( 'VALID_DB_HOST', "localhost" );
 define( 'INVALID_DB_HOST', "local" );
 define( 'INVALID_DB_NAME', "my-wiki" );
-define( 'VALID_DB_NAME', "my_wiki1");
+define( 'VALID_DB_NAME', "my_wiki1" );
 define( 'INVALID_DB_PREFIX', "database prefix" );
-define( 'VALID_DB_PREFIX', "database_prefix");
+define( 'VALID_DB_PREFIX', "database_prefix" );
 define( 'INVALID_DB_USER_NAME', "roots" );
-define( 'VALID_DB_USER_NAME', "root");
+define( 'VALID_DB_USER_NAME', "root" );
 define( 'INVALID_DB_PASSWORD', "12345" );
 
 
index 58ccc7c..03ffbfd 100644 (file)
@@ -44,10 +44,7 @@ require_once ( __DIR__ . '/MediaWikiDifferntDatabasePrefixTestCase.php' );
 require_once ( __DIR__ . '/MediaWikiDifferentDatabaseAccountTestCase.php' );
 require_once ( __DIR__ . '/MediaWikiOnAlreadyInstalledTestCase.php' );
 
-
-
-
-$suite = new PHPUnit_Framework_TestSuite('ArrayTest');
+$suite = new PHPUnit_Framework_TestSuite( 'ArrayTest' );
 $result = new PHPUnit_Framework_TestResult;
 
-$suite->run($result);
+$suite->run( $result );
index 16d065c..d631ed8 100644 (file)
  *
  */
 
-
-require_once (__DIR__.'/'.'MediaWikiInstallationCommonFunction.php');
+require_once ( __DIR__ . '/' . 'MediaWikiInstallationCommonFunction.php' );
 
 /**
  * Test Case ID   : 01 (http://www.mediawiki.org/wiki/New_installer/Test_plan)
  * Test Case Name : Install Mediawiki using 'MySQL' database type successfully
  * Version        : MediaWiki 1.18alpha
-*/
+ */
 
 class MediaWikiMySQLDataBaseTestCase extends MediaWikiInstallationCommonFunction {
+       function setUp() {
+               parent::setUp();
+       }
 
-    function setUp() {
-        parent::setUp();
-    }
-
-    // Verify  MediaWiki installation using 'MySQL' database type
-    public function testMySQLDatabaseSuccess() {
-
-        $databaseName = DB_NAME_PREFIX."_sql_db";
+       // Verify  MediaWiki installation using 'MySQL' database type
+       public function testMySQLDatabaseSuccess() {
+               $databaseName = DB_NAME_PREFIX . "_sql_db";
 
-        parent::navigateConnetToDatabasePage();
+               parent::navigateConnetToDatabasePage();
 
-        // Verify 'MySQL" is selected as the default database type
-        $this->assertEquals( "MySQL settings", $this->getText( "//div[@id='DB_wrapper_mysql']/h3" ));
+               // Verify 'MySQL" is selected as the default database type
+               $this->assertEquals( "MySQL settings", $this->getText( "//div[@id='DB_wrapper_mysql']/h3" ) );
 
-        // Change 'Database name'
-        $defaultDbName = $this->getText( "mysql_wgDBname" );
-        $this->type( "mysql_wgDBname", " ");
-        $this->type( "mysql_wgDBname", $databaseName );
-        $this->assertNotEquals( $defaultDbName, $databaseName );
+               // Change 'Database name'
+               $defaultDbName = $this->getText( "mysql_wgDBname" );
+               $this->type( "mysql_wgDBname", " " );
+               $this->type( "mysql_wgDBname", $databaseName );
+               $this->assertNotEquals( $defaultDbName, $databaseName );
 
-        // 'Database settings' page
-        parent::clickContinueButton();
+               // 'Database settings' page
+               parent::clickContinueButton();
 
-        // 'Name' page
-        parent::clickContinueButton();
-        parent::completeNamePage();
+               // 'Name' page
+               parent::clickContinueButton();
+               parent::completeNamePage();
 
-        // 'Options page
-        parent::clickContinueButton();
+               // 'Options page
+               parent::clickContinueButton();
 
-        // 'Install' page
-        parent::clickContinueButton();
+               // 'Install' page
+               parent::clickContinueButton();
 
-        // 'Complete' page
-        parent::completePageSuccessfull();
-        parent::restartInstallation();
-    }
+               // 'Complete' page
+               parent::completePageSuccessfull();
+               parent::restartInstallation();
+       }
 }
index 4ca6916..19c05da 100644 (file)
  */
 
 
-require_once (__DIR__.'/'.'MediaWikiInstallationCommonFunction.php');
+require_once ( __DIR__ . '/' . 'MediaWikiInstallationCommonFunction.php' );
 
 /**
  * Test Case ID   : 06 (http://www.mediawiki.org/wiki/New_installer/Test_plan)
  * Test Case Name : Install Mediawiki using 'MySQL' database type successfully
  * Version        : MediaWiki 1.18alpha
-*/
+ */
 
 class MediaWikiMySQLiteDataBaseTestCase extends MediaWikiInstallationCommonFunction {
+       function setUp() {
+               parent::setUp();
+       }
 
-    function setUp() {
-        parent::setUp();
-    }
-
-    // Verify  MediaWiki installation using 'MySQL' database type
-    public function testMySQLDatabaseSuccess() {
-
-        $databaseName = DB_NAME_PREFIX."_sqlite_db";
+       // Verify  MediaWiki installation using 'MySQL' database type
+       public function testMySQLDatabaseSuccess() {
+               $databaseName = DB_NAME_PREFIX . "_sqlite_db";
 
-        parent::navigateConnetToDatabasePage();
-        $this->click( "DBType_sqlite" );
+               parent::navigateConnetToDatabasePage();
+               $this->click( "DBType_sqlite" );
 
-        // Select 'SQLite' database type
-        $this->assertEquals( "SQLite settings", $this->getText( "//div[@id='DB_wrapper_sqlite']/h3" ));
+               // Select 'SQLite' database type
+               $this->assertEquals( "SQLite settings", $this->getText( "//div[@id='DB_wrapper_sqlite']/h3" ) );
 
-        // Change database name
-        $defaultDbName = $this->getText( "sqlite_wgDBname" );
-        $this->type( "sqlite_wgDBname", " ");
-        $this->type( "sqlite_wgDBname", $databaseName );
-        $this->assertNotEquals( $defaultDbName, $databaseName );
+               // Change database name
+               $defaultDbName = $this->getText( "sqlite_wgDBname" );
+               $this->type( "sqlite_wgDBname", " " );
+               $this->type( "sqlite_wgDBname", $databaseName );
+               $this->assertNotEquals( $defaultDbName, $databaseName );
 
-        // 'Database settings' page
-        parent::clickContinueButton();
+               // 'Database settings' page
+               parent::clickContinueButton();
 
-        // 'Name' page
-        parent::clickContinueButton();
-        parent::completeNamePage();
+               // 'Name' page
+               parent::clickContinueButton();
+               parent::completeNamePage();
 
-        // 'Options page
-        parent::clickContinueButton();
+               // 'Options page
+               parent::clickContinueButton();
 
-        // 'Install' page
-        parent::clickContinueButton();
+               // 'Install' page
+               parent::clickContinueButton();
 
-        // 'Complete' page
-        parent::completePageSuccessfull();
-        parent::restartInstallation();
-    }
+               // 'Complete' page
+               parent::completePageSuccessfull();
+               parent::restartInstallation();
+       }
 }
index 7a1b615..21c4578 100644 (file)
  */
 
 
-require_once (__DIR__.'/'.'MediaWikiInstallationCommonFunction.php');
+require_once ( __DIR__ . '/' . 'MediaWikiInstallationCommonFunction.php' );
 
 
 /**
  * Test Case ID   : 03 (http://www.mediawiki.org/wiki/New_installer/Test_plan)
  * Test Case Name : Install mediawiki on a already installed Mediawiki.]
  * Version        : MediaWiki 1.18alpha
-*/
+ */
 
 class MediaWikiOnAlreadyInstalledTestCase extends MediaWikiInstallationCommonFunction {
+       function setUp() {
+               parent::setUp();
+       }
 
-    function setUp() {
-        parent::setUp();
-    }
-
-    // Install Mediawiki using 'MySQL' database type.
-    public function testInstallOnAlreadyInstalled() {
-
-        $databaseName = DB_NAME_PREFIX."_already_installed";
-        parent::navigateInstallPage( $databaseName );
+       // Install Mediawiki using 'MySQL' database type.
+       public function testInstallOnAlreadyInstalled() {
+               $databaseName = DB_NAME_PREFIX . "_already_installed";
+               parent::navigateInstallPage( $databaseName );
 
-        // 'Options' page
-        parent::clickBackButton();
+               // 'Options' page
+               parent::clickBackButton();
 
-        // Install page
-        parent::clickContinueButton();
+               // Install page
+               parent::clickContinueButton();
 
-        // 'Install' page should display after the 'Option' page
-        $this->assertEquals( "Install", $this->getText( LINK_DIV."h2" ));
+               // 'Install' page should display after the 'Option' page
+               $this->assertEquals( "Install", $this->getText( LINK_DIV . "h2" ) );
 
-        // Verify warning text displayed
-        $this->assertEquals( "Warning: You seem to have already installed MediaWiki and are trying to install it again. Please proceed to the next page.",
-                $this->getText( LINK_FORM."div[1]/div[2]" ));
+               // Verify warning text displayed
+               $this->assertEquals( "Warning: You seem to have already installed MediaWiki and are trying to install it again. Please proceed to the next page.",
+                       $this->getText( LINK_FORM . "div[1]/div[2]" ) );
 
-        // Complete page
-        parent::clickContinueButton();
-        parent::completePageSuccessfull();
-        $this->chooseCancelOnNextConfirmation();
-        parent::restartInstallation();
-    }
+               // Complete page
+               parent::clickContinueButton();
+               parent::completePageSuccessfull();
+               $this->chooseCancelOnNextConfirmation();
+               parent::restartInstallation();
+       }
 }
index ea87de0..2acb4df 100644 (file)
  */
 
 
-
-require_once (__DIR__.'/'.'MediaWikiInstallationCommonFunction.php');
+require_once ( __DIR__ . '/' . 'MediaWikiInstallationCommonFunction.php' );
 
 /**
  * Test Case ID   : 11, 12 (http://www.mediawiki.org/wiki/New_installer/Test_plan)
  * Test Case Name : Install mediawiki on a already installed Mediawiki.
  * Version        : MediaWiki 1.18alpha
-*/
+ */
 
 class MediaWikiRestartInstallationTestCase extends MediaWikiInstallationCommonFunction {
+       function setUp() {
+               parent::setUp();
+       }
 
-    function setUp() {
-        parent::setUp();
-    }
-
-    // Verify restarting the installation
-    public function testSuccessRestartInstallation() {
-
-        $dbNameBeforeRestart  = DB_NAME_PREFIX."_db_before";
-        parent::navigateDatabaseSettingsPage( $dbNameBeforeRestart );
-
-        // Verify 'Restart installation' link available
-        $this->assertTrue($this->isElementPresent( "link=Restart installation" ));
-
-        // Click 'Restart installation'
-        $this->click( "link=Restart installation ");
-        $this->waitForPageToLoad( PAGE_LOAD_TIME );
+       // Verify restarting the installation
+       public function testSuccessRestartInstallation() {
+               $dbNameBeforeRestart = DB_NAME_PREFIX . "_db_before";
+               parent::navigateDatabaseSettingsPage( $dbNameBeforeRestart );
 
-        // 'Restart Installation' page displayed
-        $this->assertEquals( "Restart installation", $this->getText( LINK_DIV."h2"));
+               // Verify 'Restart installation' link available
+               $this->assertTrue( $this->isElementPresent( "link=Restart installation" ) );
 
-        // Restart warning message displayed
-        $this->assertTrue($this->isTextPresent( "exact:Do you want to clear all saved data that you have entered and restart the installation process?" ));
+               // Click 'Restart installation'
+               $this->click( "link=Restart installation " );
+               $this->waitForPageToLoad( PAGE_LOAD_TIME );
 
-        // Click on the 'Yes, restart' button
-        $this->click( "submit-restart" );
-        $this->waitForPageToLoad( PAGE_LOAD_TIME );
+               // 'Restart Installation' page displayed
+               $this->assertEquals( "Restart installation", $this->getText( LINK_DIV . "h2" ) );
 
-        // Navigate to the initial installation page(Language).
-        $this->assertEquals(  "Language", $this->getText( LINK_DIV."h2" ));
+               // Restart warning message displayed
+               $this->assertTrue( $this->isTextPresent( "exact:Do you want to clear all saved data that you have entered and restart the installation process?" ) );
 
-        // 'Welcome to MediaWiki!' page
-        parent::clickContinueButton();
+               // Click on the 'Yes, restart' button
+               $this->click( "submit-restart" );
+               $this->waitForPageToLoad( PAGE_LOAD_TIME );
 
-        // 'Connect to database' page
-        parent::clickContinueButton();
+               // Navigate to the initial installation page(Language).
+               $this->assertEquals( "Language", $this->getText( LINK_DIV . "h2" ) );
 
-        // saved data should be deleted
-        $dbNameAfterRestart = $this->getValue("mysql_wgDBname");
-        $this->assertNotEquals($dbNameBeforeRestart, $dbNameAfterRestart);
-    }
+               // 'Welcome to MediaWiki!' page
+               parent::clickContinueButton();
 
+               // 'Connect to database' page
+               parent::clickContinueButton();
 
-    // Verify cancelling restart
-    public function testCancelRestartInstallation() {
+               // saved data should be deleted
+               $dbNameAfterRestart = $this->getValue( "mysql_wgDBname" );
+               $this->assertNotEquals( $dbNameBeforeRestart, $dbNameAfterRestart );
+       }
 
-        $dbNameBeforeRestart  = DB_NAME_PREFIX."_cancel_restart";
+       // Verify cancelling restart
+       public function testCancelRestartInstallation() {
+               $dbNameBeforeRestart = DB_NAME_PREFIX . "_cancel_restart";
 
-        parent::navigateDatabaseSettingsPage( $dbNameBeforeRestart);
-        // Verify 'Restart installation' link available
-        $this->assertTrue($this->isElementPresent( "link=Restart installation" ));
+               parent::navigateDatabaseSettingsPage( $dbNameBeforeRestart );
+               // Verify 'Restart installation' link available
+               $this->assertTrue( $this->isElementPresent( "link=Restart installation" ) );
 
-        $this->click( "link=Restart installation" );
-        $this->waitForPageToLoad( PAGE_LOAD_TIME );
+               $this->click( "link=Restart installation" );
+               $this->waitForPageToLoad( PAGE_LOAD_TIME );
 
-        // 'Restart Installation' page displayed
-        $this->assertEquals( "Restart installation", $this->getText( LINK_DIV."h2" ));
+               // 'Restart Installation' page displayed
+               $this->assertEquals( "Restart installation", $this->getText( LINK_DIV . "h2" ) );
 
-        // Restart warning message displayed
-        $this->assertTrue( $this->isTextPresent( "Do you want to clear all saved data that you have entered and restart the installation process?"));
+               // Restart warning message displayed
+               $this->assertTrue( $this->isTextPresent( "Do you want to clear all saved data that you have entered and restart the installation process?" ) );
 
-        // Click on the 'Back' button
-        parent::clickBackButton();
+               // Click on the 'Back' button
+               parent::clickBackButton();
 
-        // Navigates to the previous page
-        $this->assertEquals( "Database settings", $this->getText( LINK_DIV."h2" ));
+               // Navigates to the previous page
+               $this->assertEquals( "Database settings", $this->getText( LINK_DIV . "h2" ) );
 
-        // 'Connect to database' page
-        parent::clickBackButton();
+               // 'Connect to database' page
+               parent::clickBackButton();
 
-        // Saved data remain on the page.
-        $dbNameAfterRestart = $this->getValue( "mysql_wgDBname" );
-        $this->assertEquals( $dbNameBeforeRestart, $dbNameAfterRestart );
-    }
+               // Saved data remain on the page.
+               $dbNameAfterRestart = $this->getValue( "mysql_wgDBname" );
+               $this->assertEquals( $dbNameBeforeRestart, $dbNameAfterRestart );
+       }
 }
index 7b0fcf3..63491c7 100644 (file)
@@ -27,8 +27,7 @@
  *
  */
 
-
-require_once (__DIR__.'/'.'MediaWikiInstallationCommonFunction.php');
+require_once ( __DIR__ . '/' . 'MediaWikiInstallationCommonFunction.php' );
 
 /**
  * Test Case ID   : 14, 15, 16, 17 (http://www.mediawiki.org/wiki/New_installer/Test_plan)
@@ -37,57 +36,53 @@ require_once (__DIR__.'/'.'MediaWikiInstallationCommonFunction.php');
  *                  User selects 'Copying' link.
  *                  User selects 'Upgrading' link.
  * Version        : MediaWiki 1.18alpha
-*/
-
+ */
 
 class MediaWikiRightFrameworkLinksTestCase extends MediaWikiInstallationCommonFunction {
-
-    function setUp() {
-        parent::setUp();
-    }
-
-    public function testLinksAvailability() {
-
-        $this->open( "http://".HOST_NAME.":".PORT."/".DIRECTORY_NAME."/config/index.php" );
-
-        // Verify 'Read me' link availability
-        $this->assertTrue($this->isElementPresent( "link=Read me" ));
-
-        // Verify 'Release notes' link availability
-        $this->assertTrue($this->isElementPresent( "link=Release notes" ));
-
-        //  Verify 'Copying' link availability
-        $this->assertTrue($this->isElementPresent( "link=Copying" ));
-    }
-
-    public function testPageNavigation() {
-
-        $this->open( "http://".HOST_NAME.":".PORT."/".DIRECTORY_NAME."/config/index.php" );
-
-        // Navigate to the 'Read me' page
-        $this->click( "link=Read me" );
-        $this->waitForPageToLoad( PAGE_LOAD_TIME );
-        $this->assertEquals( "Read me", $this->getText( LINK_DIV."h2[1]" ));
-        $this->assertTrue($this->isElementPresent( "submit-back" ));
-        parent::clickBackButton();
-
-        // Navigate to the 'Release notes' page
-        $this->click( "link=Release notes" );
-        $this->waitForPageToLoad( PAGE_LOAD_TIME);
-        $this->assertEquals( "Release notes", $this->getText( LINK_DIV."h2[1]" ));
-        $this->assertTrue( $this->isElementPresent( "submit-back" ));
-        parent::clickBackButton();
-
-        // Navigate to the 'Copying' page
-        $this->click( "link=Copying" );
-        $this->waitForPageToLoad( PAGE_LOAD_TIME );
-        $this->assertEquals( "Copying", $this->getText( LINK_DIV."h2[1]" ));
-        $this->assertTrue($this->isElementPresent( "submit-back" ));
-        parent::clickBackButton();
-
-        // Navigate to the 'Upgrading' page
-        $this->click( "link=Upgrading" );
-        $this->waitForPageToLoad( PAGE_LOAD_TIME );
-        $this->assertEquals( "Upgrading", $this->getText( LINK_DIV."h2[1]" ));
-    }
+       function setUp() {
+               parent::setUp();
+       }
+
+       public function testLinksAvailability() {
+               $this->open( "http://" . HOST_NAME . ":" . PORT . "/" . DIRECTORY_NAME . "/config/index.php" );
+
+               // Verify 'Read me' link availability
+               $this->assertTrue( $this->isElementPresent( "link=Read me" ) );
+
+               // Verify 'Release notes' link availability
+               $this->assertTrue( $this->isElementPresent( "link=Release notes" ) );
+
+               //  Verify 'Copying' link availability
+               $this->assertTrue( $this->isElementPresent( "link=Copying" ) );
+       }
+
+       public function testPageNavigation() {
+               $this->open( "http://" . HOST_NAME . ":" . PORT . "/" . DIRECTORY_NAME . "/config/index.php" );
+
+               // Navigate to the 'Read me' page
+               $this->click( "link=Read me" );
+               $this->waitForPageToLoad( PAGE_LOAD_TIME );
+               $this->assertEquals( "Read me", $this->getText( LINK_DIV . "h2[1]" ) );
+               $this->assertTrue( $this->isElementPresent( "submit-back" ) );
+               parent::clickBackButton();
+
+               // Navigate to the 'Release notes' page
+               $this->click( "link=Release notes" );
+               $this->waitForPageToLoad( PAGE_LOAD_TIME );
+               $this->assertEquals( "Release notes", $this->getText( LINK_DIV . "h2[1]" ) );
+               $this->assertTrue( $this->isElementPresent( "submit-back" ) );
+               parent::clickBackButton();
+
+               // Navigate to the 'Copying' page
+               $this->click( "link=Copying" );
+               $this->waitForPageToLoad( PAGE_LOAD_TIME );
+               $this->assertEquals( "Copying", $this->getText( LINK_DIV . "h2[1]" ) );
+               $this->assertTrue( $this->isElementPresent( "submit-back" ) );
+               parent::clickBackButton();
+
+               // Navigate to the 'Upgrading' page
+               $this->click( "link=Upgrading" );
+               $this->waitForPageToLoad( PAGE_LOAD_TIME );
+               $this->assertEquals( "Upgrading", $this->getText( LINK_DIV . "h2[1]" ) );
+       }
 }
index 5cdc8d4..c20fafe 100644 (file)
  */
 
 
-require_once (__DIR__.'/'.'MediaWikiInstallationCommonFunction.php');
+require_once ( __DIR__ . '/' . 'MediaWikiInstallationCommonFunction.php' );
 
 /**
  * Test Case ID   : 05 (http://www.mediawiki.org/wiki/New_installer/Test_plan)
  * Test Case Name : Install Mediawiki by updating the existing database.
  * Version        : MediaWiki 1.18alpha
-*/
-
+ */
 
 class MediaWikiUpgradeExistingDatabaseTestCase extends MediaWikiInstallationCommonFunction {
-    
-    function setUp() {
-        parent::setUp();
-    }
-    
-    // Install Mediawiki using 'MySQL' database type.
-    public function testUpgradeExistingDatabase() {
-        
-        $databaseName = DB_NAME_PREFIX."_upgrade_existing";
-        parent::navigateInstallPage( $databaseName );
-        
-        $this->open( "http://localhost:".PORT."/".DIRECTORY_NAME."/config/index.php" );
-        $this->assertEquals( "Install", $this->getText( LINK_DIV."h2" ));
-        $this->assertEquals( "Warning: You seem to have already installed MediaWiki and are trying to install it again. Please proceed to the next page.",
-                $this->getText( LINK_DIV."div[2]/form/div[1]/div[2]" ));
-        
-        // 'Optionis' page
-        parent::clickBackButton();
-        
-        // 'Name' page
-        parent::clickBackButton();
-        
-        // 'Database settings' page
-        parent::clickBackButton();
-        
-        // 'Connect to database' page
-        parent::clickBackButton();
-        $this->type( "mysql_wgDBname", $databaseName );
-        parent::clickContinueButton();
-        
-        // 'Upgrade existing installation' page  displayed next to the 'Connect to database' page.
-        $this->assertEquals( "Upgrade existing installation", $this->getText( LINK_DIV."h2" ));
-        
-        // Warning message displayed.
-        $this->assertEquals( "There are MediaWiki tables in this database. To upgrade them to MediaWiki 1.18alpha, click Continue.",
-                $this->getText( LINK_DIV."div[2]/form/div[1]/div[2]" ));
-        
-        parent::clickContinueButton();
-        $this->assertEquals( "Upgrade existing installation",
-                $this->getText( LINK_DIV."h2" ));
-        
-        // 'Upgrade complete.' text display
-        $this->assertEquals("Upgrade complete.",
-                $this->getText("//div[@id='bodyContent']/div/div[1]/div[4]/form/div[1]/div[2]/p[1]"));
-        
-        $this->assertEquals("You can now Folder/index.php start using your wiki.",
-                $this->getText("//div[@id='bodyContent']/div/div[1]/div[4]/form/div[1]/div[2]/p[2]" ));
-        
-        $this->assertEquals( "Folder/index.php start using your wiki",
-                $this->getText( "link=Folder/index.php start using your wiki" ));
-        
-        $this->assertTrue($this->isElementPresent( "submit-regenerate" ));
-        $this->click( "submit-regenerate" );
-        $this->waitForPageToLoad( PAGE_LOAD_TIME );
-        $this->assertEquals( "Database settings",
-                $this->getText( LINK_DIV."h2" ));
-        
-        // 'Database settings' page
-        parent::clickContinueButton();
-        
-        // Name page
-        parent::completeNamePage();
-        
-        // Options page
-        parent::clickContinueButton();
-        
-        // Install page
-        $this->assertEquals( "Warning: You seem to have already installed MediaWiki and are trying to install it again. Please proceed to the next page.",
-                $this->getText( LINK_FORM."div[1]/div[2]" ));
-        parent::clickContinueButton();
-        
-        // complete
-        parent::completePageSuccessfull();
-        $this->chooseCancelOnNextConfirmation();
-        parent::restartInstallation();
-    }
+       function setUp() {
+               parent::setUp();
+       }
+
+       // Install Mediawiki using 'MySQL' database type.
+       public function testUpgradeExistingDatabase() {
+
+               $databaseName = DB_NAME_PREFIX . "_upgrade_existing";
+               parent::navigateInstallPage( $databaseName );
+
+               $this->open( "http://localhost:" . PORT . "/" . DIRECTORY_NAME . "/config/index.php" );
+               $this->assertEquals( "Install", $this->getText( LINK_DIV . "h2" ) );
+               $this->assertEquals(
+                       "Warning: You seem to have already installed MediaWiki and are trying to install it again. Please proceed to the next page.",
+                       $this->getText( LINK_DIV . "div[2]/form/div[1]/div[2]" )
+               );
+
+               // 'Optionis' page
+               parent::clickBackButton();
+
+               // 'Name' page
+               parent::clickBackButton();
+
+               // 'Database settings' page
+               parent::clickBackButton();
+
+               // 'Connect to database' page
+               parent::clickBackButton();
+               $this->type( "mysql_wgDBname", $databaseName );
+               parent::clickContinueButton();
+
+               // 'Upgrade existing installation' page  displayed next to the 'Connect to database' page.
+               $this->assertEquals( "Upgrade existing installation", $this->getText( LINK_DIV . "h2" ) );
+
+               // Warning message displayed.
+               $this->assertEquals( "There are MediaWiki tables in this database. To upgrade them to MediaWiki 1.18alpha, click Continue.",
+                       $this->getText( LINK_DIV . "div[2]/form/div[1]/div[2]" ) );
+
+               parent::clickContinueButton();
+               $this->assertEquals( "Upgrade existing installation",
+                       $this->getText( LINK_DIV . "h2" ) );
+
+               // 'Upgrade complete.' text display
+               $this->assertEquals( "Upgrade complete.",
+                       $this->getText( "//div[@id='bodyContent']/div/div[1]/div[4]/form/div[1]/div[2]/p[1]" ) );
+
+               $this->assertEquals( "You can now Folder/index.php start using your wiki.",
+                       $this->getText( "//div[@id='bodyContent']/div/div[1]/div[4]/form/div[1]/div[2]/p[2]" ) );
+
+               $this->assertEquals( "Folder/index.php start using your wiki",
+                       $this->getText( "link=Folder/index.php start using your wiki" ) );
+
+               $this->assertTrue( $this->isElementPresent( "submit-regenerate" ) );
+               $this->click( "submit-regenerate" );
+               $this->waitForPageToLoad( PAGE_LOAD_TIME );
+               $this->assertEquals( "Database settings",
+                       $this->getText( LINK_DIV . "h2" ) );
+
+               // 'Database settings' page
+               parent::clickContinueButton();
+
+               // Name page
+               parent::completeNamePage();
+
+               // Options page
+               parent::clickContinueButton();
+
+               // Install page
+               $this->assertEquals( "Warning: You seem to have already installed MediaWiki and are trying to install it again. Please proceed to the next page.",
+                       $this->getText( LINK_FORM . "div[1]/div[2]" ) );
+               parent::clickContinueButton();
+
+               // complete
+               parent::completePageSuccessfull();
+               $this->chooseCancelOnNextConfirmation();
+               parent::restartInstallation();
+       }
 }
index 15fad95..c73effc 100644 (file)
  *
  */
 
-require_once (__DIR__.'/'.'MediaWikiInstallationCommonFunction.php');
+require_once ( __DIR__ . '/' . 'MediaWikiInstallationCommonFunction.php' );
 
 /**
  * Test Case ID   : 18 - 27 (http://www.mediawiki.org/wiki/New_installer/Test_plan)
  * Test Case Name : UI of MediaWiki initial/ Language/ Welcome to MediaWiki!/ Connect to database/
  * Database settings/ Name/ Options/ Install/ Complete/ Restart Inslation pages
  * Version        : MediaWiki 1.18alpha
-*/
+ */
 
 
 class MediaWikiUserInterfaceTestCase extends MediaWikiInstallationCommonFunction {
-    
-    function setUp() {
-        parent::setUp();
-    }
-    
-    
-    public function testInitialPageUI() {
-        
-        parent::navigateInitialpage();
-        
-        // MediaWiki logo available
-        $this->assertTrue( $this->isElementPresent( "//img[@alt='The MediaWiki logo']" ));
-        
-        // 'MediaWiki 1.18alpha' text available
-        $this->assertEquals( "MediaWiki 1.18alpha", $this->getText( "//h1" ));
-        
-        // 'LocalSettings.php not found.' text available
-        $this->assertEquals( "LocalSettings.php not found.", $this->getText( "//p[1]" ));
-        
-        // 'Please set up the wiki first' text available
-        $this->assertEquals( "Please set up the wiki first.", $this->getText( "//p[2]" ));
-        
-        // 'set up the wiki' link available
-        $this->assertTrue($this->isElementPresent( "link=set up the wiki" ));
-    }
-    
-    
-    public function testlanguagePageUI() {
-        
-        parent::navigateLanguagePage();
-        
-        // Verify 'Language' heading
-        $this->assertEquals( "Language", $this->getText( LINK_DIV."h2" ));
-        
-        // 'Your language' label available
-        $this->assertEquals( "Your language:",
-                $this->getText( LINK_FORM."div[1]/div[1]/label" ));
-        
-        // 'Your language' dropdown available
-        $this->assertTrue( $this->isElementPresent( "UserLang" ));
-        
-        // 'Wiki language' label available
-        $this->assertEquals( "Wiki language:",
-                $this->getText( LINK_FORM."div[2]/div[1]/label" ));
-        
-        // 'Wiki language' dropdown available
-        $this->assertTrue($this->isElementPresent( "ContLang" ));
-    }
-    
-    
-    public function testWelcometoMediaWikiUI() {
-        
-        parent::navigateWelcometoMediaWikiPage();
-        
-        // Verify 'Welcome to MediaWiki!' heading
-        $this->assertEquals( "Welcome to MediaWiki!",
-                $this->getText( LINK_DIV."h2" ));
-        
-        // Verify environment ok text displayed.
-        $this->assertEquals( "The environment has been checked.You can install MediaWiki.",
-                $this->getText( LINK_DIV."div[6]/span" ));
-    }
-    
-    
-    public function testConnectToDatabaseUI() {
-        
-        parent::navigateConnetToDatabasePage();
-        
-        //  'MYSQL radio button available
-        $this->assertEquals( "MySQL",
-                $this->getText( LINK_FORM."div[2]/div[2]/ul/li[1]/label" ));
-        $this->assertTrue( $this->isElementPresent( LINK_FORM."div[2]/div[2]/ul/li[1]" ));
-        
-        // 'SQLite' radio button available
-        $this->assertTrue( $this->isElementPresent( LINK_FORM."div[2]/div[2]/ul/li[2]" ));
-        $this->assertEquals( "SQLite", $this->getText( LINK_FORM."div[2]/div[2]/ul/li[2]/label "));
-        
-        // 'Database host' label available
-        $this->assertEquals( "Database host:", $this->getText( "//div[@id='DB_wrapper_mysql']/div/div[1]/label" ));
-        
-        // 'Database host' text box default to 'localhost'
-        $this->assertEquals( "localhost", $this->getValue( "mysql_wgDBserver" ));
-        
-        // 'Identify this wiki' section available
-        $this->assertTrue( $this->isElementPresent( "//div[@id='DB_wrapper_mysql']/fieldset[1]/legend" ));
-        
-        // 'Identify this wiki' label available
-        $this->assertEquals( "Identify this wiki", $this->getText( "//div[@id='DB_wrapper_mysql']/fieldset[1]/legend" ));
-        
-        // 'Database name' lable available
-        $this->assertEquals( "Database name:",
-                $this->getText( "//div[@id='DB_wrapper_mysql']/fieldset[1]/div[1]/div[1]/label" ));
-        
-        // Verify 'Database name:' text box is default to 'my_wiki'
-        $this->assertEquals( "my_wiki", $this->getValue( "mysql_wgDBname" ));
-        
-        // Verify 'Database table prefix:' label available
-        $this->assertEquals( "Database table prefix:",
-                $this->getText( "//div[@id='DB_wrapper_mysql']/fieldset[1]/div[2]/div[1]/label" ));
-        
-        // 'User account for installation' section available
-        $this->assertTrue( $this->isElementPresent( "//div[@id='DB_wrapper_mysql']/fieldset[2]/legend" ));
-        
-        // 'User account for installation' label available
-        $this->assertEquals( "User account for installation", $this->getText( "//div[@id='DB_wrapper_mysql']/fieldset[2]/legend" ));
-        
-        // 'Database username' label available
-        $this->assertEquals( "Database username:",
-                $this->getText( "//div[@id='DB_wrapper_mysql']/fieldset[2]/div[1]/div[1]/label" ));
-        
-        // 'Database username' text box defaults to 'root'
-        $this->assertEquals("root", $this->getValue( "mysql__InstallUser" ));
-        
-        // 'Database password' label available
-        $this->assertEquals( "Database password:",
-                $this->getText( "//div[@id='DB_wrapper_mysql']/fieldset[2]/div[2]/div[1]/label" ));
-    }
-    
-    
-    
-    public function testDatabaseSettingsUI() {
-        
-        $databaseName = DB_NAME_PREFIX."_db_settings_UI";
-        parent::navigateDatabaseSettingsPage( $databaseName );
-        
-        // 'Database settings' text available.
-        $this->assertEquals( "Database settings", $this->getText( LINK_DIV."h2" ));
-        
-        // 'Database account for web access' section available
-        $this->assertTrue( $this->isElementPresent( LINK_FORM."fieldset" ));
-        
-        // 'Database account for web access' label available
-        $this->assertEquals( "Database account for web access", $this->getText( LINK_FORM."fieldset/legend" ));
-        
-        // 'Use the same account as for installation' check box available
-        $this->assertEquals( "Use the same account as for installation", $this->getText( LINK_FORM."fieldset/div[1]/label" ));
-        
-        // 'Use the same account as for installation' check box is selected by default
-        $this->assertEquals( "on", $this->getValue( "mysql__SameAccount" ));
-        
-        // 'Use the same account as for installation' check box deselected
-        $this->click( "mysql__SameAccount" );
-        
-        // verify 'Use the same account as for installation' check box is not selected
-        $this->assertEquals( "off", $this->getValue( "mysql__SameAccount" ));
-        
-        // 'Database username' label available
-        $this->assertEquals( "Database username:", $this->getText( "//div[@id='dbOtherAccount']/div[1]/div[1]/label" ));
-        
-        // 'Database username' text box is default to the 'wikiuser'
-        $this->assertEquals( "wikiuser", $this->getValue( "mysql_wgDBuser" ));
-        
-        // 'Database password' label available
-        $this->assertEquals( "Database password:", $this->getText( "//div[@id='dbOtherAccount']/div[2]/div[1]/label" ));
-        
-        // 'Create the account if it does not already exist' label available
-        $this->assertEquals( "Create the account if it does not already exist", $this->getText( "//div[@id='dbOtherAccount']/div[4]/label" ));
-        
-        // 'Create the account if it does not already exist' check box is not selected by default
-        $this->assertEquals( "off" , $this->getValue( "mysql__CreateDBAccount" ));
-        
-        //  'Create the account if it does not already exist' check box selected
-        $this->click( "mysql__CreateDBAccount" );
-        
-        // Verify  'Create the account if it does not already exist' check box is selected
-        $this->assertEquals( "on" , $this->getValue( "mysql__CreateDBAccount" ));
-        $this->click( "mysql__SameAccount" );
-        $this->assertEquals( "on", $this->getValue( "mysql__SameAccount" ));
-        
-        // 'Storage engine' label available
-        $this->assertEquals( "Storage engine:",
-                $this->getText( LINK_FORM."div[1]/div[1]/label"));
-        
-        // 'InnoDB' label available
-        $this->assertEquals( "InnoDB",
-                $this->getText( LINK_FORM."div[1]/div[2]/ul/li[1]/label" ));
-        
-        // 'InnoDB' radio button available
-        $this->assertTrue( $this->isElementPresent( "mysql__MysqlEngine_InnoDB" ));
-        
-        // 'MyISAM' label available
-        $this->assertEquals( "MyISAM", $this->getText( LINK_FORM."div[1]/div[2]/ul/li[2]/label" ));
-        
-        // 'MyISAM' radio button available
-        $this->assertTrue($this->isElementPresent( "mysql__MysqlEngine_MyISAM" ));
-        
-        // 'Database character set' label available
-        $this->assertEquals( "Database character set:",
-                $this->getText( LINK_FORM."div[3]/div[1]/label" ));
-        
-        // 'Binary' radio button available
-        $this->assertTrue( $this->isElementPresent( "mysql__MysqlCharset_binary" ));
-        
-        // 'Binary' radio button available
-        $this->assertEquals( "Binary", $this->getText( LINK_FORM."div[3]/div[2]/ul/li[1]/label" ));
-        
-        // 'UTF-8' radio button available
-        $this->assertTrue( $this->isElementPresent( "mysql__MysqlCharset_utf8" ));
-        
-        // 'UTF-8' label available
-        $this->assertEquals( "UTF-8", $this->getText( LINK_FORM."div[3]/div[2]/ul/li[2]/label" ));
-        
-        // 'Binary' radio button is selected
-        $this->assertEquals( "on", $this->getValue( "mysql__MysqlCharset_binary" ));
-    }
-    
-    
-    
-    public function testNamePageUI() {
-        
-        $databaseName = DB_NAME_PREFIX."_name_UI";
-        parent::navigateNamePage($databaseName);
-        
-        // 'Name of wiki' text box available
-        $this->assertEquals( "Name of wiki:",
-                $this->getText( LINK_FORM."div[1]/div[1]/label" ));
-        
-        $this->assertTrue( $this->isElementPresent( "config_wgSitename" ));
-        
-        // 'Project namespace' label available
-        $this->assertEquals( "Project namespace:",
-                $this->getText( LINK_FORM."div[2]/div[1]/label" ));
-        
-        // 'Same as the wiki name' radio button available
-        $this->assertTrue( $this->isElementPresent( "config__NamespaceType_site-name" ));
-        
-        // 'Project' radio button available
-        $this->assertTrue( $this->isElementPresent( "config__NamespaceType_generic" ));
-        
-        // 'Project' radio button available
-        $this->assertTrue( $this->isElementPresent( "config__NamespaceType_other" ));
-        
-        // 'Same as the wiki name' label available
-        $this->assertEquals( "Same as the wiki name:",
-                $this->getText( LINK_FORM."div[2]/div[2]/ul/li[1]/label" ));
-        
-        // 'Project' label available
-        $this->assertEquals("Project",
-                $this->getText( LINK_FORM."div[2]/div[2]/ul/li[2]/label" ));
-        
-        // 'Project' label available
-        $this->assertEquals( "Other (specify)",
-                $this->getText( LINK_FORM."div[2]/div[2]/ul/li[3]/label" ));
-        
-        //  'Same as the wiki name' radio button selected by default
-        $this->assertEquals( "on", $this->getValue( "config__NamespaceType_site-name" ));
-        
-        // 'Administrator account' section available
-        $this->assertTrue( $this->isElementPresent( LINK_FORM."fieldset" ));
-        
-        // 'Administrator account' label available
-        $this->assertEquals( "Administrator account",
-                $this->getText( LINK_FORM."fieldset/legend" ));
-        
-        // 'Your Name' label available
-        $this->assertEquals( "Your name:",
-                $this->getText( LINK_FORM."fieldset/div[1]/div[1]/label" ));
-        
-        // 'Your Name' text box available
-        $this->assertTrue( $this->isElementPresent( "config__AdminName" ));
-        
-        // 'Password' label available
-        $this->assertEquals( "Password:",
-                $this->getText( LINK_FORM."fieldset/div[2]/div[1]/label" ));
-        
-        // 'Password' text box available
-        $this->assertTrue( $this->isElementPresent( "config__AdminPassword" ));
-        
-        // 'Password again' label available
-        $this->assertEquals( "Password again:",
-                $this->getText( LINK_FORM."fieldset/div[3]/div[1]/label" ));
-        
-        // 'Password again' text box available
-        $this->assertTrue( $this->isElementPresent( "config__AdminPassword2" ));
-        
-        // 'Email address' label avaialble
-        $this->assertEquals( "E-mail address:",
-                $this->getText( LINK_FORM."fieldset/div[4]/div[1]/label" ));
-        
-        // 'Email address' text box available
-        $this->assertTrue( $this->isElementPresent( "config__AdminEmail" ));
-        
-        // Message displayed
-        $this->assertEquals( "You are almost done! You can now skip the remaining configuration and install the wiki right now.",
-                $this->getText( LINK_FORM."/div[4]/div[2]/p" ));
-        
-        // 'Ask me more questions.' radio button available
-        $this->assertTrue( $this->isElementPresent( "config__SkipOptional_continue" ));
-        
-        // 'Ask me more questions.' label available
-        $this->assertEquals( "Ask me more questions.",
-                $this->getText( LINK_FORM."div[5]/div[2]/ul/li[1]/label" ));
-        
-        // 'I'm bored already, just install the wiki' radio button is avaiable
-        $this->assertTrue( $this->isElementPresent( "config__SkipOptional_skip" ));
-        
-        // 'I'm bored already, just install the wiki' label available
-        $this->assertEquals( "I'm bored already, just install the wiki.",
-                $this->getText( LINK_FORM."div[5]/div[2]/ul/li[2]/label" ));
-        
-        //  'Ask me more questions.' radio button is default selected
-        $this->assertEquals( "on", $this->getValue( "config__SkipOptional_continue" ));
-    }
-    
-    
-    
-    public function testOptionPageUI() {
-        
-        $databaseName = DB_NAME_PREFIX."_options_UI";
-        parent::navigateOptionsPage($databaseName);
-        
-        // 'Options' label available
-        $this->assertEquals( "Options", $this->getText( LINK_DIV."h2"));
-        
-        // 'Return e-mail address' label available
-        $this->assertEquals( "Return e-mail address:", $this->getText( "//div[@id='emailwrapper']/div[1]/div[1]/label" ));
-        
-        //    'Return e-mail address' text box available
-        $this->assertTrue( $this->isElementPresent( "config_wgPasswordSender" ));
-        
-        // Text 'apache@localhost' is default value of the 'Return e-mail address' text box
-        $this->assertEquals( "apache@localhost", $this->getValue( "config_wgPasswordSender" ));
-        
-        // 'Logo URL' label available
-        $this->assertEquals( "Logo URL:", $this->getText( LINK_FORM."fieldset[2]/div[3]/div[1]/label" ));
-        
-        // 'Logo URL' text box available
-        $this->assertTrue( $this->isElementPresent( "config_wgLogo" ));
-        
-        // Correct path available in the 'Logo URL' text box
-        $this->assertEquals( "/wiki/skins/common/images/wiki.png", $this->getValue( "config_wgLogo" ));
-        
-        // 'Enable file uploads' radio button available
-        $this->assertTrue( $this->isElementPresent( "config_wgEnableUploads" ));
-        
-        // 'Enable file uploads' label available
-        $this->assertEquals( "Enable file uploads",
-                $this->getText( LINK_FORM."fieldset[2]/div[1]/label" ));
-        
-        // 'Enable file uploads' check box is not selected
-        $this->assertEquals( "off", $this->getValue( "config_wgEnableUploads" ));
-        
-        $this->click( "config_wgEnableUploads" );
-        
-        // 'Directory for deleted files' label available
-        $this->assertEquals( "Directory for deleted files:",
-                $this->getText( "//div[@id='uploadwrapper']/div/div[1]/label" ));
-        
-        // 'Directory for deleted files' text box available
-        $this->assertTrue( $this->isElementPresent( "config_wgDeletedDirectory" ));
-        
-        // Correct path available in the 'Directory for deleted files' text box
-        $this->assertEquals( "C:\\wamp\\www\\".DIRECTORY_NAME."/images/deleted",
-                $this->getValue( "config_wgDeletedDirectory" ));
-    }
-    
-    
-    
-    public function testInstallPageUI() {
-        
-        $databaseName = DB_NAME_PREFIX."_install_UI";
-        parent::navigateInstallPage( $databaseName );
-        
-        // Verify installation done messages display
-        $this->assertEquals( "Setting up database... done",
-                $this->getText( LINK_FORM."ul/li[1]" ));
-        $this->assertEquals( "Creating tables... done",
-                $this->getText( LINK_FORM."ul/li[2]" ));
-        $this->assertEquals( "Creating database user... done",
-                $this->getText( LINK_FORM."ul/li[3]" ));
-        $this->assertEquals( "Populating default interwiki table... done",
-                $this->getText( LINK_FORM."ul/li[4]" ));
-        $this->assertEquals( "Generating secret key... done",
-                $this->getText( LINK_FORM."ul/li[5]" ));
-        $this->assertEquals( "Generating default upgrade key... done",
-                $this->getText( LINK_FORM."ul/li[6]" ));
-        $this->assertEquals( "Creating administrator user account... done",
-                $this->getText( LINK_FORM."ul/li[7]" ));
-        $this->assertEquals( "Creating main page with default content... done",
-                $this->getText( LINK_FORM."ul/li[8]" ));
-    }
-    
-    
-    
-    public function testCompletePageUI() {
-        
-        $databaseName = DB_NAME_PREFIX."_complete_UI";
-        parent::navigateCompletePage( $databaseName );
-        
-        // 'Congratulations!' text display
-        $this->assertEquals("Congratulations!",
-                $this->getText( LINK_FORM."div[1]/div[2]/p[1]/b"));
-        // 'LocalSettings.php' generated message display
-        $this->assertEquals( "The installer has generated a LocalSettings.php file. It contains all your configuration.",
-                $this->getText( LINK_FORM."div[1]/div[2]/p[2]" ));
-        
-        // 'Download LocalSettings.php'' link available
-        $this->assertTrue( $this->isElementPresent( "link=Download LocalSettings.php" ));
-        
-        // 'enter your wiki' link available
-        $this->assertTrue($this->isElementPresent("link=Folder/index.php enter your wiki"));
-    }
-    
-    
-    
-    public function testRestartInstallation() {
-        
-        parent::navigateConnetToDatabasePage();
-        $this->click( "link=Restart installation" );
-        $this->waitForPageToLoad( PAGE_LOAD_TIME );
-        
-        // Restart installation' label should be available.
-        $this->assertEquals( "Restart installation", $this->getText( LINK_DIV."h2" ));
-        
-        //'Do you want to clear all saved data that you have entered and restart the installation process?' label available
-        $this->assertEquals( "Do you want to clear all saved data that you have entered and restart the installation process?",
-                $this->getText( "//*[@id='bodyContent']/div/div/div[2]/form/div[1]/div[2]" ));
-        // 'Back' button available
-        $this->assertTrue($this->isElementPresent( "submit-back" ));
-        
-        // 'Restart' button available
-        $this->assertTrue($this->isElementPresent( "submit-restart" ));
-    }
-    
-    
-    
-    public function testMediaWikiLogoAvailability() {
-        
-        $databaseName = DB_NAME_PREFIX."_mediawiki_logo";
-        parent::navigateInitialpage();
-        parent::mediaWikiLogoPresentInitialScreen();
-        $this->click( "link=set up the wiki" );
-        $this->waitForPageToLoad( PAGE_LOAD_TIME );
-        
-        // 'Language' page
-        parent::mediaWikiLogoPresent();
-        parent::clickContinueButton();
-        
-        // 'Welcome to MediaWiki' page
-        parent::mediaWikiLogoPresent();
-        parent::clickContinueButton();
-        
-        // 'Connet to database' page
-        parent::mediaWikiLogoPresent();
-        $this->type("mysql_wgDBname", $databaseName );
-        parent::clickContinueButton();
-        
-        // 'Database setting' page
-        parent::mediaWikiLogoPresent();
-        parent::clickContinueButton();
-        
-        // 'Name' page
-        parent::mediaWikiLogoPresent();
-        parent::completeNamePage();
-        parent::clickContinueButton();
-        
-        // 'Options' page
-        parent::mediaWikiLogoPresent();
-        parent::clickContinueButton();
-        
-        // 'Install' page
-        parent::mediaWikiLogoPresent();
-    }
-    
-    
-    public function testRightFramework() {
-        
-        parent::navigateLanguagePage();
-        // Verfy right framework texts display
-        $this->assertEquals( "Language",
-                $this->getText( LINK_RIGHT_FRAMEWORK."li[1]" ));
-        $this->assertEquals( "Existing wiki",
-                $this->getText( LINK_RIGHT_FRAMEWORK."li[2]" ));
-        $this->assertEquals( "Welcome to MediaWiki!",
-                $this->getText( LINK_RIGHT_FRAMEWORK."li[3]" ));
-        $this->assertEquals( "Connect to database",
-                $this->getText( LINK_RIGHT_FRAMEWORK."li[4]" ));
-        $this->assertEquals( "Upgrade existing installation",
-                $this->getText( LINK_RIGHT_FRAMEWORK."li[5]" ));
-        $this->assertEquals( "Database settings",
-                $this->getText( LINK_RIGHT_FRAMEWORK."li[6]" ));
-        $this->assertEquals( "Name",
-                $this->getText( LINK_RIGHT_FRAMEWORK."li[7]" ));
-        $this->assertEquals( "Options",
-                $this->getText( LINK_RIGHT_FRAMEWORK."li[8]" ));
-        $this->assertEquals( "Install",
-                $this->getText( LINK_RIGHT_FRAMEWORK."li[9]" ));
-        $this->assertEquals( "Complete!",
-                $this->getText( LINK_RIGHT_FRAMEWORK."li[10]/span" ));
-    } 
+       function setUp() {
+               parent::setUp();
+       }
+
+       public function testInitialPageUI() {
+
+               parent::navigateInitialpage();
+
+               // MediaWiki logo available
+               $this->assertTrue( $this->isElementPresent( "//img[@alt='The MediaWiki logo']" ) );
+
+               // 'MediaWiki 1.18alpha' text available
+               $this->assertEquals( "MediaWiki 1.18alpha", $this->getText( "//h1" ) );
+
+               // 'LocalSettings.php not found.' text available
+               $this->assertEquals( "LocalSettings.php not found.", $this->getText( "//p[1]" ) );
+
+               // 'Please set up the wiki first' text available
+               $this->assertEquals( "Please set up the wiki first.", $this->getText( "//p[2]" ) );
+
+               // 'set up the wiki' link available
+               $this->assertTrue( $this->isElementPresent( "link=set up the wiki" ) );
+       }
+
+       public function testlanguagePageUI() {
+               parent::navigateLanguagePage();
+
+               // Verify 'Language' heading
+               $this->assertEquals( "Language", $this->getText( LINK_DIV . "h2" ) );
+
+               // 'Your language' label available
+               $this->assertEquals( "Your language:",
+                       $this->getText( LINK_FORM . "div[1]/div[1]/label" ) );
+
+               // 'Your language' dropdown available
+               $this->assertTrue( $this->isElementPresent( "UserLang" ) );
+
+               // 'Wiki language' label available
+               $this->assertEquals( "Wiki language:",
+                       $this->getText( LINK_FORM . "div[2]/div[1]/label" ) );
+
+               // 'Wiki language' dropdown available
+               $this->assertTrue( $this->isElementPresent( "ContLang" ) );
+       }
+
+       public function testWelcometoMediaWikiUI() {
+               parent::navigateWelcometoMediaWikiPage();
+
+               // Verify 'Welcome to MediaWiki!' heading
+               $this->assertEquals( "Welcome to MediaWiki!",
+                       $this->getText( LINK_DIV . "h2" ) );
+
+               // Verify environment ok text displayed.
+               $this->assertEquals( "The environment has been checked.You can install MediaWiki.",
+                       $this->getText( LINK_DIV . "div[6]/span" ) );
+       }
+
+       public function testConnectToDatabaseUI() {
+               parent::navigateConnetToDatabasePage();
+
+               //  'MYSQL radio button available
+               $this->assertEquals( "MySQL",
+                       $this->getText( LINK_FORM . "div[2]/div[2]/ul/li[1]/label" ) );
+               $this->assertTrue( $this->isElementPresent( LINK_FORM . "div[2]/div[2]/ul/li[1]" ) );
+
+               // 'SQLite' radio button available
+               $this->assertTrue( $this->isElementPresent( LINK_FORM . "div[2]/div[2]/ul/li[2]" ) );
+               $this->assertEquals( "SQLite", $this->getText( LINK_FORM . "div[2]/div[2]/ul/li[2]/label " ) );
+
+               // 'Database host' label available
+               $this->assertEquals( "Database host:", $this->getText( "//div[@id='DB_wrapper_mysql']/div/div[1]/label" ) );
+
+               // 'Database host' text box default to 'localhost'
+               $this->assertEquals( "localhost", $this->getValue( "mysql_wgDBserver" ) );
+
+               // 'Identify this wiki' section available
+               $this->assertTrue( $this->isElementPresent( "//div[@id='DB_wrapper_mysql']/fieldset[1]/legend" ) );
+
+               // 'Identify this wiki' label available
+               $this->assertEquals( "Identify this wiki", $this->getText( "//div[@id='DB_wrapper_mysql']/fieldset[1]/legend" ) );
+
+               // 'Database name' lable available
+               $this->assertEquals( "Database name:",
+                       $this->getText( "//div[@id='DB_wrapper_mysql']/fieldset[1]/div[1]/div[1]/label" ) );
+
+               // Verify 'Database name:' text box is default to 'my_wiki'
+               $this->assertEquals( "my_wiki", $this->getValue( "mysql_wgDBname" ) );
+
+               // Verify 'Database table prefix:' label available
+               $this->assertEquals( "Database table prefix:",
+                       $this->getText( "//div[@id='DB_wrapper_mysql']/fieldset[1]/div[2]/div[1]/label" ) );
+
+               // 'User account for installation' section available
+               $this->assertTrue( $this->isElementPresent( "//div[@id='DB_wrapper_mysql']/fieldset[2]/legend" ) );
+
+               // 'User account for installation' label available
+               $this->assertEquals( "User account for installation", $this->getText( "//div[@id='DB_wrapper_mysql']/fieldset[2]/legend" ) );
+
+               // 'Database username' label available
+               $this->assertEquals( "Database username:",
+                       $this->getText( "//div[@id='DB_wrapper_mysql']/fieldset[2]/div[1]/div[1]/label" ) );
+
+               // 'Database username' text box defaults to 'root'
+               $this->assertEquals( "root", $this->getValue( "mysql__InstallUser" ) );
+
+               // 'Database password' label available
+               $this->assertEquals( "Database password:",
+                       $this->getText( "//div[@id='DB_wrapper_mysql']/fieldset[2]/div[2]/div[1]/label" ) );
+       }
+
+       public function testDatabaseSettingsUI() {
+               $databaseName = DB_NAME_PREFIX . "_db_settings_UI";
+               parent::navigateDatabaseSettingsPage( $databaseName );
+
+               // 'Database settings' text available.
+               $this->assertEquals( "Database settings", $this->getText( LINK_DIV . "h2" ) );
+
+               // 'Database account for web access' section available
+               $this->assertTrue( $this->isElementPresent( LINK_FORM . "fieldset" ) );
+
+               // 'Database account for web access' label available
+               $this->assertEquals( "Database account for web access", $this->getText( LINK_FORM . "fieldset/legend" ) );
+
+               // 'Use the same account as for installation' check box available
+               $this->assertEquals( "Use the same account as for installation", $this->getText( LINK_FORM . "fieldset/div[1]/label" ) );
+
+               // 'Use the same account as for installation' check box is selected by default
+               $this->assertEquals( "on", $this->getValue( "mysql__SameAccount" ) );
+
+               // 'Use the same account as for installation' check box deselected
+               $this->click( "mysql__SameAccount" );
+
+               // verify 'Use the same account as for installation' check box is not selected
+               $this->assertEquals( "off", $this->getValue( "mysql__SameAccount" ) );
+
+               // 'Database username' label available
+               $this->assertEquals( "Database username:", $this->getText( "//div[@id='dbOtherAccount']/div[1]/div[1]/label" ) );
+
+               // 'Database username' text box is default to the 'wikiuser'
+               $this->assertEquals( "wikiuser", $this->getValue( "mysql_wgDBuser" ) );
+
+               // 'Database password' label available
+               $this->assertEquals( "Database password:", $this->getText( "//div[@id='dbOtherAccount']/div[2]/div[1]/label" ) );
+
+               // 'Create the account if it does not already exist' label available
+               $this->assertEquals( "Create the account if it does not already exist", $this->getText( "//div[@id='dbOtherAccount']/div[4]/label" ) );
+
+               // 'Create the account if it does not already exist' check box is not selected by default
+               $this->assertEquals( "off", $this->getValue( "mysql__CreateDBAccount" ) );
+
+               //  'Create the account if it does not already exist' check box selected
+               $this->click( "mysql__CreateDBAccount" );
+
+               // Verify  'Create the account if it does not already exist' check box is selected
+               $this->assertEquals( "on", $this->getValue( "mysql__CreateDBAccount" ) );
+               $this->click( "mysql__SameAccount" );
+               $this->assertEquals( "on", $this->getValue( "mysql__SameAccount" ) );
+
+               // 'Storage engine' label available
+               $this->assertEquals( "Storage engine:",
+                       $this->getText( LINK_FORM . "div[1]/div[1]/label" ) );
+
+               // 'InnoDB' label available
+               $this->assertEquals( "InnoDB",
+                       $this->getText( LINK_FORM . "div[1]/div[2]/ul/li[1]/label" ) );
+
+               // 'InnoDB' radio button available
+               $this->assertTrue( $this->isElementPresent( "mysql__MysqlEngine_InnoDB" ) );
+
+               // 'MyISAM' label available
+               $this->assertEquals( "MyISAM", $this->getText( LINK_FORM . "div[1]/div[2]/ul/li[2]/label" ) );
+
+               // 'MyISAM' radio button available
+               $this->assertTrue( $this->isElementPresent( "mysql__MysqlEngine_MyISAM" ) );
+
+               // 'Database character set' label available
+               $this->assertEquals( "Database character set:",
+                       $this->getText( LINK_FORM . "div[3]/div[1]/label" ) );
+
+               // 'Binary' radio button available
+               $this->assertTrue( $this->isElementPresent( "mysql__MysqlCharset_binary" ) );
+
+               // 'Binary' radio button available
+               $this->assertEquals( "Binary", $this->getText( LINK_FORM . "div[3]/div[2]/ul/li[1]/label" ) );
+
+               // 'UTF-8' radio button available
+               $this->assertTrue( $this->isElementPresent( "mysql__MysqlCharset_utf8" ) );
+
+               // 'UTF-8' label available
+               $this->assertEquals( "UTF-8", $this->getText( LINK_FORM . "div[3]/div[2]/ul/li[2]/label" ) );
+
+               // 'Binary' radio button is selected
+               $this->assertEquals( "on", $this->getValue( "mysql__MysqlCharset_binary" ) );
+       }
+
+       public function testNamePageUI() {
+               $databaseName = DB_NAME_PREFIX . "_name_UI";
+               parent::navigateNamePage( $databaseName );
+
+               // 'Name of wiki' text box available
+               $this->assertEquals( "Name of wiki:",
+                       $this->getText( LINK_FORM . "div[1]/div[1]/label" ) );
+
+               $this->assertTrue( $this->isElementPresent( "config_wgSitename" ) );
+
+               // 'Project namespace' label available
+               $this->assertEquals( "Project namespace:",
+                       $this->getText( LINK_FORM . "div[2]/div[1]/label" ) );
+
+               // 'Same as the wiki name' radio button available
+               $this->assertTrue( $this->isElementPresent( "config__NamespaceType_site-name" ) );
+
+               // 'Project' radio button available
+               $this->assertTrue( $this->isElementPresent( "config__NamespaceType_generic" ) );
+
+               // 'Project' radio button available
+               $this->assertTrue( $this->isElementPresent( "config__NamespaceType_other" ) );
+
+               // 'Same as the wiki name' label available
+               $this->assertEquals( "Same as the wiki name:",
+                       $this->getText( LINK_FORM . "div[2]/div[2]/ul/li[1]/label" ) );
+
+               // 'Project' label available
+               $this->assertEquals( "Project",
+                       $this->getText( LINK_FORM . "div[2]/div[2]/ul/li[2]/label" ) );
+
+               // 'Project' label available
+               $this->assertEquals( "Other (specify)",
+                       $this->getText( LINK_FORM . "div[2]/div[2]/ul/li[3]/label" ) );
+
+               //  'Same as the wiki name' radio button selected by default
+               $this->assertEquals( "on", $this->getValue( "config__NamespaceType_site-name" ) );
+
+               // 'Administrator account' section available
+               $this->assertTrue( $this->isElementPresent( LINK_FORM . "fieldset" ) );
+
+               // 'Administrator account' label available
+               $this->assertEquals( "Administrator account",
+                       $this->getText( LINK_FORM . "fieldset/legend" ) );
+
+               // 'Your Name' label available
+               $this->assertEquals( "Your name:",
+                       $this->getText( LINK_FORM . "fieldset/div[1]/div[1]/label" ) );
+
+               // 'Your Name' text box available
+               $this->assertTrue( $this->isElementPresent( "config__AdminName" ) );
+
+               // 'Password' label available
+               $this->assertEquals( "Password:",
+                       $this->getText( LINK_FORM . "fieldset/div[2]/div[1]/label" ) );
+
+               // 'Password' text box available
+               $this->assertTrue( $this->isElementPresent( "config__AdminPassword" ) );
+
+               // 'Password again' label available
+               $this->assertEquals( "Password again:",
+                       $this->getText( LINK_FORM . "fieldset/div[3]/div[1]/label" ) );
+
+               // 'Password again' text box available
+               $this->assertTrue( $this->isElementPresent( "config__AdminPassword2" ) );
+
+               // 'Email address' label avaialble
+               $this->assertEquals( "E-mail address:",
+                       $this->getText( LINK_FORM . "fieldset/div[4]/div[1]/label" ) );
+
+               // 'Email address' text box available
+               $this->assertTrue( $this->isElementPresent( "config__AdminEmail" ) );
+
+               // Message displayed
+               $this->assertEquals( "You are almost done! You can now skip the remaining configuration and install the wiki right now.",
+                       $this->getText( LINK_FORM . "/div[4]/div[2]/p" ) );
+
+               // 'Ask me more questions.' radio button available
+               $this->assertTrue( $this->isElementPresent( "config__SkipOptional_continue" ) );
+
+               // 'Ask me more questions.' label available
+               $this->assertEquals( "Ask me more questions.",
+                       $this->getText( LINK_FORM . "div[5]/div[2]/ul/li[1]/label" ) );
+
+               // 'I'm bored already, just install the wiki' radio button is avaiable
+               $this->assertTrue( $this->isElementPresent( "config__SkipOptional_skip" ) );
+
+               // 'I'm bored already, just install the wiki' label available
+               $this->assertEquals( "I'm bored already, just install the wiki.",
+                       $this->getText( LINK_FORM . "div[5]/div[2]/ul/li[2]/label" ) );
+
+               //  'Ask me more questions.' radio button is default selected
+               $this->assertEquals( "on", $this->getValue( "config__SkipOptional_continue" ) );
+       }
+
+       public function testOptionPageUI() {
+               $databaseName = DB_NAME_PREFIX . "_options_UI";
+               parent::navigateOptionsPage( $databaseName );
+
+               // 'Options' label available
+               $this->assertEquals( "Options", $this->getText( LINK_DIV . "h2" ) );
+
+               // 'Return e-mail address' label available
+               $this->assertEquals( "Return e-mail address:", $this->getText( "//div[@id='emailwrapper']/div[1]/div[1]/label" ) );
+
+               //    'Return e-mail address' text box available
+               $this->assertTrue( $this->isElementPresent( "config_wgPasswordSender" ) );
+
+               // Text 'apache@localhost' is default value of the 'Return e-mail address' text box
+               $this->assertEquals( "apache@localhost", $this->getValue( "config_wgPasswordSender" ) );
+
+               // 'Logo URL' label available
+               $this->assertEquals( "Logo URL:", $this->getText( LINK_FORM . "fieldset[2]/div[3]/div[1]/label" ) );
+
+               // 'Logo URL' text box available
+               $this->assertTrue( $this->isElementPresent( "config_wgLogo" ) );
+
+               // Correct path available in the 'Logo URL' text box
+               $this->assertEquals( "/wiki/skins/common/images/wiki.png", $this->getValue( "config_wgLogo" ) );
+
+               // 'Enable file uploads' radio button available
+               $this->assertTrue( $this->isElementPresent( "config_wgEnableUploads" ) );
+
+               // 'Enable file uploads' label available
+               $this->assertEquals( "Enable file uploads",
+                       $this->getText( LINK_FORM . "fieldset[2]/div[1]/label" ) );
+
+               // 'Enable file uploads' check box is not selected
+               $this->assertEquals( "off", $this->getValue( "config_wgEnableUploads" ) );
+
+               $this->click( "config_wgEnableUploads" );
+
+               // 'Directory for deleted files' label available
+               $this->assertEquals( "Directory for deleted files:",
+                       $this->getText( "//div[@id='uploadwrapper']/div/div[1]/label" ) );
+
+               // 'Directory for deleted files' text box available
+               $this->assertTrue( $this->isElementPresent( "config_wgDeletedDirectory" ) );
+
+               // Correct path available in the 'Directory for deleted files' text box
+               $this->assertEquals( "C:\\wamp\\www\\" . DIRECTORY_NAME . "/images/deleted",
+                       $this->getValue( "config_wgDeletedDirectory" ) );
+       }
+
+       public function testInstallPageUI() {
+               $databaseName = DB_NAME_PREFIX . "_install_UI";
+               parent::navigateInstallPage( $databaseName );
+
+               // Verify installation done messages display
+               $this->assertEquals( "Setting up database... done",
+                       $this->getText( LINK_FORM . "ul/li[1]" ) );
+               $this->assertEquals( "Creating tables... done",
+                       $this->getText( LINK_FORM . "ul/li[2]" ) );
+               $this->assertEquals( "Creating database user... done",
+                       $this->getText( LINK_FORM . "ul/li[3]" ) );
+               $this->assertEquals( "Populating default interwiki table... done",
+                       $this->getText( LINK_FORM . "ul/li[4]" ) );
+               $this->assertEquals( "Generating secret key... done",
+                       $this->getText( LINK_FORM . "ul/li[5]" ) );
+               $this->assertEquals( "Generating default upgrade key... done",
+                       $this->getText( LINK_FORM . "ul/li[6]" ) );
+               $this->assertEquals( "Creating administrator user account... done",
+                       $this->getText( LINK_FORM . "ul/li[7]" ) );
+               $this->assertEquals( "Creating main page with default content... done",
+                       $this->getText( LINK_FORM . "ul/li[8]" ) );
+       }
+
+       public function testCompletePageUI() {
+               $databaseName = DB_NAME_PREFIX . "_complete_UI";
+               parent::navigateCompletePage( $databaseName );
+
+               // 'Congratulations!' text display
+               $this->assertEquals( "Congratulations!",
+                       $this->getText( LINK_FORM . "div[1]/div[2]/p[1]/b" ) );
+               // 'LocalSettings.php' generated message display
+               $this->assertEquals( "The installer has generated a LocalSettings.php file. It contains all your configuration.",
+                       $this->getText( LINK_FORM . "div[1]/div[2]/p[2]" ) );
+
+               // 'Download LocalSettings.php'' link available
+               $this->assertTrue( $this->isElementPresent( "link=Download LocalSettings.php" ) );
+
+               // 'enter your wiki' link available
+               $this->assertTrue( $this->isElementPresent( "link=Folder/index.php enter your wiki" ) );
+       }
+
+       public function testRestartInstallation() {
+               parent::navigateConnetToDatabasePage();
+               $this->click( "link=Restart installation" );
+               $this->waitForPageToLoad( PAGE_LOAD_TIME );
+
+               // Restart installation' label should be available.
+               $this->assertEquals( "Restart installation", $this->getText( LINK_DIV . "h2" ) );
+
+               //'Do you want to clear all saved data that you have entered and restart the installation process?' label available
+               $this->assertEquals( "Do you want to clear all saved data that you have entered and restart the installation process?",
+                       $this->getText( "//*[@id='bodyContent']/div/div/div[2]/form/div[1]/div[2]" ) );
+               // 'Back' button available
+               $this->assertTrue( $this->isElementPresent( "submit-back" ) );
+
+               // 'Restart' button available
+               $this->assertTrue( $this->isElementPresent( "submit-restart" ) );
+       }
+
+       public function testMediaWikiLogoAvailability() {
+               $databaseName = DB_NAME_PREFIX . "_mediawiki_logo";
+               parent::navigateInitialpage();
+               parent::mediaWikiLogoPresentInitialScreen();
+               $this->click( "link=set up the wiki" );
+               $this->waitForPageToLoad( PAGE_LOAD_TIME );
+
+               // 'Language' page
+               parent::mediaWikiLogoPresent();
+               parent::clickContinueButton();
+
+               // 'Welcome to MediaWiki' page
+               parent::mediaWikiLogoPresent();
+               parent::clickContinueButton();
+
+               // 'Connet to database' page
+               parent::mediaWikiLogoPresent();
+               $this->type( "mysql_wgDBname", $databaseName );
+               parent::clickContinueButton();
+
+               // 'Database setting' page
+               parent::mediaWikiLogoPresent();
+               parent::clickContinueButton();
+
+               // 'Name' page
+               parent::mediaWikiLogoPresent();
+               parent::completeNamePage();
+               parent::clickContinueButton();
+
+               // 'Options' page
+               parent::mediaWikiLogoPresent();
+               parent::clickContinueButton();
+
+               // 'Install' page
+               parent::mediaWikiLogoPresent();
+       }
+
+       public function testRightFramework() {
+               parent::navigateLanguagePage();
+               // Verfy right framework texts display
+               $this->assertEquals( "Language",
+                       $this->getText( LINK_RIGHT_FRAMEWORK . "li[1]" ) );
+               $this->assertEquals( "Existing wiki",
+                       $this->getText( LINK_RIGHT_FRAMEWORK . "li[2]" ) );
+               $this->assertEquals( "Welcome to MediaWiki!",
+                       $this->getText( LINK_RIGHT_FRAMEWORK . "li[3]" ) );
+               $this->assertEquals( "Connect to database",
+                       $this->getText( LINK_RIGHT_FRAMEWORK . "li[4]" ) );
+               $this->assertEquals( "Upgrade existing installation",
+                       $this->getText( LINK_RIGHT_FRAMEWORK . "li[5]" ) );
+               $this->assertEquals( "Database settings",
+                       $this->getText( LINK_RIGHT_FRAMEWORK . "li[6]" ) );
+               $this->assertEquals( "Name",
+                       $this->getText( LINK_RIGHT_FRAMEWORK . "li[7]" ) );
+               $this->assertEquals( "Options",
+                       $this->getText( LINK_RIGHT_FRAMEWORK . "li[8]" ) );
+               $this->assertEquals( "Install",
+                       $this->getText( LINK_RIGHT_FRAMEWORK . "li[9]" ) );
+               $this->assertEquals( "Complete!",
+                       $this->getText( LINK_RIGHT_FRAMEWORK . "li[10]/span" ) );
+       }
 }
index 72e75e1..a74efc5 100644 (file)
@@ -6,7 +6,7 @@
  * @file
  * @ingroup Testing
  * Copyright (C) 2010 Nadeesha Weerasinghe <nadeesha@calcey.com>
- * http://www.calcey.com/ 
+ * http://www.calcey.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
  *
  */
 
-
 class AddContentToNewPageTestCase extends SeleniumTestCase {
-
-  
-    // Add bold text and verify output
-    public function testAddBoldText() {
-
-        $this->getExistingPage();
-        $this->clickEditLink();
-        $this->loadWikiEditor();
-        $this->clearWikiEditor();
-        $this->click( "//*[@id='mw-editbutton-bold']" );
-        $this->clickShowPreviewBtn();
-        $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME );
-
-        // Verify bold text displayed on mediawiki preview
-        $this->assertTrue($this->isElementPresent( "//div[@id='wikiPreview']/p/b" ));
-        $this->assertTrue($this->isTextPresent( "Bold text" ));
-    }
-
-    // Add italic text and verify output
-    public function testAddItalicText() {
-
-        $this->getExistingPage();
-        $this->clickEditLink();
-        $this->loadWikiEditor();
-        $this->clearWikiEditor();
-        $this->click( "//*[@id='mw-editbutton-italic']" );
-        $this->clickShowPreviewBtn();
-        $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME );
-
-        // Verify italic text displayed on mediawiki preview
-        $this->assertTrue($this->isElementPresent("//div[@id='wikiPreview']/p/i"));
-        $this->assertTrue($this->isTextPresent( "Italic text" ));
-    }
-
-    // Add internal link for a new page and verify output in the preview
-    public function testAddInternalLinkNewPage() {
-        $this->getExistingPage();
-        $this->clickEditLink();
-        $this->loadWikiEditor();
-        $this->clearWikiEditor();
-        $this->click( "//*[@id='mw-editbutton-link']" );
-        $this->clickShowPreviewBtn();
-        $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME );
-
-        // Verify internal link displayed on mediawiki preview
-        $source = $this->getText( "//*[@id='wikiPreview']/p/a" );
-        $correct = strstr( $source, "Link title" );
-        $this->assertEquals( $correct, true );
-
-        $this->click( SeleniumTestConstants::LINK_START."Link title" );
-        $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME );
-
-        // Verify internal link open as a new page - editing mode
-        $source = $this->getText( "firstHeading" );
-        $correct = strstr( $source, "Editing Link title" );
-        $this->assertEquals( $correct, true );
-    }
-
-    // Add external link and verify output in the preview
-    public function testAddExternalLink() {
-        $this->getExistingPage();
-        $this->clickEditLink();
-        $this->loadWikiEditor();
-        $this->clearWikiEditor();
-        $this->click( "//*[@id='mw-editbutton-extlink']" );
-        $this->type( SeleniumTestConstants::TEXT_EDITOR, "[http://www.google.com Google]" );
-        $this->clickShowPreviewBtn();
-        $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME );
-
-        // Verify external links displayed on mediawiki preview
-        $source = $this->getText( "//*[@id='wikiPreview']/p/a" );
-        $correct = strstr( $source, "Google" );
-        $this->assertEquals( $correct, true );
-
-        $this->click( SeleniumTestConstants::LINK_START."Google" );
-        $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME );
-
-        // Verify external link opens
-        $source = $this->getTitle();
-        $correct = strstr( $source, "Google" );
-        $this->assertEquals( $correct, true);
-    }
-
-    // Add level 2 headline and verify output in the preview
-    public function testAddLevel2HeadLine() {
-        $blnElementPresent = false;
-        $blnTextPresent = false;
-        $this->getExistingPage();
-        $this->clickEditLink();
-        $this->loadWikiEditor();
-        $this->clearWikiEditor();
-        $this->click( "mw-editbutton-headline" );
-        $this->clickShowPreviewBtn();
-        $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME );
-        $this->assertTrue($this->isElementPresent( "//div[@id='wikiPreview']/h2" ));
-
-        // Verify level 2 headline displayed on mediawiki preview
-        $source = $this->getText( "//*[@id='Headline_text']" );
-        $correct = strstr( $source, "Headline text" );
-        $this->assertEquals( $correct, true );
-    }
-
-    // Add text with ignore wiki format and verify output the preview
-    public function testAddNoWikiFormat() {
-        $this->getExistingPage();
-        $this->clickEditLink();
-        $this->loadWikiEditor();
-        $this->clearWikiEditor();
-        $this->click( "//*[@id='mw-editbutton-nowiki']" );
-        $this->clickShowPreviewBtn();
-        $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME );
-
-        // Verify ignore wiki format text displayed on mediawiki preview
-        $source = $this->getText( "//div[@id='wikiPreview']/p" );
-        $correct = strstr( $source, "Insert non-formatted text here" );
-        $this->assertEquals( $correct, true );
-    }
-
-    // Add signature and verify output in the preview
-    public function testAddUserSignature() {
-        $this->getExistingPage();
-        $this->clickEditLink();
-        $this->loadWikiEditor();
-        $this->clearWikiEditor();
-        $this->click( "mw-editbutton-signature" );
-        $this->clickShowPreviewBtn();
-        $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME );
-
-        // Verify signature displayed on mediawiki preview
-        $source = $this->getText( "//*[@id='wikiPreview']/p/a" );
-        $username = $this->getText( "//*[@id='pt-userpage']/a" );
-        $correct = strstr( $source, $username );
-        $this->assertEquals( $correct, true );
-    }
-
-    // Add horizontal line and verify output in the preview
-    public function testHorizontalLine() {
-        $this->getExistingPage();
-        $this->clickEditLink();
-        $this->loadWikiEditor();
-        $this->clearWikiEditor();
-        $this->click( "mw-editbutton-hr" );
-
-        $this->clickShowPreviewBtn();
-        $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME );
-
-        // Verify horizontal line displayed on mediawiki preview
-        $this->assertTrue( $this->isElementPresent( "//div[@id='wikiPreview']/hr" ));
-        $this->deletePage( "new" );
-    }
+       // Add bold text and verify output
+       public function testAddBoldText() {
+               $this->getExistingPage();
+               $this->clickEditLink();
+               $this->loadWikiEditor();
+               $this->clearWikiEditor();
+               $this->click( "//*[@id='mw-editbutton-bold']" );
+               $this->clickShowPreviewBtn();
+               $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME );
+
+               // Verify bold text displayed on mediawiki preview
+               $this->assertTrue( $this->isElementPresent( "//div[@id='wikiPreview']/p/b" ) );
+               $this->assertTrue( $this->isTextPresent( "Bold text" ) );
+       }
+
+       // Add italic text and verify output
+       public function testAddItalicText() {
+               $this->getExistingPage();
+               $this->clickEditLink();
+               $this->loadWikiEditor();
+               $this->clearWikiEditor();
+               $this->click( "//*[@id='mw-editbutton-italic']" );
+               $this->clickShowPreviewBtn();
+               $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME );
+
+               // Verify italic text displayed on mediawiki preview
+               $this->assertTrue( $this->isElementPresent( "//div[@id='wikiPreview']/p/i" ) );
+               $this->assertTrue( $this->isTextPresent( "Italic text" ) );
+       }
+
+       // Add internal link for a new page and verify output in the preview
+       public function testAddInternalLinkNewPage() {
+               $this->getExistingPage();
+               $this->clickEditLink();
+               $this->loadWikiEditor();
+               $this->clearWikiEditor();
+               $this->click( "//*[@id='mw-editbutton-link']" );
+               $this->clickShowPreviewBtn();
+               $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME );
+
+               // Verify internal link displayed on mediawiki preview
+               $source = $this->getText( "//*[@id='wikiPreview']/p/a" );
+               $correct = strstr( $source, "Link title" );
+               $this->assertEquals( $correct, true );
+
+               $this->click( SeleniumTestConstants::LINK_START . "Link title" );
+               $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME );
+
+               // Verify internal link open as a new page - editing mode
+               $source = $this->getText( "firstHeading" );
+               $correct = strstr( $source, "Editing Link title" );
+               $this->assertEquals( $correct, true );
+       }
+
+       // Add external link and verify output in the preview
+       public function testAddExternalLink() {
+               $this->getExistingPage();
+               $this->clickEditLink();
+               $this->loadWikiEditor();
+               $this->clearWikiEditor();
+               $this->click( "//*[@id='mw-editbutton-extlink']" );
+               $this->type( SeleniumTestConstants::TEXT_EDITOR, "[http://www.google.com Google]" );
+               $this->clickShowPreviewBtn();
+               $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME );
+
+               // Verify external links displayed on mediawiki preview
+               $source = $this->getText( "//*[@id='wikiPreview']/p/a" );
+               $correct = strstr( $source, "Google" );
+               $this->assertEquals( $correct, true );
+
+               $this->click( SeleniumTestConstants::LINK_START . "Google" );
+               $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME );
+
+               // Verify external link opens
+               $source = $this->getTitle();
+               $correct = strstr( $source, "Google" );
+               $this->assertEquals( $correct, true );
+       }
+
+       // Add level 2 headline and verify output in the preview
+       public function testAddLevel2HeadLine() {
+               $blnElementPresent = false;
+               $blnTextPresent = false;
+               $this->getExistingPage();
+               $this->clickEditLink();
+               $this->loadWikiEditor();
+               $this->clearWikiEditor();
+               $this->click( "mw-editbutton-headline" );
+               $this->clickShowPreviewBtn();
+               $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME );
+               $this->assertTrue( $this->isElementPresent( "//div[@id='wikiPreview']/h2" ) );
+
+               // Verify level 2 headline displayed on mediawiki preview
+               $source = $this->getText( "//*[@id='Headline_text']" );
+               $correct = strstr( $source, "Headline text" );
+               $this->assertEquals( $correct, true );
+       }
+
+       // Add text with ignore wiki format and verify output the preview
+       public function testAddNoWikiFormat() {
+               $this->getExistingPage();
+               $this->clickEditLink();
+               $this->loadWikiEditor();
+               $this->clearWikiEditor();
+               $this->click( "//*[@id='mw-editbutton-nowiki']" );
+               $this->clickShowPreviewBtn();
+               $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME );
+
+               // Verify ignore wiki format text displayed on mediawiki preview
+               $source = $this->getText( "//div[@id='wikiPreview']/p" );
+               $correct = strstr( $source, "Insert non-formatted text here" );
+               $this->assertEquals( $correct, true );
+       }
+
+       // Add signature and verify output in the preview
+       public function testAddUserSignature() {
+               $this->getExistingPage();
+               $this->clickEditLink();
+               $this->loadWikiEditor();
+               $this->clearWikiEditor();
+               $this->click( "mw-editbutton-signature" );
+               $this->clickShowPreviewBtn();
+               $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME );
+
+               // Verify signature displayed on mediawiki preview
+               $source = $this->getText( "//*[@id='wikiPreview']/p/a" );
+               $username = $this->getText( "//*[@id='pt-userpage']/a" );
+               $correct = strstr( $source, $username );
+               $this->assertEquals( $correct, true );
+       }
+
+       // Add horizontal line and verify output in the preview
+       public function testHorizontalLine() {
+               $this->getExistingPage();
+               $this->clickEditLink();
+               $this->loadWikiEditor();
+               $this->clearWikiEditor();
+               $this->click( "mw-editbutton-hr" );
+
+               $this->clickShowPreviewBtn();
+               $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME );
+
+               // Verify horizontal line displayed on mediawiki preview
+               $this->assertTrue( $this->isElementPresent( "//div[@id='wikiPreview']/hr" ) );
+               $this->deletePage( "new" );
+       }
 }
index f3302e5..19dc927 100644 (file)
@@ -6,7 +6,7 @@
  * @file
  * @ingroup Testing
  * Copyright (C) 2010 Nadeesha Weerasinghe <nadeesha@calcey.com>
- * http://www.calcey.com/ 
+ * http://www.calcey.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
  *
  */
 
-
 class AddNewPageTestCase extends SeleniumTestCase {
-
-    // Verify adding a new page
-    public function testAddNewPage() {
-        $newPage = "new";
-        $displayName = "New";
-        $this->open( $this->getUrl() .
-                '/index.php?title=Main_Page&action=edit' );
-        $this->type( "searchInput", $newPage );
-        $this->click( "searchGoButton" );
-        $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME );
-
-        // Verify 'Search results' text available
-        $source = $this->gettext( "firstHeading" );
-        $correct = strstr( $source, "Search results" );
-        $this->assertEquals( $correct, true);
-
-        // Verify  'Create the page "<page name>" on this wiki' text available
-        $source = $this->gettext( "//div[@id='bodyContent']/div[4]/p/b" );
-        $correct = strstr ( $source, "Create the page \"New\" on this wiki!" );
-        $this->assertEquals( $correct, true );
-
-        $this->click( SeleniumTestConstants::LINK_START.$displayName );
-        $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME );
-
-        $this->assertTrue($this->isElementPresent( SeleniumTestConstants::LINK_START."Create" ));
-        $this->type( "wpTextbox1", "add new test page" );
-        $this->click( SeleniumTestConstants::BUTTON_SAVE );
-
-        // Verify new page added
-        $source = $this->gettext( "firstHeading" );
-        $correct = strstr ( $source, $displayName );
-        $this->assertEquals( $correct, true );
-    }
+       // Verify adding a new page
+       public function testAddNewPage() {
+               $newPage = "new";
+               $displayName = "New";
+               $this->open( $this->getUrl() .
+                       '/index.php?title=Main_Page&action=edit' );
+               $this->type( "searchInput", $newPage );
+               $this->click( "searchGoButton" );
+               $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME );
+
+               // Verify 'Search results' text available
+               $source = $this->gettext( "firstHeading" );
+               $correct = strstr( $source, "Search results" );
+               $this->assertEquals( $correct, true );
+
+               // Verify  'Create the page "<page name>" on this wiki' text available
+               $source = $this->gettext( "//div[@id='bodyContent']/div[4]/p/b" );
+               $correct = strstr( $source, "Create the page \"New\" on this wiki!" );
+               $this->assertEquals( $correct, true );
+
+               $this->click( SeleniumTestConstants::LINK_START . $displayName );
+               $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME );
+
+               $this->assertTrue( $this->isElementPresent( SeleniumTestConstants::LINK_START . "Create" ) );
+               $this->type( "wpTextbox1", "add new test page" );
+               $this->click( SeleniumTestConstants::BUTTON_SAVE );
+
+               // Verify new page added
+               $source = $this->gettext( "firstHeading" );
+               $correct = strstr( $source, $displayName );
+               $this->assertEquals( $correct, true );
+       }
 }
index 5708bcf..e29f2c7 100644 (file)
@@ -6,7 +6,7 @@
  * @file
  * @ingroup Testing
  * Copyright (C) 2010 Nadeesha Weerasinghe <nadeesha@calcey.com>
- * http://www.calcey.com/ 
+ * http://www.calcey.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
  */
 
 Class CreateAccountTestCase extends SeleniumTestCase {
-
-    // Change these values before run the test
-    private $userName = "yourname4000";
-    private $password = "yourpass4000";
-
-    // Verify 'Log in/create account' link existance in Main page.
-    public function testMainPageLink() {
-
-        $this->click( "link=Log out" );
-        $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME );
-
-        $this->open( $this->getUrl().'/index.php?title=Main_Page' );
-        $this->assertTrue($this->isElementPresent( "link=Log in / create account" ));
-    }
-
-    // Verify 'Create an account' link existance in 'Log in / create account' Page.
-    public function testCreateAccountPageLink() {
-
-        $this->click( "link=Log out" );
-        $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME );
-
-        $this->open( $this->getUrl().'/index.php?title=Main_Page' );
-
-        // click Log in / create account link to open Log in / create account' page
-        $this->click( "link=Log in / create account" );
-        $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME );
-        $this->assertTrue($this->isElementPresent( "link=Create an account" ));
-    }
-
-    // Verify Create account
-    public function testCreateAccount() {
-
-        $this->click( "link=Log out" );
-        $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME );
-
-        $this->open( $this->getUrl().'/index.php?title=Main_Page' );
-
-        $this->click( "link=Log in / create account" );
-        $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME );
-
-        $this->click( "link=Create an account" );
-        $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME );
-
-        // Verify for blank user name
-        $this->type( "wpName2", "" );
-        $this->click( "wpCreateaccount" );
-        $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME );
-        $this->assertEquals( "Login error\n You have not specified a valid user name.",
-                $this->getText( "//div[@id='bodyContent']/div[4]" ));
-
-        // Verify for invalid user name
-        $this->type( "wpName2", "@" );
-        $this->click("wpCreateaccount" );
-        $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME );
-        $this->assertEquals( "Login error\n You have not specified a valid user name.",
-                $this->getText( "//div[@id='bodyContent']/div[4]" ));
-
-        // start of test for blank password
-        $this->type( "wpName2", $this->userName);
-        $this->type( "wpPassword2", "" );
-        $this->click( "wpCreateaccount" );
-        $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME );
-        $this->assertEquals( "Login error\n Passwords must be at least 1 character.",
-                $this->getText("//div[@id='bodyContent']/div[4]" ));
-
-        $this->type( "wpName2", $this->userName );
-        $this->type( "wpPassword2", $this->password );
-        $this->click( "wpCreateaccount" );
-        $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME );
-        $this->assertEquals( "Login error\n The passwords you entered do not match.",
-                $this->getText( "//div[@id='bodyContent']/div[4]" ));
-
-        $this->type( "wpName2", $this->userName );
-        $this->type( "wpPassword2", $this->password );
-        $this->type( "wpRetype", $this->password );
-        $this->click( "wpCreateaccount" );
-        $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME );
-
-        // Verify successful account creation for valid combination of 'Username', 'Password', 'Retype password'
-        $this->assertEquals( "Welcome, ".ucfirst( $this->userName )."!",
-                $this->getText( "Welcome,_".ucfirst( $this->userName )."!" ));
-    }
+       // Change these values before run the test
+       private $userName = "yourname4000";
+       private $password = "yourpass4000";
+
+       // Verify 'Log in/create account' link existance in Main page.
+       public function testMainPageLink() {
+
+               $this->click( "link=Log out" );
+               $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME );
+
+               $this->open( $this->getUrl() . '/index.php?title=Main_Page' );
+               $this->assertTrue( $this->isElementPresent( "link=Log in / create account" ) );
+       }
+
+       // Verify 'Create an account' link existance in 'Log in / create account' Page.
+       public function testCreateAccountPageLink() {
+
+               $this->click( "link=Log out" );
+               $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME );
+
+               $this->open( $this->getUrl() . '/index.php?title=Main_Page' );
+
+               // click Log in / create account link to open Log in / create account' page
+               $this->click( "link=Log in / create account" );
+               $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME );
+               $this->assertTrue( $this->isElementPresent( "link=Create an account" ) );
+       }
+
+       // Verify Create account
+       public function testCreateAccount() {
+
+               $this->click( "link=Log out" );
+               $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME );
+
+               $this->open( $this->getUrl() . '/index.php?title=Main_Page' );
+
+               $this->click( "link=Log in / create account" );
+               $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME );
+
+               $this->click( "link=Create an account" );
+               $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME );
+
+               // Verify for blank user name
+               $this->type( "wpName2", "" );
+               $this->click( "wpCreateaccount" );
+               $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME );
+               $this->assertEquals( "Login error\n You have not specified a valid user name.",
+                       $this->getText( "//div[@id='bodyContent']/div[4]" ) );
+
+               // Verify for invalid user name
+               $this->type( "wpName2", "@" );
+               $this->click( "wpCreateaccount" );
+               $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME );
+               $this->assertEquals( "Login error\n You have not specified a valid user name.",
+                       $this->getText( "//div[@id='bodyContent']/div[4]" ) );
+
+               // start of test for blank password
+               $this->type( "wpName2", $this->userName );
+               $this->type( "wpPassword2", "" );
+               $this->click( "wpCreateaccount" );
+               $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME );
+               $this->assertEquals( "Login error\n Passwords must be at least 1 character.",
+                       $this->getText( "//div[@id='bodyContent']/div[4]" ) );
+
+               $this->type( "wpName2", $this->userName );
+               $this->type( "wpPassword2", $this->password );
+               $this->click( "wpCreateaccount" );
+               $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME );
+               $this->assertEquals( "Login error\n The passwords you entered do not match.",
+                       $this->getText( "//div[@id='bodyContent']/div[4]" ) );
+
+               $this->type( "wpName2", $this->userName );
+               $this->type( "wpPassword2", $this->password );
+               $this->type( "wpRetype", $this->password );
+               $this->click( "wpCreateaccount" );
+               $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME );
+
+               // Verify successful account creation for valid combination of 'Username', 'Password', 'Retype password'
+               $this->assertEquals( "Welcome, " . ucfirst( $this->userName ) . "!",
+                       $this->getText( "Welcome,_" . ucfirst( $this->userName ) . "!" ) );
+       }
 }
 
index 9898188..eb25f8b 100644 (file)
@@ -6,7 +6,7 @@
  * @file
  * @ingroup Testing
  * Copyright (C) 2010 Nadeesha Weerasinghe <nadeesha@calcey.com>
- * http://www.calcey.com/ 
+ * http://www.calcey.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
  *
  */
 
-
 class DeletePageAdminTestCase extends SeleniumTestCase {
+       // Verify adding a new page
+       public function testDeletePage() {
 
-    // Verify adding a new page
-    public function testDeletePage() {
-
-       
-        $newPage = "new";
-        $displayName = "New";
+               $newPage = "new";
+               $displayName = "New";
 
-        $this->open( $this->getUrl().'/index.php?title=Main_Page' );
+               $this->open( $this->getUrl() . '/index.php?title=Main_Page' );
 
-        $this->type( "searchInput", $newPage );
-        $this->click( "searchGoButton" );
-        $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME );
-        $this->click( SeleniumTestConstants::LINK_START.$displayName );
-        $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME );
-        $this->type( SeleniumTestConstants::TEXT_EDITOR, $newPage." text" );
-        $this->click( SeleniumTestConstants::BUTTON_SAVE );
+               $this->type( "searchInput", $newPage );
+               $this->click( "searchGoButton" );
+               $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME );
+               $this->click( SeleniumTestConstants::LINK_START . $displayName );
+               $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME );
+               $this->type( SeleniumTestConstants::TEXT_EDITOR, $newPage . " text" );
+               $this->click( SeleniumTestConstants::BUTTON_SAVE );
 
-        $this->open( $this->getUrl() .
-                '/index.php?title=Main_Page&action=edit' );
-        $this->click( SeleniumTestConstants::LINK_START."Log out" );
-        $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME );
-        $this->click( SeleniumTestConstants::LINK_START."Log in / create account" );
-        $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME );
+               $this->open( $this->getUrl() .
+                       '/index.php?title=Main_Page&action=edit' );
+               $this->click( SeleniumTestConstants::LINK_START . "Log out" );
+               $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME );
+               $this->click( SeleniumTestConstants::LINK_START . "Log in / create account" );
+               $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME );
 
-        $this->type( "wpName1", $this->selenium->getUser() );
-        $this->type( "wpPassword1", $this->selenium->getPass() );
-        $this->click( "wpLoginAttempt" );
-        $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME );
-        $this->type( "searchInput", "new" );
-        $this->click( "searchGoButton");
-        $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME );
+               $this->type( "wpName1", $this->selenium->getUser() );
+               $this->type( "wpPassword1", $this->selenium->getPass() );
+               $this->click( "wpLoginAttempt" );
+               $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME );
+               $this->type( "searchInput", "new" );
+               $this->click( "searchGoButton" );
+               $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME );
 
-        // Verify  'Delete' link displayed
-        $source = $this->gettext( SeleniumTestConstants::LINK_START."Delete" );
-        $correct = strstr ( $source, "Delete" );
-        $this->assertEquals($correct, true );
+               // Verify  'Delete' link displayed
+               $source = $this->gettext( SeleniumTestConstants::LINK_START . "Delete" );
+               $correct = strstr( $source, "Delete" );
+               $this->assertEquals( $correct, true );
 
-        $this->click( SeleniumTestConstants::LINK_START."Delete" );
-        $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME );
+               $this->click( SeleniumTestConstants::LINK_START . "Delete" );
+               $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME );
 
-        // Verify 'Delete' button available
-        $this->assertTrue($this->isElementPresent( "wpConfirmB" ));
+               // Verify 'Delete' button available
+               $this->assertTrue( $this->isElementPresent( "wpConfirmB" ) );
 
-        $this->click( "wpConfirmB" );
-        $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME );
+               $this->click( "wpConfirmB" );
+               $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME );
 
-        // Verify  'Action complete' text displayed
-        $source = $this->gettext( "firstHeading" );
-        $correct = strstr ( $source, "Action complete" );
-        $this->assertEquals( $correct, true );
+               // Verify  'Action complete' text displayed
+               $source = $this->gettext( "firstHeading" );
+               $correct = strstr( $source, "Action complete" );
+               $this->assertEquals( $correct, true );
 
-        // Verify  '<Page Name> has been deleted. See deletion log for a record of recent deletions.' text displayed
-        $source = $this->gettext( "//div[@id='bodyContent']/p[1]" );
-        $correct = strstr ( $source, "\"New\" has been deleted. See deletion log for a record of recent deletions." );
-        $this->assertEquals( $correct, true );
-    }
+               // Verify  '<Page Name> has been deleted. See deletion log for a record of recent deletions.' text displayed
+               $source = $this->gettext( "//div[@id='bodyContent']/p[1]" );
+               $correct = strstr( $source, "\"New\" has been deleted. See deletion log for a record of recent deletions." );
+               $this->assertEquals( $correct, true );
+       }
 }
index 88d9cf9..81310b1 100644 (file)
@@ -6,7 +6,7 @@
  * @file
  * @ingroup Testing
  * Copyright (C) 2010 Nadeesha Weerasinghe <nadeesha@calcey.com>
- * http://www.calcey.com/ 
+ * http://www.calcey.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
  */
 
 class EmailPasswordTestCase extends SeleniumTestCase {
-
-    // change user name for each and every test (with in 24 hours)
-    private $userName = "test1";
-
-    public function testEmailPasswordButton() {
-
-        $this->click( SeleniumTestConstants::LINK_START."Log out" );
-        $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME );
-
-        $this->open( $this->getUrl().'/index.php?title=Main_Page' );
-
-        // click Log in / create account link to open Log in / create account' page
-        $this->click( SeleniumTestConstants::LINK_START."Log in / create account" );
-        $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME );
-        $this->assertTrue($this->isElementPresent( "wpMailmypassword" ));
-    }
-
-    // Verify Email password functionality
-    public function testEmailPasswordMessages() {
-
-        $this->click( SeleniumTestConstants::LINK_START."Log out" );
-        $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME );
-
-        $this->open( $this->getUrl().'/index.php?title=Main_Page' );
-
-        // click Log in / create account link to open Log in / create account' page
-        $this->click( SeleniumTestConstants::LINK_START."Log in / create account" );
-        $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME );
-
-        $this->type( "wpName1", "" );
-        $this->click( "wpMailmypassword" );
-        $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME );
-        $this->assertEquals( "Login error\n You have not specified a valid user name.",
-                $this->getText("//div[@id='bodyContent']/div[4]"));
-
-        $this->type( "wpName1", $this->userName );
-        $this->click( "wpMailmypassword" );
-        $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME );
-
-        //  Can not run on localhost
-        $this->assertEquals( "A new password has been sent to the e-mail address registered for ".ucfirst($this->userName).". Please log in again after you receive it.",
-                $this->getText("//div[@id='bodyContent']/div[4]" ));
-
-        $this->type( "wpName1", $this->userName );
-        $this->click( "wpMailmypassword" );
-        $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME );
-        $this->assertEquals( "Login error\n A password reminder has already been sent, within the last 24 hours. To prevent abuse, only one password reminder will be sent per 24 hours.",
-                $this->getText( "//div[@id='bodyContent']/div[4]" ));
-    }
+       // change user name for each and every test (with in 24 hours)
+       private $userName = "test1";
+
+       public function testEmailPasswordButton() {
+               $this->click( SeleniumTestConstants::LINK_START . "Log out" );
+               $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME );
+
+               $this->open( $this->getUrl() . '/index.php?title=Main_Page' );
+
+               // click Log in / create account link to open Log in / create account' page
+               $this->click( SeleniumTestConstants::LINK_START . "Log in / create account" );
+               $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME );
+               $this->assertTrue( $this->isElementPresent( "wpMailmypassword" ) );
+       }
+
+       // Verify Email password functionality
+       public function testEmailPasswordMessages() {
+               $this->click( SeleniumTestConstants::LINK_START . "Log out" );
+               $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME );
+
+               $this->open( $this->getUrl() . '/index.php?title=Main_Page' );
+
+               // click Log in / create account link to open Log in / create account' page
+               $this->click( SeleniumTestConstants::LINK_START . "Log in / create account" );
+               $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME );
+
+               $this->type( "wpName1", "" );
+               $this->click( "wpMailmypassword" );
+               $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME );
+               $this->assertEquals( "Login error\n You have not specified a valid user name.",
+                       $this->getText( "//div[@id='bodyContent']/div[4]" ) );
+
+               $this->type( "wpName1", $this->userName );
+               $this->click( "wpMailmypassword" );
+               $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME );
+
+               //  Can not run on localhost
+               $this->assertEquals( "A new password has been sent to the e-mail address registered for " . ucfirst( $this->userName ) . ". Please log in again after you receive it.",
+                       $this->getText( "//div[@id='bodyContent']/div[4]" ) );
+
+               $this->type( "wpName1", $this->userName );
+               $this->click( "wpMailmypassword" );
+               $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME );
+               $this->assertEquals( "Login error\n A password reminder has already been sent, within the last 24 hours. To prevent abuse, only one password reminder will be sent per 24 hours.",
+                       $this->getText( "//div[@id='bodyContent']/div[4]" ) );
+       }
 }
 
index 072c3cb..aeb2315 100644 (file)
@@ -6,7 +6,7 @@
  * @file
  * @ingroup Testing
  * Copyright (C) 2010 Nadeesha Weerasinghe <nadeesha@calcey.com>
- * http://www.calcey.com/ 
+ * http://www.calcey.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
  */
 
 class MediaWikiEditorConfig {
-
-    public static function getSettings(&$includeFiles, &$globalConfigs) {
-        $includes = array(
-                //files that needed to be included would go here
-                //commenting out because this does not exist
-                //'tests/selenium/suites/MediaWikiCommonFunction.php'
-        );
-        $configs = array(
-                'wgPageLoadTime' => "600000"
-        );
-        $includeFiles = array_merge( $includeFiles, $includes );
-        $globalConfigs = array_merge( $globalConfigs, $configs);
-        return true;
-    }
+       public static function getSettings( &$includeFiles, &$globalConfigs ) {
+               $includes = array(
+                       //files that needed to be included would go here
+                       //commenting out because this does not exist
+                       //'tests/selenium/suites/MediaWikiCommonFunction.php'
+               );
+               $configs = array(
+                       'wgPageLoadTime' => "600000"
+               );
+               $includeFiles = array_merge( $includeFiles, $includes );
+               $globalConfigs = array_merge( $globalConfigs, $configs );
+               return true;
+       }
 }
 
-
-
index c0aee9f..f9cfb7f 100644 (file)
@@ -1,18 +1,19 @@
 <?php
 
 class MediaWikiEditorTestSuite extends SeleniumTestSuite {
-    public function setUp() {
-        $this->setLoginBeforeTests( true );
-        parent::setUp();
-    }
-    public function addTests() {
-        $testFiles = array(
-                'tests/selenium/suites/AddNewPageTestCase.php',
-                'tests/selenium/suites/AddContentToNewPageTestCase.php',
-                'tests/selenium/suites/PreviewPageTestCase.php',
-                'tests/selenium/suites/SavePageTestCase.php',
-        );
-        parent::addTestFiles( $testFiles );
-    }
+       public function setUp() {
+               $this->setLoginBeforeTests( true );
+               parent::setUp();
+       }
+
+       public function addTests() {
+               $testFiles = array(
+                       'tests/selenium/suites/AddNewPageTestCase.php',
+                       'tests/selenium/suites/AddContentToNewPageTestCase.php',
+                       'tests/selenium/suites/PreviewPageTestCase.php',
+                       'tests/selenium/suites/SavePageTestCase.php',
+               );
+               parent::addTestFiles( $testFiles );
+       }
 }
 
index 5cd0a34..8993907 100644 (file)
@@ -5,6 +5,7 @@ class MediaWikiExtraTestSuite extends SeleniumTestSuite {
                $this->setLoginBeforeTests( true );
                parent::setUp();
        }
+
        public function addTests() {
                $testFiles = array(
                        'tests/selenium/suites/MyContributionsTestCase.php',
index 6b8fc97..4491afd 100644 (file)
@@ -50,7 +50,8 @@ class MediawikiCoreSmokeTestCase extends SeleniumTestCase {
                $this->waitForPageToLoad( 30000 );
 
                $this->assertSeleniumHTMLContains(
-                               '//h1[@class="firstHeading"]', "Wikipedia-logo-v2-de.png" );
+                       '//h1[@class="firstHeading"]', "Wikipedia-logo-v2-de.png"
+               );
 
                /*
                $this->open( $this->getUrl() . '/index.php?title=Image:'
index a9a9b4d..fc69e3c 100644 (file)
@@ -2,12 +2,12 @@
 /**
  * Stubs for now. We're going to start populating this test.
  */
-class MediawikiCoreSmokeTestSuite extends SeleniumTestSuite
-{
+class MediawikiCoreSmokeTestSuite extends SeleniumTestSuite {
        public function setUp() {
                $this->setLoginBeforeTests( false );
                parent::setUp();
-       } 
+       }
+
        public function addTests() {
                $testFiles = array(
                        'tests/selenium/suites/MediawikiCoreSmokeTestCase.php'
index 5263e7b..3964dc1 100644 (file)
@@ -6,7 +6,7 @@
  * @file
  * @ingroup Testing
  * Copyright (C) 2010 Nadeesha Weerasinghe <nadeesha@calcey.com>
- * http://www.calcey.com/ 
+ * http://www.calcey.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
  */
 
 class MovePageTestCase extends SeleniumTestCase {
-
-    // Verify move(rename) wiki page
-    public function testMovePage() {
-
-        $newPage = "mypage99";
-        $displayName = "Mypage99";
-
-        $this->open( $this->getUrl() .
-                '/index.php?title=Main_Page&action=edit' );
-        $this->type( "searchInput", $newPage );
-        $this->click( "searchGoButton" );
-        $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME );
-        $this->click( "link=".$displayName );
-        $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME );
-        $this->type( SeleniumTestConstants::TEXT_EDITOR, $newPage." text" );
-        $this->click( SeleniumTestConstants::BUTTON_SAVE );
-        $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME );
-
-        // Verify link 'Move' available
-        $this->assertTrue($this->isElementPresent( "link=Move" ));
-
-        $this->click( "link=Move" );
-        $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME );
-
-        // Verify correct page name displayed under 'Move Page' field
-        $this->assertEquals($displayName,
-                $this->getText("//table[@id='mw-movepage-table']/tbody/tr[1]/td[2]/strong/a"));
-        $movePageName = $this->getText( "//table[@id='mw-movepage-table']/tbody/tr[1]/td[2]/strong/a" );
-
-        // Verify 'To new title' field has current page name as the default name
-        $newTitle =  $this->getValue( "wpNewTitle" );
-        $correct = strstr( $movePageName , $newTitle  );
-        $this->assertEquals( $correct, true );
-
-        $this->type( "wpNewTitle", $displayName );
-        $this->click( "wpMove" );
-        $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME );
-
-        // Verify warning message for the same source and destination titles
-        $this->assertEquals( "Source and destination titles are the same; cannot move a page over itself.",
-                $this->getText("//div[@id='bodyContent']/p[4]/strong" ));
-
-        // Verify warning message for the blank title
-        $this->type( "wpNewTitle", "" );
-        $this->click( "wpMove" );
-        $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME );
-
-        // Verify warning message for the blank title
-        $this->assertEquals( "The requested page title was invalid, empty, or an incorrectly linked inter-language or inter-wiki title. It may contain one or more characters which cannot be used in titles.",
-                $this->getText( "//div[@id='bodyContent']/p[4]/strong" ));
-
-        //  Verify warning messages for the invalid titles
-        $this->type( "wpNewTitle", "# < > [ ] | { }" );
-        $this->click( "wpMove" );
-        $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME );
-        $this->assertEquals( "The requested page title was invalid, empty, or an incorrectly linked inter-language or inter-wiki title. It may contain one or more characters which cannot be used in titles.",
-                $this->getText( "//div[@id='bodyContent']/p[4]/strong" ));
-
-        $this->type( "wpNewTitle", $displayName."move" );
-        $this->click( "wpMove" );
-        $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME );
-
-        // Verify move success message displayed correctly
-        $this->assertEquals( "\"".$displayName."\" has been moved to \"".$displayName."move"."\"",
-                $this->getText( "//div[@id='bodyContent']/p[1]/b" ));
-
-        $this->type( "searchInput", $newPage."move" );
-        $this->click( "searchGoButton" );
-        $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME );
-
-        // Verify search using new page name
-        $this->assertEquals( $displayName."move", $this->getText( "firstHeading" ));
-
-        $this->type( "searchInput", $newPage );
-        $this->click( "searchGoButton" );
-        $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME );
-
-        // Verify search using old page name
-        $redirectPageName = $this->getText( "//*[@id='contentSub']" );
-        $this->assertEquals( "(Redirected from ".$displayName.")" , $redirectPageName );
-
-        // newpage delete
-        $this->deletePage( $newPage."move" );
-        $this->deletePage( $newPage );
-    }
+       // Verify move(rename) wiki page
+       public function testMovePage() {
+               $newPage = "mypage99";
+               $displayName = "Mypage99";
+
+               $this->open( $this->getUrl() .
+                       '/index.php?title=Main_Page&action=edit' );
+               $this->type( "searchInput", $newPage );
+               $this->click( "searchGoButton" );
+               $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME );
+               $this->click( "link=" . $displayName );
+               $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME );
+               $this->type( SeleniumTestConstants::TEXT_EDITOR, $newPage . " text" );
+               $this->click( SeleniumTestConstants::BUTTON_SAVE );
+               $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME );
+
+               // Verify link 'Move' available
+               $this->assertTrue( $this->isElementPresent( "link=Move" ) );
+
+               $this->click( "link=Move" );
+               $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME );
+
+               // Verify correct page name displayed under 'Move Page' field
+               $this->assertEquals( $displayName,
+                       $this->getText( "//table[@id='mw-movepage-table']/tbody/tr[1]/td[2]/strong/a" ) );
+               $movePageName = $this->getText( "//table[@id='mw-movepage-table']/tbody/tr[1]/td[2]/strong/a" );
+
+               // Verify 'To new title' field has current page name as the default name
+               $newTitle = $this->getValue( "wpNewTitle" );
+               $correct = strstr( $movePageName, $newTitle );
+               $this->assertEquals( $correct, true );
+
+               $this->type( "wpNewTitle", $displayName );
+               $this->click( "wpMove" );
+               $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME );
+
+               // Verify warning message for the same source and destination titles
+               $this->assertEquals( "Source and destination titles are the same; cannot move a page over itself.",
+                       $this->getText( "//div[@id='bodyContent']/p[4]/strong" ) );
+
+               // Verify warning message for the blank title
+               $this->type( "wpNewTitle", "" );
+               $this->click( "wpMove" );
+               $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME );
+
+               // Verify warning message for the blank title
+               $this->assertEquals( "The requested page title was invalid, empty, or an incorrectly linked inter-language or inter-wiki title. It may contain one or more characters which cannot be used in titles.",
+                       $this->getText( "//div[@id='bodyContent']/p[4]/strong" ) );
+
+               //  Verify warning messages for the invalid titles
+               $this->type( "wpNewTitle", "# < > [ ] | { }" );
+               $this->click( "wpMove" );
+               $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME );
+               $this->assertEquals( "The requested page title was invalid, empty, or an incorrectly linked inter-language or inter-wiki title. It may contain one or more characters which cannot be used in titles.",
+                       $this->getText( "//div[@id='bodyContent']/p[4]/strong" ) );
+
+               $this->type( "wpNewTitle", $displayName . "move" );
+               $this->click( "wpMove" );
+               $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME );
+
+               // Verify move success message displayed correctly
+               $this->assertEquals( "\"" . $displayName . "\" has been moved to \"" . $displayName . "move" . "\"",
+                       $this->getText( "//div[@id='bodyContent']/p[1]/b" ) );
+
+               $this->type( "searchInput", $newPage . "move" );
+               $this->click( "searchGoButton" );
+               $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME );
+
+               // Verify search using new page name
+               $this->assertEquals( $displayName . "move", $this->getText( "firstHeading" ) );
+
+               $this->type( "searchInput", $newPage );
+               $this->click( "searchGoButton" );
+               $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME );
+
+               // Verify search using old page name
+               $redirectPageName = $this->getText( "//*[@id='contentSub']" );
+               $this->assertEquals( "(Redirected from " . $displayName . ")", $redirectPageName );
+
+               // newpage delete
+               $this->deletePage( $newPage . "move" );
+               $this->deletePage( $newPage );
+       }
 }
 
index b8d2d48..730323d 100644 (file)
@@ -6,7 +6,7 @@
  * @file
  * @ingroup Testing
  * Copyright (C) 2010 Nadeesha Weerasinghe <nadeesha@calcey.com>
- * http://www.calcey.com/ 
+ * http://www.calcey.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
 require_once dirname( __DIR__ ) . '/SeleniumTestConstants.php';
 
 class MyContributionsTestCase extends SeleniumTestCase {
+       // Verify user contributions
+       public function testRecentChangesAvailability() {
+               $newPage = $this->createNewTestPage( "MyContributionsTest" );
 
-    // Verify user contributions
-    public function testRecentChangesAvailability() {
+               // Verify My contributions Link available
+               $this->assertTrue( $this->isElementPresent( "link=Contributions" ) );
 
-        $newPage = $this->createNewTestPage( "MyContributionsTest" );
-        
-        // Verify My contributions Link available
-        $this->assertTrue($this->isElementPresent( "link=Contributions" ));
 
-        
-        $this->click( "link=Contributions" );
-        $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME );
+               $this->click( "link=Contributions" );
+               $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME );
 
-        // Verify recent page adding available on My Contributions list
-        $this->assertEquals( $newPage, $this->getText( "link=".$newPage ));
+               // Verify recent page adding available on My Contributions list
+               $this->assertEquals( $newPage, $this->getText( "link=" . $newPage ) );
 
-        $this->type( SeleniumTestConstants::INPUT_SEARCH_BOX, $newPage );
-        $this->click( SeleniumTestConstants::BUTTON_SEARCH );
-        $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME );
-        
-        $this->click( SeleniumTestConstants::LINK_EDIT );
-        $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME );
-        $this->type( SeleniumTestConstants::TEXT_EDITOR, $newPage . " text changed" );
-        $this->click( SeleniumTestConstants::BUTTON_SAVE );
-        $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME );
-        $this->click( "link=Contributions" );
-        $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME );
+               $this->type( SeleniumTestConstants::INPUT_SEARCH_BOX, $newPage );
+               $this->click( SeleniumTestConstants::BUTTON_SEARCH );
+               $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME );
 
-        // Verify recent page changes available on My Contributions
-        $this->assertTrue( $this->isTextPresent( $newPage ) );
-    }
+               $this->click( SeleniumTestConstants::LINK_EDIT );
+               $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME );
+               $this->type( SeleniumTestConstants::TEXT_EDITOR, $newPage . " text changed" );
+               $this->click( SeleniumTestConstants::BUTTON_SAVE );
+               $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME );
+               $this->click( "link=Contributions" );
+               $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME );
+
+               // Verify recent page changes available on My Contributions
+               $this->assertTrue( $this->isTextPresent( $newPage ) );
+       }
 }
 
index 998fab9..bc7c768 100644 (file)
@@ -6,7 +6,7 @@
  * @file
  * @ingroup Testing
  * Copyright (C) 2010 Nadeesha Weerasinghe <nadeesha@calcey.com>
- * http://www.calcey.com/ 
+ * http://www.calcey.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
 require_once dirname( __DIR__ ) . '/SeleniumTestConstants.php';
 
 class MyWatchListTestCase extends SeleniumTestCase {
-
-    // Verify user watchlist
-    public function testMyWatchlist() {
-
-        $pageName = $this->createNewTestPage( "MyWatchListTest", true );
-        // Verify link 'My Watchlist' available
-        $this->assertTrue( $this->isElementPresent( SeleniumTestConstants::LINK_START."Watchlist" ) );
-
-        $this->click( SeleniumTestConstants::LINK_START."Watchlist" );
-        $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME );
-
-        // Verify newly added page to the watchlist is available
-        $this->assertEquals( $pageName, $this->getText( SeleniumTestConstants::LINK_START.$pageName ));
-
-        $this->click( SeleniumTestConstants::LINK_START.$pageName );
-        $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME );
-        $this->click( SeleniumTestConstants::LINK_EDIT );
-        $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME );
-        $this->click( "wpWatchthis" );
-        $this->click( SeleniumTestConstants::BUTTON_SAVE );
-        $this->assertFalse( $this->isElementPresent( SeleniumTestConstants::LINK_START.$pageName ) );
-        //todo watch using the dropdown menu
-    }
+       // Verify user watchlist
+       public function testMyWatchlist() {
+               $pageName = $this->createNewTestPage( "MyWatchListTest", true );
+               // Verify link 'My Watchlist' available
+               $this->assertTrue( $this->isElementPresent( SeleniumTestConstants::LINK_START . "Watchlist" ) );
+
+               $this->click( SeleniumTestConstants::LINK_START . "Watchlist" );
+               $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME );
+
+               // Verify newly added page to the watchlist is available
+               $this->assertEquals( $pageName, $this->getText( SeleniumTestConstants::LINK_START . $pageName ) );
+
+               $this->click( SeleniumTestConstants::LINK_START . $pageName );
+               $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME );
+               $this->click( SeleniumTestConstants::LINK_EDIT );
+               $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME );
+               $this->click( "wpWatchthis" );
+               $this->click( SeleniumTestConstants::BUTTON_SAVE );
+               $this->assertFalse( $this->isElementPresent( SeleniumTestConstants::LINK_START . $pageName ) );
+               //todo watch using the dropdown menu
+       }
 }
 
index 256e354..e43ffa8 100644 (file)
@@ -1,16 +1,15 @@
 <?php
 
 class PageDeleteTestSuite extends SeleniumTestSuite {
-    public function setUp() {
-        $this->setLoginBeforeTests( true );
-        parent::setUp();
-    }
-    public function addTests() {
-        $testFiles = array(
-                'tests/selenium/suites/DeletePageAdminTestCase.php'
-        );
-        parent::addTestFiles( $testFiles );
-    }
-
+       public function setUp() {
+               $this->setLoginBeforeTests( true );
+               parent::setUp();
+       }
 
+       public function addTests() {
+               $testFiles = array(
+                       'tests/selenium/suites/DeletePageAdminTestCase.php'
+               );
+               parent::addTestFiles( $testFiles );
+       }
 }
index fe71ead..bde1b57 100644 (file)
@@ -6,7 +6,7 @@
  * @file
  * @ingroup Testing
  * Copyright (C) 2010 Nadeesha Weerasinghe <nadeesha@calcey.com>
- * http://www.calcey.com/ 
+ * http://www.calcey.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
  */
 
 class PageSearchTestCase extends SeleniumTestCase {
-
-    // Verify the functionality of the 'Go' button
-    public function testPageSearchBtnGo() {
-
-        $this->open( $this->getUrl() .
-                '/index.php?title=Main_Page&action=edit' );
-        $this->type( SeleniumTestConstants::INPUT_SEARCH_BOX, "calcey qa" );
-        $this->click( "searchGoButton" );
-        $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME );
-
-        // Verify  no page matched with the entered search text
-        $source = $this->gettext( "//div[@id='bodyContent']/div[4]/p/b" );
-        $correct = strstr ( $source, "Create the page \"Calcey qa\" on this wiki!" );
-        $this->assertEquals( $correct, true );
-
-        $this->click( "link=Calcey qa" );
-        $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME );
-
-        $this->type( SeleniumTestConstants::TEXT_EDITOR , "Calcey QA team" );
-        $this->click( "wpSave" );
-        $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME );
-
-    }
-
-    // Verify the functionality of the 'Search' button
-    public function testPageSearchBtnSearch() {
-
-        $this->open( $this->getUrl() .
-                '/index.php?title=Main_Page&action=edit' );
-        $this->type( SeleniumTestConstants::INPUT_SEARCH_BOX, "Calcey web" );
-        $this->click( SeleniumTestConstants::BUTTON_SEARCH );
-        $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME );
-
-        // Verify  no page is available as the search text
-        $source = $this->gettext( "//div[@id='bodyContent']/div[4]/p[2]/b" );
-        $correct = strstr ( $source, "Create the page \"Calcey web\" on this wiki!" );
-        $this->assertEquals( $correct, true );
-
-        $this->click( "link=Calcey web" );
-        $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME );
-
-        $this->type( SeleniumTestConstants::TEXT_EDITOR, "Calcey web team" );
-        $this->click( SeleniumTestConstants::BUTTON_SAVE );
-        $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME );
-
-        // Verify saved page is opened  when the exact page name is given
-        $this->type( SeleniumTestConstants::INPUT_SEARCH_BOX, "Calcey web" );
-        $this->click( SeleniumTestConstants::BUTTON_SEARCH );
-        $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME );
-
-        // Verify exact page matched with the entered search text using 'Search' button
-        $source = $this->getText( "//*[@id='bodyContent']/div[4]/p/b" );
-        $correct = strstr( $source, "There is a page named \"Calcey web\" on this wiki." );
-        $this->assertEquals( $correct, true );
-
-        // Verify resutls available when partial page name is entered as the search text
-        $this->type( SeleniumTestConstants::INPUT_SEARCH_BOX, "Calcey" );
-        $this->click( SeleniumTestConstants::BUTTON_SEARCH );
-        $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME );
-
-        //  Verify text avaialble in the search result under the page titles
-        if($this->isElementPresent( "Page_title_matches" )) {
-            $textPageTitle = $this->getText( "//*[@id='bodyContent']/div[4]/ul[1]/li[1]/div[1]/a" );
-            $this->assertContains( 'Calcey', $textPageTitle );
-        }
-
-        //  Verify text avaialble in the search result under the page text
-        if($this->isElementPresent( "Page_text_matches" )) {
-            $textPageText = $this->getText( "//*[@id='bodyContent']/div[4]/ul[2]/li[2]/div[2]/span" );
-            $this->assertContains( 'Calcey', $textPageText );
-        }
-        $this->deletePage("Calcey QA");
-        $this->deletePage("Calcey web");
-    }
+       // Verify the functionality of the 'Go' button
+       public function testPageSearchBtnGo() {
+
+               $this->open( $this->getUrl() .
+                       '/index.php?title=Main_Page&action=edit' );
+               $this->type( SeleniumTestConstants::INPUT_SEARCH_BOX, "calcey qa" );
+               $this->click( "searchGoButton" );
+               $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME );
+
+               // Verify  no page matched with the entered search text
+               $source = $this->gettext( "//div[@id='bodyContent']/div[4]/p/b" );
+               $correct = strstr( $source, "Create the page \"Calcey qa\" on this wiki!" );
+               $this->assertEquals( $correct, true );
+
+               $this->click( "link=Calcey qa" );
+               $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME );
+
+               $this->type( SeleniumTestConstants::TEXT_EDITOR, "Calcey QA team" );
+               $this->click( "wpSave" );
+               $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME );
+       }
+
+       // Verify the functionality of the 'Search' button
+       public function testPageSearchBtnSearch() {
+               $this->open( $this->getUrl() .
+                       '/index.php?title=Main_Page&action=edit' );
+               $this->type( SeleniumTestConstants::INPUT_SEARCH_BOX, "Calcey web" );
+               $this->click( SeleniumTestConstants::BUTTON_SEARCH );
+               $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME );
+
+               // Verify  no page is available as the search text
+               $source = $this->gettext( "//div[@id='bodyContent']/div[4]/p[2]/b" );
+               $correct = strstr( $source, "Create the page \"Calcey web\" on this wiki!" );
+               $this->assertEquals( $correct, true );
+
+               $this->click( "link=Calcey web" );
+               $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME );
+
+               $this->type( SeleniumTestConstants::TEXT_EDITOR, "Calcey web team" );
+               $this->click( SeleniumTestConstants::BUTTON_SAVE );
+               $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME );
+
+               // Verify saved page is opened  when the exact page name is given
+               $this->type( SeleniumTestConstants::INPUT_SEARCH_BOX, "Calcey web" );
+               $this->click( SeleniumTestConstants::BUTTON_SEARCH );
+               $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME );
+
+               // Verify exact page matched with the entered search text using 'Search' button
+               $source = $this->getText( "//*[@id='bodyContent']/div[4]/p/b" );
+               $correct = strstr( $source, "There is a page named \"Calcey web\" on this wiki." );
+               $this->assertEquals( $correct, true );
+
+               // Verify resutls available when partial page name is entered as the search text
+               $this->type( SeleniumTestConstants::INPUT_SEARCH_BOX, "Calcey" );
+               $this->click( SeleniumTestConstants::BUTTON_SEARCH );
+               $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME );
+
+               //  Verify text avaialble in the search result under the page titles
+               if ( $this->isElementPresent( "Page_title_matches" ) ) {
+                       $textPageTitle = $this->getText( "//*[@id='bodyContent']/div[4]/ul[1]/li[1]/div[1]/a" );
+                       $this->assertContains( 'Calcey', $textPageTitle );
+               }
+
+               //  Verify text avaialble in the search result under the page text
+               if ( $this->isElementPresent( "Page_text_matches" ) ) {
+                       $textPageText = $this->getText( "//*[@id='bodyContent']/div[4]/ul[2]/li[2]/div[2]/span" );
+                       $this->assertContains( 'Calcey', $textPageText );
+               }
+               $this->deletePage( "Calcey QA" );
+               $this->deletePage( "Calcey web" );
+       }
 }
index 32206b9..615c23c 100644 (file)
@@ -6,7 +6,7 @@
  * @file
  * @ingroup Testing
  * Copyright (C) 2010 Nadeesha Weerasinghe <nadeesha@calcey.com>
- * http://www.calcey.com/ 
+ * http://www.calcey.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
  */
 
 class PreviewPageTestCase extends SeleniumTestCase {
+       // Verify adding a new page
+       public function testPreviewPage() {
+               $wikiText = "Adding this page to test the \n Preview button functionality";
+               $newPage = "Test Preview Page";
+               $this->open( $this->getUrl() .
+                       '/index.php?title=Main_Page&action=edit' );
+               $this->getNewPage( $newPage );
+               $this->type( SeleniumTestConstants::TEXT_EDITOR, $wikiText . "" );
+               $this->assertTrue( $this->isElementPresent( "//*[@id='wpPreview']" ) );
 
-    // Verify adding a new page
-    public function testPreviewPage() {
-        $wikiText = "Adding this page to test the \n Preview button functionality";
-        $newPage =  "Test Preview Page";
-        $this->open( $this->getUrl() .
-                '/index.php?title=Main_Page&action=edit' );
-        $this->getNewPage( $newPage );
-        $this->type( SeleniumTestConstants::TEXT_EDITOR, $wikiText."" );
-        $this->assertTrue($this->isElementPresent( "//*[@id='wpPreview']" ));
+               $this->click( "wpPreview" );
 
-        $this->click( "wpPreview" );
+               // Verify saved page available
+               $source = $this->gettext( "firstHeading" );
+               $correct = strstr( $source, "Test Preview Page" );
+               $this->assertEquals( $correct, true );
 
-        // Verify saved page available
-        $source = $this->gettext( "firstHeading" );
-        $correct = strstr( $source, "Test Preview Page" );
-        $this->assertEquals( $correct, true);
-
-        // Verify page content previewed succesfully
-        $contentOfPreviewPage = $this->getText( "//*[@id='content']" );
-        $this->assertContains( $wikiText, $contentOfPreviewPage  );
-    }
+               // Verify page content previewed succesfully
+               $contentOfPreviewPage = $this->getText( "//*[@id='content']" );
+               $this->assertContains( $wikiText, $contentOfPreviewPage );
+       }
 }
index 310ff20..80eacc5 100644 (file)
@@ -6,7 +6,7 @@
  * @file
  * @ingroup Testing
  * Copyright (C) 2010 Nadeesha Weerasinghe <nadeesha@calcey.com>
- * http://www.calcey.com/ 
+ * http://www.calcey.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
  */
 
 class SavePageTestCase extends SeleniumTestCase {
-
-    // Verify adding a new page
-    public function testSavePage() {
-        $wikiText = "Adding this page to test the Save button functionality";
-        $newPage = "Test Save Page";
-
-        $this->open( $this->getUrl() .
-                '/index.php?title=Main_Page&action=edit' );
-        $this->getNewPage($newPage);
-        $this->type( SeleniumTestConstants::TEXT_EDITOR, $wikiText );
-
-        // verify 'Save' button available
-        $this->assertTrue($this->isElementPresent( SeleniumTestConstants::BUTTON_SAVE ));
-        $this->click( SeleniumTestConstants::BUTTON_SAVE );
-
-        // Verify saved page available
-        $source = $this->gettext( "firstHeading" );
-        $correct = strstr( $source, "Test Save Page" );
-
-        // Verify Saved page name displayed correctly
-        $this->assertEquals( $correct, true );
-
-        // Verify page content saved succesfully
-        $contentOfSavedPage = $this->getText( "//*[@id='content']" );
-        $this->assertContains( $wikiText, $contentOfSavedPage  );
-        $this->deletePage( $newPage );
-    }
+       // Verify adding a new page
+       public function testSavePage() {
+               $wikiText = "Adding this page to test the Save button functionality";
+               $newPage = "Test Save Page";
+
+               $this->open( $this->getUrl() .
+                       '/index.php?title=Main_Page&action=edit' );
+               $this->getNewPage( $newPage );
+               $this->type( SeleniumTestConstants::TEXT_EDITOR, $wikiText );
+
+               // verify 'Save' button available
+               $this->assertTrue( $this->isElementPresent( SeleniumTestConstants::BUTTON_SAVE ) );
+               $this->click( SeleniumTestConstants::BUTTON_SAVE );
+
+               // Verify saved page available
+               $source = $this->gettext( "firstHeading" );
+               $correct = strstr( $source, "Test Save Page" );
+
+               // Verify Saved page name displayed correctly
+               $this->assertEquals( $correct, true );
+
+               // Verify page content saved succesfully
+               $contentOfSavedPage = $this->getText( "//*[@id='content']" );
+               $this->assertContains( $wikiText, $contentOfSavedPage );
+               $this->deletePage( $newPage );
+       }
 }
index 54def35..a693511 100644 (file)
@@ -1,30 +1,30 @@
 <?php
 class SimpleSeleniumConfig {
-       
-       public static function getSettings(&$includeFiles, &$globalConfigs, &$resourceFiles) {
+
+       public static function getSettings( &$includeFiles, &$globalConfigs, &$resourceFiles ) {
                global $IP;
                $includes = array(
                        //files that needed to be included would go here
                );
                $configs = array(
-                       'wgDBprefix'        => 'mw_',
-                       'wgDBTableOptions'  => 'ENGINE=InnoDB, DEFAULT CHARSET=binary',
-                       'wgDBmysql5'        => 'false',
-                       'wgMainCacheType'   => 'CACHE_NONE',
+                       'wgDBprefix' => 'mw_',
+                       'wgDBTableOptions' => 'ENGINE=InnoDB, DEFAULT CHARSET=binary',
+                       'wgDBmysql5' => 'false',
+                       'wgMainCacheType' => 'CACHE_NONE',
                        'wgParserCacheType' => 'CACHE_NONE',
-                       'wgMemCachedServers'=> array(),
-                       'wgLanguageCode'    => 'en',
-                       'wgSitename'        => 'test_wiki',
-                       'wgDefaultSkin'     => 'chick'
+                       'wgMemCachedServers' => array(),
+                       'wgLanguageCode' => 'en',
+                       'wgSitename' => 'test_wiki',
+                       'wgDefaultSkin' => 'chick'
                );
                $resources = array(
                        'db' => "$IP/tests/selenium/data/SimpleSeleniumTestDB.sql",
                        'images' => "$IP/tests/selenium/data/SimpleSeleniumTestImages.zip"
                );
-               
+
                $includeFiles = array_merge( $includeFiles, $includes );
-               $globalConfigs = array_merge( $globalConfigs, $configs);
+               $globalConfigs = array_merge( $globalConfigs, $configs );
                $resourceFiles = array_merge( $resourceFiles, $resources );
-               return true; 
+               return true;
        }
-}
\ No newline at end of file
+}
index b87172e..14c9e6b 100644 (file)
@@ -24,7 +24,7 @@ class SimpleSeleniumTestCase extends SeleniumTestCase {
        public function testGlobalVariableForDefaultSkin() {
                $this->open( $this->getUrl() . '/index.php' );
                $bodyClass = $this->getAttribute( "//body/@class" );
-               $this-> assertContains('skin-chick', $bodyClass, 'Chick skin not set');
+               $this->assertContains( 'skin-chick', $bodyClass, 'Chick skin not set' );
        }
 
        /**
@@ -33,7 +33,7 @@ class SimpleSeleniumTestCase extends SeleniumTestCase {
        public function testDatabaseResourceLoadedCorrectly() {
                $this->open( $this->getUrl() . '/index.php/TestResources?action=purge' );
                $testString = $this->gettext( "//body//*[@id='firstHeading']" );
-               $this-> assertEquals('TestResources', $testString, 'Article that should be present in the test db was not found.');
+               $this->assertEquals( 'TestResources', $testString, 'Article that should be present in the test db was not found.' );
        }
 
 }
index 2e0c4ee..446836a 100644 (file)
@@ -1,6 +1,6 @@
 <?php
 /**
- * Sample test suite. 
+ * Sample test suite.
  * Two ways to configure MW for these tests
  * 1) If you are running multiple test suites, add the following in LocalSettings.php
  * require_once("tests/selenium/SimpleSeleniumConfig.php");
@@ -9,12 +9,12 @@
  * 2) Add the following to your Localsettings.php
  * $wgDefaultSkin = 'chick';
  */
-class SimpleSeleniumTestSuite extends SeleniumTestSuite
-{
+class SimpleSeleniumTestSuite extends SeleniumTestSuite {
        public function setUp() {
                $this->setLoginBeforeTests( false );
                parent::setUp();
-       } 
+       }
+
        public function addTests() {
                $testFiles = array(
                        'selenium/suites/SimpleSeleniumTestCase.php'
index 3ceb3a9..a68ea97 100644 (file)
@@ -6,7 +6,7 @@
  * @file
  * @ingroup Testing
  * Copyright (C) 2010 Nadeesha Weerasinghe <nadeesha@calcey.com>
- * http://www.calcey.com/ 
+ * http://www.calcey.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
  */
 
 class UserPreferencesTestCase extends SeleniumTestCase {
-
-    // Verify user information
-    public function testUserInfoDisplay() {
-
-        $this->open( $this->getUrl() .
-                '/index.php?title=Main_Page&action=edit' );
-        $this->click( SeleniumTestConstants::LINK_START."My preferences" );
-        $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME );
-
-        // Verify correct username displayed in User Preferences
-        $this->assertEquals( $this->getText( "//li[@id='pt-userpage']/a" ),
-                $this->getText( "//table[@id='mw-htmlform-info']/tbody/tr[1]/td[2]" ));
-
-        // Verify existing Signature Displayed correctly
-        $this->assertEquals( $this->selenium->getUser(),
-                $this->getTable( "mw-htmlform-signature.0.1" ) );
-    }
-
-    // Verify change password
-    public function testChangePassword() {
-
-        $this->open( $this->getUrl() .
-                '/index.php?title=Main_Page&action=edit' );
-        $this->click( SeleniumTestConstants::LINK_START."My preferences" );
-        $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME );
-
-        $this->click( SeleniumTestConstants::LINK_START."Change password" );
-        $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME );
-
-        $this->type( "wpPassword", "12345" );
-        $this->type( "wpNewPassword", "54321" );
-        $this->type( "wpRetype", "54321" );
-        $this->click( "//input[@value='Change password']" );
-        $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME );
-
-        $this->assertEquals( "Preferences", $this->getText( "firstHeading" ));
-
-        $this->click( SeleniumTestConstants::LINK_START."Change password" );
-        $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME );
-
-        $this->type( "wpPassword", "54321" );
-        $this->type( "wpNewPassword", "12345" );
-        $this->type( "wpRetype", "12345" );
-        $this->click( "//input[@value='Change password']" );
-        $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME );
-        $this->assertEquals( "Preferences", $this->getText( "firstHeading" ));
-
-        $this->click( SeleniumTestConstants::LINK_START."Change password" );
-        $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME );
-
-        $this->type( "wpPassword", "54321" );
-        $this->type( "wpNewPassword", "12345" );
-        $this->type( "wpRetype", "12345" );
-        $this->click( "//input[@value='Change password']" );
-        $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME );
-    }
-
-    // Verify successful preferences save
-    public function testSuccessfullSave() {
-
-        $this->open( $this->getUrl() .
-                '/index.php?title=Main_Page&action=edit' );
-        $this->click( SeleniumTestConstants::LINK_START."My preferences" );
-        $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME );
-
-        $this->type( "mw-input-realname", "Test User" );
-        $this->click( "prefcontrol" );
-        $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME );
-
-        // Verify  "Your preferences have been saved." message
-        $this->assertEquals( "Your preferences have been saved.",
-                $this->getText( "//div[@id='bodyContent']/div[4]/strong/p" ));
-        $this->type( "mw-input-realname", "" );
-        $this->click( "prefcontrol" );
-        $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME );
-
-    }
-
-    // Verify change signature
-    public function testChangeSignature() {
-
-        $this->open( $this->getUrl() .
-                '/index.php?title=Main_Page&action=edit' );
-        $this->click( SeleniumTestConstants::LINK_START."My preferences" );
-        $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME );
-
-        $this->type( "mw-input-nickname", "TestSignature" );
-        $this->click( "prefcontrol" );
-        $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME );
-
-        // Verify change user signature
-        $this->assertEquals( "TestSignature", $this->getText( SeleniumTestConstants::LINK_START."TestSignature" ));
-        $this->type( "mw-input-nickname", "Test" );
-        $this->click( "prefcontrol" );
-        $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME );
-    }
-
-    // Verify change date format
-    public function testChangeDateFormatTimeZone() {
-
-        $this->open( $this->getUrl() .
-                '/index.php?title=Main_Page&action=edit' );
-
-        $this->click( SeleniumTestConstants::LINK_START."My preferences" );
-        $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME );
-        $this->click( SeleniumTestConstants::LINK_START."Date and time" );
-        $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME );
-
-        $this->click( "mw-input-date-dmy" );
-        $this->select( "mw-input-timecorrection", "label=Asia/Colombo" );
-        $this->click( "prefcontrol" );
-        $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME );
-
-        // Verify Date format and time zome saved
-        $this->assertEquals( "Your preferences have been saved.",
-                $this->getText( "//div[@id='bodyContent']/div[4]/strong/p" ));
-    }
-
-    // Verify restoring all default settings
-    public function testSetAllDefault() {
-
-        $this->open( $this->getUrl() .
-                '/index.php?title=Main_Page&action=edit' );
-        $this->click( SeleniumTestConstants::LINK_START."My preferences" );
-        $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME );
-
-        // Verify restoring all default settings
-        $this->assertEquals( "Restore all default settings",
-                $this->getText( SeleniumTestConstants::LINK_START."Restore all default settings" ));
-
-        $this->click("//*[@id='preferences']/div/a");
-        $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME );
-
-        // Verify 'This can not be undone' warning message displayed
-        $this->assertTrue($this->isElementPresent("//input[@value='Restore all default settings']"));
-
-        // Verify 'Restore all default settings' button available
-        $this->assertEquals("You can use this page to reset your preferences to the site defaults. This cannot be undone.",
-                $this->getText("//div[@id='bodyContent']/p"));
-
-        $this->click("//input[@value='Restore all default settings']");
-        $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME  );
-
-        // Verify preferences saved successfully
-        $this->assertEquals("Your preferences have been saved.",
-                $this->getText("//div[@id='bodyContent']/div[4]/strong/p"));
-    }
+       // Verify user information
+       public function testUserInfoDisplay() {
+
+               $this->open( $this->getUrl() .
+                       '/index.php?title=Main_Page&action=edit' );
+               $this->click( SeleniumTestConstants::LINK_START . "My preferences" );
+               $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME );
+
+               // Verify correct username displayed in User Preferences
+               $this->assertEquals( $this->getText( "//li[@id='pt-userpage']/a" ),
+                       $this->getText( "//table[@id='mw-htmlform-info']/tbody/tr[1]/td[2]" ) );
+
+               // Verify existing Signature Displayed correctly
+               $this->assertEquals( $this->selenium->getUser(),
+                       $this->getTable( "mw-htmlform-signature.0.1" ) );
+       }
+
+       // Verify change password
+       public function testChangePassword() {
+
+               $this->open( $this->getUrl() .
+                       '/index.php?title=Main_Page&action=edit' );
+               $this->click( SeleniumTestConstants::LINK_START . "My preferences" );
+               $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME );
+
+               $this->click( SeleniumTestConstants::LINK_START . "Change password" );
+               $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME );
+
+               $this->type( "wpPassword", "12345" );
+               $this->type( "wpNewPassword", "54321" );
+               $this->type( "wpRetype", "54321" );
+               $this->click( "//input[@value='Change password']" );
+               $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME );
+
+               $this->assertEquals( "Preferences", $this->getText( "firstHeading" ) );
+
+               $this->click( SeleniumTestConstants::LINK_START . "Change password" );
+               $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME );
+
+               $this->type( "wpPassword", "54321" );
+               $this->type( "wpNewPassword", "12345" );
+               $this->type( "wpRetype", "12345" );
+               $this->click( "//input[@value='Change password']" );
+               $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME );
+               $this->assertEquals( "Preferences", $this->getText( "firstHeading" ) );
+
+               $this->click( SeleniumTestConstants::LINK_START . "Change password" );
+               $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME );
+
+               $this->type( "wpPassword", "54321" );
+               $this->type( "wpNewPassword", "12345" );
+               $this->type( "wpRetype", "12345" );
+               $this->click( "//input[@value='Change password']" );
+               $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME );
+       }
+
+       // Verify successful preferences save
+       public function testSuccessfullSave() {
+
+               $this->open( $this->getUrl() .
+                       '/index.php?title=Main_Page&action=edit' );
+               $this->click( SeleniumTestConstants::LINK_START . "My preferences" );
+               $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME );
+
+               $this->type( "mw-input-realname", "Test User" );
+               $this->click( "prefcontrol" );
+               $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME );
+
+               // Verify  "Your preferences have been saved." message
+               $this->assertEquals( "Your preferences have been saved.",
+                       $this->getText( "//div[@id='bodyContent']/div[4]/strong/p" ) );
+               $this->type( "mw-input-realname", "" );
+               $this->click( "prefcontrol" );
+               $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME );
+       }
+
+       // Verify change signature
+       public function testChangeSignature() {
+               $this->open( $this->getUrl() .
+                       '/index.php?title=Main_Page&action=edit' );
+               $this->click( SeleniumTestConstants::LINK_START . "My preferences" );
+               $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME );
+
+               $this->type( "mw-input-nickname", "TestSignature" );
+               $this->click( "prefcontrol" );
+               $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME );
+
+               // Verify change user signature
+               $this->assertEquals( "TestSignature", $this->getText( SeleniumTestConstants::LINK_START . "TestSignature" ) );
+               $this->type( "mw-input-nickname", "Test" );
+               $this->click( "prefcontrol" );
+               $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME );
+       }
+
+       // Verify change date format
+       public function testChangeDateFormatTimeZone() {
+               $this->open( $this->getUrl() .
+                       '/index.php?title=Main_Page&action=edit' );
+
+               $this->click( SeleniumTestConstants::LINK_START . "My preferences" );
+               $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME );
+               $this->click( SeleniumTestConstants::LINK_START . "Date and time" );
+               $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME );
+
+               $this->click( "mw-input-date-dmy" );
+               $this->select( "mw-input-timecorrection", "label=Asia/Colombo" );
+               $this->click( "prefcontrol" );
+               $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME );
+
+               // Verify Date format and time zome saved
+               $this->assertEquals( "Your preferences have been saved.",
+                       $this->getText( "//div[@id='bodyContent']/div[4]/strong/p" ) );
+       }
+
+       // Verify restoring all default settings
+       public function testSetAllDefault() {
+               $this->open( $this->getUrl() .
+                       '/index.php?title=Main_Page&action=edit' );
+               $this->click( SeleniumTestConstants::LINK_START . "My preferences" );
+               $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME );
+
+               // Verify restoring all default settings
+               $this->assertEquals( "Restore all default settings",
+                       $this->getText( SeleniumTestConstants::LINK_START . "Restore all default settings" ) );
+
+               $this->click( "//*[@id='preferences']/div/a" );
+               $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME );
+
+               // Verify 'This can not be undone' warning message displayed
+               $this->assertTrue( $this->isElementPresent( "//input[@value='Restore all default settings']" ) );
+
+               // Verify 'Restore all default settings' button available
+               $this->assertEquals( "You can use this page to reset your preferences to the site defaults. This cannot be undone.",
+                       $this->getText( "//div[@id='bodyContent']/p" ) );
+
+               $this->click( "//input[@value='Restore all default settings']" );
+               $this->waitForPageToLoad( SeleniumTestConstants::WIKI_TEST_WAIT_TIME );
+
+               // Verify preferences saved successfully
+               $this->assertEquals( "Your preferences have been saved.",
+                       $this->getText( "//div[@id='bodyContent']/div[4]/strong/p" ) );
+       }
 }
 
index f1eb833..1e51d80 100644 (file)
@@ -59,7 +59,7 @@ class TestRecorder {
                if ( $success == $total ) {
                        print $this->term->color( 32 ) . "ALL TESTS PASSED!";
                } else {
-                       $failed = $total - $success ;
+                       $failed = $total - $success;
                        print $this->term->color( 31 ) . "$failed tests failed!";
                }
 
@@ -69,10 +69,10 @@ class TestRecorder {
        }
 }
 
-class DbTestPreviewer extends TestRecorder  {
-       protected $lb;      // /< Database load balancer
-       protected $db;      // /< Database connection to the main DB
-       protected $curRun;  // /< run ID number for the current run
+class DbTestPreviewer extends TestRecorder {
+       protected $lb; // /< Database load balancer
+       protected $db; // /< Database connection to the main DB
+       protected $curRun; // /< run ID number for the current run
        protected $prevRun; // /< run ID number for the previous run, if any
        protected $results; // /< Result array
 
@@ -94,9 +94,9 @@ class DbTestPreviewer extends TestRecorder  {
        function start() {
                parent::start();
 
-               if ( ! $this->db->tableExists( 'testrun', __METHOD__ )
-                       || ! $this->db->tableExists( 'testitem', __METHOD__ ) )
-               {
+               if ( !$this->db->tableExists( 'testrun', __METHOD__ )
+                       || !$this->db->tableExists( 'testitem', __METHOD__ )
+               {
                        print "WARNING> `testrun` table not found in database.\n";
                        $this->prevRun = false;
                } else {
@@ -134,8 +134,8 @@ class DbTestPreviewer extends TestRecorder  {
 
                        foreach ( $res as $row ) {
                                if ( !$this->parent->regex
-                                       || preg_match( "/{$this->parent->regex}/i", $row->ti_name ) )
-                               {
+                                       || preg_match( "/{$this->parent->regex}/i", $row->ti_name )
+                               {
                                        $prevResults[$row->ti_name] = $row->ti_success;
                                }
                        }
@@ -195,34 +195,34 @@ class DbTestPreviewer extends TestRecorder  {
        private function getTestStatusInfo( $testname, $after ) {
                // If we're looking at a test that has just been removed, then say when it first appeared.
                if ( $after == 'n' ) {
-                       $changedRun = $this->db->selectField ( 'testitem',
+                       $changedRun = $this->db->selectField( 'testitem',
                                'MIN(ti_run)',
                                array( 'ti_name' => $testname ),
                                __METHOD__ );
-                       $appear = $this->db->selectRow ( 'testrun',
+                       $appear = $this->db->selectRow( 'testrun',
                                array( 'tr_date', 'tr_mw_version' ),
                                array( 'tr_id' => $changedRun ),
                                __METHOD__ );
 
                        return "First recorded appearance: "
-                                  . date( "d-M-Y H:i:s",  strtotime ( $appear->tr_date ) )
-                                  .  ", " . $appear->tr_mw_version;
+                               . date( "d-M-Y H:i:s", strtotime( $appear->tr_date ) )
+                               . ", " . $appear->tr_mw_version;
                }
 
                // Otherwise, this test has previous recorded results.
                // See when this test last had a different result to what we're seeing now.
                $conds = array(
-                       'ti_name'    => $testname,
+                       'ti_name' => $testname,
                        'ti_success' => ( $after == 'f' ? "1" : "0" ) );
 
                if ( $this->curRun ) {
-                       $conds[] = "ti_run != " . $this->db->addQuotes ( $this->curRun );
+                       $conds[] = "ti_run != " . $this->db->addQuotes( $this->curRun );
                }
 
-               $changedRun = $this->db->selectField ( 'testitem', 'MAX(ti_run)', $conds, __METHOD__ );
+               $changedRun = $this->db->selectField( 'testitem', 'MAX(ti_run)', $conds, __METHOD__ );
 
                // If no record of ever having had a different result.
-               if ( is_null ( $changedRun ) ) {
+               if ( is_null( $changedRun ) ) {
                        if ( $after == "f" ) {
                                return "Has never passed";
                        } else {
@@ -233,27 +233,26 @@ class DbTestPreviewer extends TestRecorder  {
                // Otherwise, we're looking at a test whose status has changed.
                // (i.e. it used to work, but now doesn't; or used to fail, but is now fixed.)
                // In this situation, give as much info as we can as to when it changed status.
-               $pre  = $this->db->selectRow ( 'testrun',
+               $pre = $this->db->selectRow( 'testrun',
                        array( 'tr_date', 'tr_mw_version' ),
                        array( 'tr_id' => $changedRun ),
                        __METHOD__ );
-               $post = $this->db->selectRow ( 'testrun',
+               $post = $this->db->selectRow( 'testrun',
                        array( 'tr_date', 'tr_mw_version' ),
-                       array( "tr_id > " . $this->db->addQuotes ( $changedRun ) ),
+                       array( "tr_id > " . $this->db->addQuotes( $changedRun ) ),
                        __METHOD__,
                        array( "LIMIT" => 1, "ORDER BY" => 'tr_id' )
                );
 
                if ( $post ) {
-                       $postDate = date( "d-M-Y H:i:s",  strtotime ( $post->tr_date  ) ) . ", {$post->tr_mw_version}";
+                       $postDate = date( "d-M-Y H:i:s", strtotime( $post->tr_date ) ) . ", {$post->tr_mw_version}";
                } else {
                        $postDate = 'now';
                }
 
                return ( $after == "f" ? "Introduced" : "Fixed" ) . " between "
-                               . date( "d-M-Y H:i:s",  strtotime ( $pre->tr_date ) ) .  ", " . $pre->tr_mw_version
-                               . " and $postDate";
-
+                       . date( "d-M-Y H:i:s", strtotime( $pre->tr_date ) ) . ", " . $pre->tr_mw_version
+                       . " and $postDate";
        }
 
        /**
@@ -264,10 +263,9 @@ class DbTestPreviewer extends TestRecorder  {
                $this->lb->closeAll();
                parent::end();
        }
-
 }
 
-class DbTestRecorder extends DbTestPreviewer  {
+class DbTestRecorder extends DbTestPreviewer {
        var $version;
 
        /**
@@ -277,9 +275,9 @@ class DbTestRecorder extends DbTestPreviewer  {
        function start() {
                $this->db->begin( __METHOD__ );
 
-               if ( ! $this->db->tableExists( 'testrun' )
-                       || ! $this->db->tableExists( 'testitem' ) )
-               {
+               if ( !$this->db->tableExists( 'testrun' )
+                       || !$this->db->tableExists( 'testitem' )
+               {
                        print "WARNING> `testrun` table not found in database. Trying to create table.\n";
                        $this->db->sourceFile( $this->db->patchPath( 'patch-testrun.sql' ) );
                        echo "OK, resuming.\n";
@@ -289,18 +287,18 @@ class DbTestRecorder extends DbTestPreviewer  {
 
                $this->db->insert( 'testrun',
                        array(
-                               'tr_date'        => $this->db->timestamp(),
-                               'tr_mw_version'  => $this->version,
+                               'tr_date' => $this->db->timestamp(),
+                               'tr_mw_version' => $this->version,
                                'tr_php_version' => phpversion(),
-                               'tr_db_version'  => $this->db->getServerVersion(),
-                               'tr_uname'       => php_uname()
+                               'tr_db_version' => $this->db->getServerVersion(),
+                               'tr_uname' => php_uname()
                        ),
                        __METHOD__ );
-                       if ( $this->db->getType() === 'postgres' ) {
-                               $this->curRun = $this->db->currentSequenceValue( 'testrun_id_seq' );
-                       } else {
-                               $this->curRun = $this->db->insertId();
-                       }
+               if ( $this->db->getType() === 'postgres' ) {
+                       $this->curRun = $this->db->currentSequenceValue( 'testrun_id_seq' );
+               } else {
+                       $this->curRun = $this->db->insertId();
+               }
        }
 
        /**
@@ -314,8 +312,8 @@ class DbTestRecorder extends DbTestPreviewer  {
 
                $this->db->insert( 'testitem',
                        array(
-                               'ti_run'     => $this->curRun,
-                               'ti_name'    => $test,
+                               'ti_run' => $this->curRun,
+                               'ti_name' => $test,
                                'ti_success' => $result ? 1 : 0,
                        ),
                        __METHOD__ );
@@ -328,7 +326,8 @@ class TestFileIterator implements Iterator {
        private $parserTest; /* An instance of ParserTest (parserTests.php) or MediaWikiParserTest (phpunit) */
        private $index = 0;
        private $test;
-       private $section = null; /** String|null: current test section being analyzed */
+       private $section = null;
+       /** String|null: current test section being analyzed */
        private $sectionData = array();
        private $lineNum;
        private $eof;
@@ -395,7 +394,7 @@ class TestFileIterator implements Iterator {
                                $this->section = strtolower( $matches[1] );
 
                                if ( $this->section == 'endarticle' ) {
-                                       $this->checkSection( 'text'    );
+                                       $this->checkSection( 'text' );
                                        $this->checkSection( 'article' );
 
                                        $this->parserTest->addArticle( ParserTest::chomp( $this->sectionData['article'] ), $this->sectionData['text'], $this->lineNum );
@@ -438,8 +437,8 @@ class TestFileIterator implements Iterator {
                                }
 
                                if ( $this->section == 'end' ) {
-                                       $this->checkSection( 'test'   );
-                                       $this->checkSection( 'input'  );
+                                       $this->checkSection( 'test' );
+                                       $this->checkSection( 'input' );
                                        $this->checkSection( 'result' );
 
                                        if ( !isset( $this->sectionData['options'] ) ) {
@@ -451,7 +450,8 @@ class TestFileIterator implements Iterator {
                                        }
 
                                        if ( ( ( preg_match( '/\\bdisabled\\b/i', $this->sectionData['options'] ) && !$this->parserTest->runDisabled )
-                                                        || !preg_match( "/" . $this->parserTest->regex . "/i", $this->sectionData['test'] ) )  ) {
+                                               || !preg_match( "/" . $this->parserTest->regex . "/i", $this->sectionData['test'] ) )
+                                       ) {
                                                # disabled test
                                                $this->clearSection();
 
@@ -464,17 +464,17 @@ class TestFileIterator implements Iterator {
                                        # We are really going to run the test, run pending hooks and hooks function
                                        wfDebug( __METHOD__ . " unleashing delayed test for: {$this->sectionData['test']}" );
                                        $hooksResult = $delayedParserTest->unleash( $this->parserTest );
-                                       if( !$hooksResult ) {
+                                       if ( !$hooksResult ) {
                                                # Some hook reported an issue. Abort.
                                                return false;
                                        }
 
                                        $this->test = array(
-                                               'test'    => ParserTest::chomp( $this->sectionData['test']    ),
-                                               'input'   => ParserTest::chomp( $this->sectionData['input']   ),
-                                               'result'  => ParserTest::chomp( $this->sectionData['result']  ),
+                                               'test' => ParserTest::chomp( $this->sectionData['test'] ),
+                                               'input' => ParserTest::chomp( $this->sectionData['input'] ),
+                                               'result' => ParserTest::chomp( $this->sectionData['result'] ),
                                                'options' => ParserTest::chomp( $this->sectionData['options'] ),
-                                               'config'  => ParserTest::chomp( $this->sectionData['config']  ),
+                                               'config' => ParserTest::chomp( $this->sectionData['config'] ),
                                        );
 
                                        return true;
@@ -516,18 +516,18 @@ class TestFileIterator implements Iterator {
         * @param $token String: expected token that should have been mentionned before closing this section
         */
        private function checkSection( $token ) {
-               if( is_null( $this->section ) ) {
+               if ( is_null( $this->section ) ) {
                        throw new MWException( __METHOD__ . " can not verify a null section!\n" );
                }
 
-               if( !isset($this->sectionData[$token]) ) {
+               if ( !isset( $this->sectionData[$token] ) ) {
                        throw new MWException( sprintf(
                                "'%s' without '%s' at line %s of %s\n",
                                $this->section,
                                $token,
                                $this->lineNum,
                                $this->file
-                       ));
+                       ) );
                }
                return true;
        }
@@ -551,7 +551,7 @@ class DelayedParserTest {
         * Call to this will erase any hooks function that were pending.
         */
        public function reset() {
-               $this->hooks   = array();
+               $this->hooks = array();
                $this->fnHooks = array();
        }
 
@@ -560,23 +560,22 @@ class DelayedParserTest {
         * Should be the case if we found the parserTest is not disabled
         */
        public function unleash( &$parserTest ) {
-               if( !($parserTest instanceof ParserTest || $parserTest instanceof NewParserTest
-               ) ) {
+               if ( !( $parserTest instanceof ParserTest || $parserTest instanceof NewParserTest )     ) {
                        throw new MWException( __METHOD__ . " must be passed an instance of ParserTest or NewParserTest classes\n" );
                }
 
                # Trigger delayed hooks. Any failure will make us abort
-               foreach( $this->hooks as $hook ) {
+               foreach ( $this->hooks as $hook ) {
                        $ret = $parserTest->requireHook( $hook );
-                       if( !$ret ) {
+                       if ( !$ret ) {
                                return false;
                        }
                }
 
                # Trigger delayed function hooks. Any failure will make us abort
-               foreach( $this->fnHooks as $fnHook ) {
+               foreach ( $this->fnHooks as $fnHook ) {
                        $ret = $parserTest->requireFunctionHook( $fnHook );
-                       if( !$ret ) {
+                       if ( !$ret ) {
                                return false;
                        }
                }
@@ -592,6 +591,7 @@ class DelayedParserTest {
        public function requireHook( $hook ) {
                $this->hooks[] = $hook;
        }
+
        /**
         * Similar to ParserTest object but does not run anything
         * Use unleash() to really execute the hook function
index 7816860..ede30e6 100644 (file)
--- a/thumb.php
+++ b/thumb.php
@@ -224,7 +224,7 @@ function wfStreamThumb( array $params ) {
                        $response->header( 'Location: ' .
                                wfExpandUrl( $img->getThumbUrl( $thumbName ), PROTO_CURRENT ) );
                        $response->header( 'Expires: ' .
-                               gmdate( 'D, d M Y H:i:s', time() + 7*86400 ) . ' GMT' );
+                               gmdate( 'D, d M Y H:i:s', time() + 7 * 86400 ) . ' GMT' );
                        if ( $wgVaryOnXFP ) {
                                $varyHeader[] = 'X-Forwarded-Proto';
                        }
@@ -364,7 +364,7 @@ function wfThumbError( $status, $msg ) {
                $hostname = htmlspecialchars( wfHostname() );
                $debug = "<!-- $url -->\n<!-- $hostname -->\n";
        } else {
-               $debug = "";
+               $debug = '';
        }
        echo <<<EOT
 <html><head><title>Error generating thumbnail</title></head>