Merge "rdbms: do not treat SAVEPOINT and RELEASE SAVEPOINT as write queries"
authorjenkins-bot <jenkins-bot@gerrit.wikimedia.org>
Wed, 17 Oct 2018 16:40:16 +0000 (16:40 +0000)
committerGerrit Code Review <gerrit@wikimedia.org>
Wed, 17 Oct 2018 16:40:16 +0000 (16:40 +0000)
17 files changed:
INSTALL
RELEASE-NOTES-1.32
RELEASE-NOTES-1.33
UPGRADE
includes/OutputPage.php
includes/Revision.php
includes/ServiceWiring.php
includes/diff/DifferenceEngine.php
includes/parser/Parser.php
includes/parser/ParserFactory.php
includes/skins/Skin.php
tests/phpunit/documentation/ReleaseNotesTest.php
tests/phpunit/includes/OutputPageTest.php
tests/phpunit/includes/RevisionDbTestBase.php
tests/phpunit/includes/RevisionMcrDbTest.php
tests/phpunit/includes/RevisionMcrReadNewDbTest.php
tests/phpunit/includes/RevisionTest.php

diff --git a/INSTALL b/INSTALL
index d68342c..b6364e1 100644 (file)
--- a/INSTALL
+++ b/INSTALL
@@ -17,8 +17,8 @@ Required software:
 MediaWiki is developed and tested mainly on Unix/Linux platforms, but should
 work on Windows as well.
 
-Support for rendering mathematical formulas requires installing the Math extension,
-see https://www.mediawiki.org/wiki/Special:MyLanguage/Extension:Math
+Support for specialised content requires installing the relevant extension. For
+formulæ, see https://www.mediawiki.org/wiki/Special:MyLanguage/Extension:Math
 
 Don't forget to check the RELEASE-NOTES file...
 
@@ -67,8 +67,8 @@ available to download from the installer. Download this now, there is not a
 way (yet) to get it after you exit the installer. Place it in the main wiki
 directory, and the wiki should now be working.
 
-Once the wiki is set up, you should remove the mw-config directory (though it will
-refuse to config again if the wiki is set up).
+Once the wiki is set up, you should remove the mw-config directory (though it
+will refuse to config again if the wiki is set up).
 
 ----
 
index 9e71285..89c1f3a 100644 (file)
@@ -27,6 +27,15 @@ production.
   by default.
 * $wgGrantPermissions – A new grant group, 'editsiteconfig', is added for
   granting the above rights.
+* $wgDBDefaultGroup – A default database group for use by maintenance scripts.
+* $wgResourceLoaderEnableJSProfiler – This new configuration setting lets you
+  enable client-side profiling of JavaScript modules; it is off by default.
+* (T193868) $wgChangeTagsSchemaMigrationStage — This temporary configuration
+  setting allows sysadmins to gradually migrate the database table schema for
+  how change tags are stored.
+* (T199334) $wgTagStatisticsNewTable — This temporary configuration setting
+  allows sysadmins to enable the caching of Special:Tags via the new
+  change_tag_def table.
 
 ==== Changed configuration ====
 * $wgUseAjax – This setting, deprecated in 1.31, is now ignored.
@@ -44,6 +53,13 @@ production.
   MIGRATION_WRITE_NEW. It instead uses SCHEMA_COMPAT_WRITE_BOTH |
   SCHEMA_COMPAT_READ_OLD and SCHEMA_COMPAT_WRITE_BOTH | SCHEMA_COMPAT_READ_NEW
   for intermediate stages of migration.
+* $wgDBTableOptions – The default table options now use the binary charset. The
+  default was already overridden in the installer-generated LocalSettings.php,
+  and so is always set to binary after the installer UI option was removed. The
+  default value is only used when the installer installs an extension.
+* $wgPopularPasswordFile — The location of the default popular passwords file
+  has been moved to be in line with other non-PHP files used by libraries and
+  classes.
 
 ==== Removed configuration ====
 * $wgEnableAPI and $wgEnableWriteAPI – These settings, deprecated in 1.31,
@@ -57,6 +73,19 @@ production.
   message `emailsender`.
 * $wgTidyConfig – The experimental Html5Internal and Html5Depurate tidy drivers
   were removed. RemexHtml, which is the default, should be used instead.
+* (T181318) The $wgStyleVersion setting and its appendage to various script and
+  style URLs in OutputPage, deprecated in 1.31, was removed.
+* (T140807) The wgResourceLoaderLESSImportPaths configuration option was removed
+  from ResourceLoader. Instead, use `@import` statements in LESS to import
+  files directly from nearby directories within the same project.
+* (T140804) The wgResourceLoaderLESSVars configuration option, deprecated
+  since 1.30, was removed. Instead, to expose variables from PHP to LESS, use
+  the ResourceLoaderModule::getLessVars() method.
+* $wgResourceLoaderValidateStaticJS – This setting, unused since MediaWiki 1.18,
+  was removed.
+* Two temporary variables for deploying the feature of filters on change lists,
+  $wgStructuredChangeFiltersShowPreference introduced in MediaWiki 1.30 and
+  $wgStructuredChangeFiltersOnWatchlist in 1.31, were removed.
 
 === New features in 1.32 ===
 * (T112474) Generalized the ResourceLoader mechanism for overriding modules
@@ -269,8 +298,6 @@ because of Phabricator reports.
   removed. Use mediawiki.widgets.visibleLengthLimit instead.
 * The jquery.farbtastic module, unused since 1.18, was removed.
 * The 'jquery.expandableField' module, unused since 1.22, was removed.
-* (T181318) The $wgStyleVersion setting and its appendage to various script and
-  style URLs in OutputPage, deprecated in 1.31, was removed.
 * The hooks 'PreferencesFormPreSave' and 'PreferencesGetLegend' may provide
   any HTMLForm object rather than PreferencesForm.
 * The non namespaced TimestampException class, deprecated in 1.29, was removed.
@@ -280,12 +307,6 @@ because of Phabricator reports.
   The UtfNormal\Utils class from the utfnormal library should be used instead.
 * The deprecated UTF8_ and UNICODE_ constants were removed. The class constants
   from the UtfNormal\Constants class from the utfnormal library should be used
-* (T140807) The wgResourceLoaderLESSImportPaths configuration option was removed
-  from ResourceLoader. Instead, use `@import` statements in LESS to import
-  files directly from nearby directories within the same project.
-* (T140804) The wgResourceLoaderLESSVars configuration option, deprecated
-  since 1.30, was removed. Instead, to expose variables from PHP to LESS, use
-  the ResourceLoaderModule::getLessVars() method.
 * The protected methods PHPSessionHandler::returnSuccess() and returnFailure(),
   only needed for PHP5 compatibility, have been removed. It now uses the boolean
   values `true` and `false` respectively.
@@ -329,8 +350,8 @@ because of Phabricator reports.
   a no-op function since 1.30.
 * SpecialPageFactory::resetList() is a no-op.  Call overrideMwServices()
   instead.
-* MediaWiki no longer supports a StartProfiler.php file.
-  Define $wgProfiler via LocalSettings.php instead.
+* MediaWiki no longer supports a StartProfiler.php file. Instead, you can set
+  $wgProfiler and $wgEnableProfileInfo.
 * The mw.loader.addSource() is now considered a private method, and no longer
   supports the `id, url` signature. Use the `Object` parameter instead.
 * The backwards-compatibility code in HTMLForm to add a drop-down control to an
index 37f282d..59443df 100644 (file)
@@ -47,6 +47,11 @@ because of Phabricator reports.
 * …
 
 === Breaking changes in 1.33 ===
+* The parameteter $lang in DifferenceEngine::setTextLanguage must be of type
+  Language. Other types are deprecated since 1.32.
+* Skin::doEditSectionLink requires type Language for the parameter $lang.
+  The parameters $tooltip and $lang are mandatory. Omitting the parameters is
+  deprecated since 1.32.
 * …
 
 === Deprecations in 1.33 ===
diff --git a/UPGRADE b/UPGRADE
index 6b38b09..571b909 100644 (file)
--- a/UPGRADE
+++ b/UPGRADE
@@ -1,24 +1,23 @@
 This file provides an overview of the MediaWiki upgrade process. For help with
-specific problems, check
+specific problems, you should check:
 
-* the documentation at https://www.mediawiki.org/wiki/Special:MyLanguage/Help:Contents
+* the docs at https://www.mediawiki.org/wiki/Special:MyLanguage/Help:Contents ;
 * the mediawiki-l mailing list archive at
-  https://lists.wikimedia.org/pipermail/mediawiki-l/
+  https://lists.wikimedia.org/pipermail/mediawiki-l/ ; and
 * the bug tracker at https://phabricator.wikimedia.org/
 
-for information and workarounds to common issues.
+… for information and workarounds to common issues.
 
 == Overview ==
 
-Comprehensive documentation on upgrading to the latest version of the software
-is available at https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Upgrading
+We provide comprehensive documentation on upgrading to the latest version of the
+software at https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Upgrading.
 
 === Consult the release notes ===
 
 Before doing anything, stop and consult the release notes supplied with the new
 version of the software. These detail bug fixes, new features and functionality,
-and any particular points that may need to be noted during the upgrade
-procedure.
+and any particular points that may need to be noted during the upgrade process.
 
 === Backup first ===
 
@@ -27,19 +26,18 @@ you take a complete backup of your wiki database and files and verify it. While
 the upgrade scripts are somewhat robust, there is no guarantee that things will
 not fail, leaving the database in an inconsistent state.
 
-https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Backing_up_a_wiki provides an overview of
-the backup process. You should also refer to the documentation for your
-database management system for information on backing up a database, and to
+https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Backing_up_a_wiki is an
+overview of the backup process. You should also refer to the documentation for
+your database management system for information on backing up a database, and to
 your operating system documentation for information on making copies of files.
 
 === Perform the file upgrade ===
 
-Download the files for the new version of the software. These are available
-as a compressed "tar" archive from the Wikimedia Download Service
+Download the files for the new version of the software. These are available as a
+compressed "tar" archive from the Wikimedia Download Service
 (https://releases.wikimedia.org/mediawiki/).
 
-You can also obtain the new files directly from our Git source code
-repository.
+You can also obtain the new files directly from our Git source code repository.
 
 Replace the existing MediaWiki files with the new. You should preserve the
 LocalSettings.php file and the "extensions" and "images" directories.
@@ -50,15 +48,15 @@ deleted file archives, and any custom skins.
 
 === Perform the database upgrade ===
 
-As of 1.21, it is possible to separate schema changes (i.e. adding,
-dropping, or changing tables, fields, or indices) from all other
-database changes (e.g. populating fields).  If you need this
-capability, see "From the command line" below.
+As of 1.21, it is possible to separate schema changes (i.e. adding, dropping, or
+changing tables, fields, or indices) from all other database changes (e.g.
+populating fields). If you need this capability, see "From the command line"
+below.
 
-==== From the web ====
+==== From the Web ====
 
-If you browse to the web-based installation script (usually at
-/mw-config/index.php) from your wiki installation you can follow the script and
+If you browse to the Web-based installation script (usually at
+./mw-config/index.php) from your wiki installation you can follow the script and
 upgrade your database in place.
 
 ==== From the command line ====
@@ -68,19 +66,19 @@ update.php script to check and update the schema. This will insert missing
 tables, update existing tables, and move data around as needed. In most cases,
 this is successful and nothing further needs to be done.
 
-If you need to separate out the schema changes so they can be run
-by someone with more privileges, then you can use the --schema option
-to produce a text file with the necessary commands.  You can use
---schema, --noschema, $wgAllowSchemaUpdates as well as proper database
-permissions to enforce this separation.
+If you need to separate out the schema changes so they can be run by someone
+with more privileges, then you can use the --schema option to produce a text
+file with the necessary commands. You can use --schema, --noschema,
+$wgAllowSchemaUpdates as well as proper database permissions to enforce this
+separation.
 
 === Check configuration settings ===
 
-The names of configuration variables, and their default values and purposes,
-can change between release branches, e.g. $wgDisableUploads in 1.4 is replaced
-with $wgEnableUploads in later versions. When upgrading, consult the release
-notes to check for configuration changes which would alter the expected
-behavior of MediaWiki.
+The names of configuration variables, and their default values and purposes, can
+change between release branches, e.g. $wgDisableUploads in 1.4 is replaced with
+$wgEnableUploads in later versions. When upgrading, consult the release notes to
+check for configuration changes which would alter the expected behavior of
+MediaWiki.
 
 === Check installed extensions ===
 
@@ -94,48 +92,48 @@ LocalSettings.php
 
 It makes sense to test your wiki immediately following any kind of maintenance
 procedure, and especially after upgrading; check that page views and edits work
-normally and that special pages continue to function, etc. and correct errors
+normally, that special pages continue to function, etc., and correct any errors
 and quirks which reveal themselves.
 
 You should also test any extensions, and upgrade these if necessary.
 
 == Upgrading from 1.16 or earlier ==
 
-If you have a Chinese or Japanese wiki ($wgLanguageCode is set to one
-of "zh", "ja", or "yue") and you are using MySQL fulltext search, you
-will probably want to update the search index.
+If you have a Chinese or Japanese wiki ($wgLanguageCode is set to one of "zh",
+"ja", or "yue") and you are using MySQL fulltext search, you will probably want
+to update the search index.
 
-In the "maintenance" directory, run the updateDoubleWidthSearch.php
-script.  This will update the searchindex table for those pages that
-contain double-byte Latin characters.
+In the "maintenance" directory, run the updateDoubleWidthSearch.php script. This
+will update the searchindex table for those pages that contain double-byte Latin
+characters.
 
 == Upgrading from 1.10 or earlier ==
 
-If upgrading from before 1.11, and you are using a wiki as a commons
-repository, make sure that it is updated as well. Otherwise, errors may arise
-due to database schema changes.
+If upgrading from before 1.11, and you are using a wiki as a commons repository,
+make sure that it is updated as well. Otherwise, errors may arise due to
+database schema changes.
 
 == Upgrading from 1.8 or earlier ==
 
-MediaWiki 1.9 and later no longer keep default localized message text
-in the database; 'MediaWiki:'-namespace pages that do not exist in the
-database are simply transparently filled-in on demand.
+MediaWiki 1.9 and later no longer keep default localized message text in the
+database; 'MediaWiki:'-namespace pages that do not exist in the database are
+simply transparently filled-in on demand.
 
-The upgrade process will delete any 'MediaWiki:' pages which are left
-in the default state (last edited by 'MediaWiki default'). This may
-take a few moments, similar to the old initial setup.
+The upgrade process will delete any 'MediaWiki:' pages which are left in the
+default state (last edited by 'MediaWiki default'). This may take a few moments,
+similar to the old initial setup.
 
-Note that the large number of deletions may cause older edits to expire
-from the list on Special:Recentchanges, although the deletions themselves
-will be hidden by default. (Click "show bot edits" to list them.)
+Note that the large number of deletions may cause older edits to expire from the
+list on Special:Recentchanges, although the deletions themselves will be hidden
+by default. (Click "show bot edits" to list them.)
 
 See RELEASE-NOTES for more details about new and changed options.
 
 == Upgrading from 1.7 or earlier ==
 
-$wgDefaultUserOptions now contains all the defaults, not only overrides.
-If you're setting this as a complete array(), you may need to change it
-to set only specific items as recommended in DefaultSettings.php.
+$wgDefaultUserOptions now contains all the defaults, not only overrides. If you
+are setting this as a complete array(), you may need to change it to set only
+specific items as recommended in DefaultSettings.php.
 
 == Upgrading from 1.6 or earlier ==
 
@@ -146,58 +144,56 @@ new database fields are filled with data.
 
 == Upgrading from 1.5 or earlier ==
 
-Major changes have been made to the schema from 1.4.x. The updater
-has not been fully tested for all conditions, and might well break.
+Major changes have been made to the schema from 1.4.x. The updater has not been
+fully tested for all conditions, and might well break.
 
-On a large site, the schema update might take a long time. It might
-explode, or leave your database half-done or otherwise badly hurting.
+On a large site, the schema update might take a long time. It might explode, or
+leave your database half-done or otherwise badly hurting.
 
-Among other changes, note that Latin-1 encoding (ISO-8859-1) is
-no longer supported. Latin-1 wikis will need to be upgraded to
-UTF-8; an experimental command-line upgrade helper script,
-'upgrade1_5.php', can do this -- run it prior to 'update.php' or
-the web upgrader.
+Among other changes, note that Latin-1 encoding (ISO-8859-1) is no longer
+supported. Latin-1 wikis will need to be upgraded to UTF-8; an experimental
+command-line upgrade helper script, 'upgrade1_5.php', can do this -- run it
+prior to 'update.php' or the Web upgrader.
 
-NOTE that upgrade1_5.php does not work properly with recent versions
-of MediaWiki. If upgrading a 1.4.x wiki, you should upgrade to 1.5
-first.  upgrade1_5.php has been removed from MediaWiki 1.21.
+    NOTE that upgrade1_5.php does not work properly with recent versions of
+    MediaWiki. If upgrading a 1.4.x wiki, you should upgrade to 1.5 first.
+    upgrade1_5.php has been removed from MediaWiki 1.21.
 
-If you absolutely cannot make the UTF-8 upgrade work, you can try
-doing it by hand: dump your old database, convert the dump file
-using iconv as described here:
-http://portal.suse.com/sdb/en/2004/05/jbartsh_utf-8.html
-and then reimport it. You can also convert filenames using convmv,
-but note that the old directory hashes will no longer be valid,
-so you will also have to move them to new destinations.
+If you absolutely cannot make the UTF-8 upgrade work, you can try doing it by
+hand: dump your old database, convert the dump file using iconv as described
+here: http://portal.suse.com/sdb/en/2004/05/jbartsh_utf-8.html
+and then re-import it. You can also convert filenames using convmv, but note
+that the old directory hashes will no longer be valid, so you will also have to
+move them to new destinations.
 
 Message changes:
-* A number of additional UI messages have been changed from HTML to
-  wikitext, and will need to be manually fixed if customized.
+* A number of additional UI messages have been changed from HTML to wikitext,
+  and will need to be manually fixed if customized.
 
 === Configuration changes from 1.4.x: ===
 
 $wgDisableUploads has been replaced with $wgEnableUploads.
 
-$wgWhitelistAccount has been replaced by the 'createaccount' permission
-key in $wgGroupPermissions. To emulate the old effect of setting:
+$wgWhitelistAccount has been replaced by the 'createaccount' permission key in
+$wgGroupPermissions. To emulate the old effect of setting:
   $wgWhitelistAccount['user'] = 0;
 set:
   $wgGroupPermissions['*']['createaccount'] = false;
 
-$wgWhitelistEdit has been replaced by the 'edit' permission key.
-To emulate the old effect of setting:
+$wgWhitelistEdit has been replaced by the 'edit' permission key. To emulate the
+old effect of setting:
   $wgWhitelistEdit = true;
 set:
   $wgGroupPermissions['*']['edit'] = false;
 
-If $wgWhitelistRead is set, you must also disable the 'read' permission
-for it to take affect on anonymous users:
+If $wgWhitelistRead is set, you must also disable the 'read' permission for it
+to take affect on anonymous users:
   $wgWhitelistRead = array( "Main Page", "Special:Userlogin" );
   $wgGroupPermissions['*']['read'] = false;
 
-Note that you can disable/enable several other permissions by modifying
-this configuration array in your LocalSettings.php; see DefaultSettings.php
-for the complete default permission set.
+Note that you can disable/enable several other permissions by modifying this
+configuration array in your LocalSettings.php; see DefaultSettings.php for the
+complete default permission set.
 
 If using Memcached, you must enabled it differently now:
   $wgUseMemCached = true;
@@ -206,35 +202,31 @@ should be replaced with:
 
 == Upgrading from 1.4.2 or earlier ==
 
-1.4.3 has added new fields to the sitestats table. These fields are
-optional and help to speed Special:Statistics on large sites. If you
-choose not to run the database upgrades, everything will continue to
-work in 1.4.3.
+1.4.3 has added new fields to the sitestats table. These fields are optional and
+help to speed Special:Statistics on large sites. If you choose not to run the
+database upgrades, everything will continue to work in 1.4.3.
 
-You can apply the update by running maintenance/update.php, or
-manually run the SQL commands from this file:
+You can apply the update by running maintenance/update.php, or manually run the
+SQL commands from this file:
   maintenance/archives/patch-ss_total_articles.sql
 
-
 == Upgrading from 1.4rc1 or earlier betas ==
 
-The logging table has been altered from 1.4beta4 to 1.4beta5
-and again in 1.4.0 final. Copy in the new files and use the web
-installer to upgrade, or the command-line maintenance/update.php.
-
-If you cannot use the automated installers/updaters, you may
-update the table by manually running the SQL commands in these
-files:
-   maintenance/archives/patch-log_params.sql
-   maintenance/archives/patch-logging-title.sql
+The logging table has been altered from 1.4beta4 to 1.4beta5 and again in 1.4.0
+final. Copy in the new files and use the Web installer to upgrade, or the
+command-line maintenance/update.php.
 
+If you cannot use the automated installers/updaters, you may update the table by
+manually running the SQL commands in these files:
+  maintenance/archives/patch-log_params.sql
+  maintenance/archives/patch-logging-title.sql
 
 == Upgrading from 1.3 or earlier ==
 
 This should generally go smoothly.
 
-If you keep your LocalSettings.php, you may need to change the style paths
-to match the newly rearranged skin modules. Change these lines:
+If you keep your LocalSettings.php, you may need to change the style paths to
+match the newly rearranged skin modules. Change these lines:
   $wgStylePath        = "$wgScriptPath/stylesheets";
   $wgStyleDirectory   = "$IP/stylesheets";
   $wgLogo             = "$wgStylePath/images/wiki.png";
@@ -244,9 +236,9 @@ to this:
   $wgStyleDirectory   = "$IP/skins";
   $wgLogo             = "$wgStylePath/common/images/wiki.png";
 
-As well as new messages, the processing of some messages has changed.
-If you have customized them, please compare the new format using
-Special:Allmessages or the relevant LanguageXX.php files:
+As well as new messages, the processing of some messages has changed. If you
+have customized them, please compare the new format using Special:Allmessages or
+the relevant LanguageXX.php files:
 
 * copyrightwarning
 * dberrortext
@@ -262,45 +254,42 @@ Special:Allmessages or the relevant LanguageXX.php files:
 * showhideminor
 * unprotectedarticle
 
-Note that the 1.3 beta releases included a potential vulnerability if PHP
-is configured with register_globals on and the includes directory is
-served to the web. For general safety, turn register_globals *off* if you
-don't _really_ need it for another package.
-
-If your hosting provider turns it on and you can't turn it off yourself,
-send them a kind note explaining that it can expose their servers and their
-customers to attacks.
+Note that the 1.3 beta releases included a potential vulnerability if PHP is
+configured with register_globals on and the includes directory is served to the
+Web. For general safety, turn register_globals *off* if you don't _really_ need
+it for another package.
 
+If your hosting provider turns it on and you can't turn it off yourself, send
+them a kind note explaining that it can expose their servers and their customers
+to attacks.
 
 == Upgrading from 1.2 or earlier ==
 
-If you've been using the MediaWiki: namespace for custom page templates,
-note that things are a little different. The Template: namespace has been
-added which is more powerful -- templates can include parameters for
-instance.
-
-If you were using custom MediaWiki: entries for text inclusions, they
-will *not* automatically be moved to Template: entries at upgrade time.
-Be sure to go through and check that everything is working properly;
-you can move them manually or you can try using moveCustomMessages.php
-in maintenance/archives to do it automatically, but this might break things.
+If you've been using the MediaWiki: namespace for custom page templates, note
+that things are a little different. The Template: namespace has been added which
+is more powerful -- templates can include parameters for instance.
 
-Also, be sure to pick the correct character encoding -- some languages were
-only available in Latin-1 on 1.2.x and are now available for Unicode as well.
-If you want to upgrade an existing wiki from Latin-1 to Unicode you'll have
-to dump the database to SQL, run it through iconv or another conversion tool,
-and restore it. Sorry.
+If you were using custom MediaWiki: entries for text inclusions, they will *not*
+automatically be moved to Template: entries at upgrade time. Be sure to go
+through and check that everything is working properly; you can move them
+manually or you can try using moveCustomMessages.php in maintenance/archives to
+do it automatically, but this might break things.
 
+Also, be sure to pick the correct character encoding -- some languages were only
+available in Latin-1 on 1.2.x and are now available for Unicode as well. If you
+want to upgrade an existing wiki from Latin-1 to Unicode you'll have to dump the
+database to SQL, run it through iconv or another conversion tool, and restore
+it. Sorry.
 
 == Upgrading from 1.1 or earlier ==
 
 This is less thoroughly tested, but should work.
 
-You need to specify the *admin* database username and password to the
-installer in order for it to successfully upgrade the database structure.
-You may wish to manually change the GRANTs later.
+You need to specify the *admin* database username and password to the installer
+in order for it to successfully upgrade the database structure. You may wish to
+manually change the GRANTs later.
 
-If you have a very old database (earlier than organized MediaWiki releases
-in late August 2003) you may need to manually run some of the update SQL
-scripts in maintenance/archives before the installer is able to pick up
-with remaining updates.
+If you have a very old database (earlier than organized MediaWiki releases in
+late August 2003) you may need to manually run some of the update SQL scripts in
+maintenance/archives before the installer is able to pick up with remaining
+updates.
index cde92e8..a5f5fab 100644 (file)
@@ -1793,6 +1793,29 @@ class OutputPage extends ContextSource {
                $this->addWikiTextTitleInternal( $text, $title, $linestart, /*tidy*/true, /*interface*/true );
        }
 
+       /**
+        * Convert wikitext *in the user interface language* to HTML and
+        * add it to the buffer with a `<div class="$wrapperClass">`
+        * wrapper.  The result will not be language-converted, as user
+        * interface messages as already localized into a specific
+        * variant.  The $text will be parsed in start-of-line context.
+        * Output will be tidy.
+        *
+        * @param string $wrapperClass The class attribute value for the <div>
+        *   wrapper in the output HTML
+        * @param string $text Wikitext in the user interface language
+        * @since 1.32
+        */
+       public function wrapWikiTextAsInterface(
+               $wrapperClass, $text
+       ) {
+               $this->addWikiTextTitleInternal(
+                       $text, $this->getTitle(),
+                       /*linestart*/true, /*tidy*/true, /*interface*/true,
+                       $wrapperClass
+               );
+       }
+
        /**
         * Convert wikitext *in the page content language* to HTML and add
         * it to the buffer.  The result with be language-converted to the
@@ -1904,10 +1927,12 @@ class OutputPage extends ContextSource {
         *             since 1.32; all wikitext should be tidied.
         * @param bool $interface Whether it is an interface message
         *   (for example disables conversion)
+        * @param string $wrapperClass if not empty, wraps the output in
+        *   a `<div class="$wrapperClass">`
         * @private
         */
        private function addWikiTextTitleInternal(
-               $text, Title $title, $linestart, $tidy, $interface
+               $text, Title $title, $linestart, $tidy, $interface, $wrapperClass = null
        ) {
                global $wgParser;
 
@@ -1924,7 +1949,7 @@ class OutputPage extends ContextSource {
 
                $this->addParserOutput( $parserOutput, [
                        'enableSectionEditLinks' => false,
-                       'wrapperDivClass' => '',
+                       'wrapperDivClass' => $wrapperClass ?? '',
                ] );
        }
 
index e8fe8bd..6d1812a 100644 (file)
@@ -61,8 +61,13 @@ class Revision implements IDBAccessObject {
        /**
         * @return RevisionStore
         */
-       protected static function getRevisionStore() {
-               return MediaWikiServices::getInstance()->getRevisionStore();
+       protected static function getRevisionStore( $wiki = false ) {
+               if ( $wiki ) {
+                       return MediaWikiServices::getInstance()->getRevisionStoreFactory()
+                               ->getRevisionStore( $wiki );
+               } else {
+                       return MediaWikiServices::getInstance()->getRevisionStore();
+               }
        }
 
        /**
@@ -1036,10 +1041,17 @@ class Revision implements IDBAccessObject {
        /**
         * Get revision text associated with an old or archive row
         *
-        * Both the flags and the text field must be included. Including the old_id
+        * If the text field is not included, this uses RevisionStore to load the appropriate slot
+        * and return its serialized content. This is the default backwards-compatibility behavior
+        * when reading from the MCR aware database schema is enabled. For this to work, either
+        * the revision ID or the page ID must be included in the row.
+        *
+        * When using the old text field, the flags field must also be set. Including the old_id
         * field will activate cache usage as long as the $wiki parameter is not set.
         *
-        * @param stdClass $row The text data
+        * @deprecated since 1.32, use RevisionStore::newRevisionFromRow instead.
+        *
+        * @param stdClass $row The text data. If a falsy value is passed instead, false is returned.
         * @param string $prefix Table prefix (default 'old_')
         * @param string|bool $wiki The name of the wiki to load the revision text from
         *   (same as the wiki $row was loaded from) or false to indicate the local
@@ -1048,19 +1060,51 @@ class Revision implements IDBAccessObject {
         * @return string|false Text the text requested or false on failure
         */
        public static function getRevisionText( $row, $prefix = 'old_', $wiki = false ) {
+               global $wgMultiContentRevisionSchemaMigrationStage;
+
+               if ( !$row ) {
+                       return false;
+               }
+
                $textField = $prefix . 'text';
                $flagsField = $prefix . 'flags';
 
-               if ( isset( $row->$flagsField ) ) {
-                       $flags = explode( ',', $row->$flagsField );
+               if ( isset( $row->$textField ) ) {
+                       if ( !( $wgMultiContentRevisionSchemaMigrationStage & SCHEMA_COMPAT_WRITE_OLD ) ) {
+                               // The text field was read, but it's no longer being populated!
+                               // We could gloss over this by using the text when it's there and loading
+                               // if when it's not, but it seems preferable to complain loudly about a
+                               // query that is no longer guaranteed to work reliably.
+                               throw new LogicException(
+                                       'Cannot use ' . __METHOD__ . ' with the ' . $textField . ' field when'
+                                       . ' $wgMultiContentRevisionSchemaMigrationStage does not include'
+                                       . ' SCHEMA_COMPAT_WRITE_OLD. The field may not be populated for all revisions!'
+                               );
+                       }
+
+                       $text = $row->$textField;
                } else {
-                       $flags = [];
+                       // Missing text field, we are probably looking at the MCR-enabled DB schema.
+
+                       if ( !( $wgMultiContentRevisionSchemaMigrationStage & SCHEMA_COMPAT_WRITE_OLD ) ) {
+                               // This method should no longer be used with the new schema. Ideally, we
+                               // would already trigger a deprecation warning when SCHEMA_COMPAT_READ_NEW is set.
+                               wfDeprecated( __METHOD__ . ' (MCR without SCHEMA_COMPAT_WRITE_OLD)', '1.32' );
+                       }
+
+                       $store = self::getRevisionStore( $wiki );
+                       $rev = $prefix === 'ar_'
+                               ? $store->newRevisionFromArchiveRow( $row )
+                               : $store->newRevisionFromRow( $row );
+
+                       $content = $rev->getContent( SlotRecord::MAIN );
+                       return $content ? $content->serialize() : false;
                }
 
-               if ( isset( $row->$textField ) ) {
-                       $text = $row->$textField;
+               if ( isset( $row->$flagsField ) ) {
+                       $flags = explode( ',', $row->$flagsField );
                } else {
-                       return false;
+                       $flags = [];
                }
 
                $cacheKey = isset( $row->old_id )
index ed203ad..a1be225 100644 (file)
@@ -361,7 +361,8 @@ return [
                        $services->getMagicWordFactory(),
                        $services->getContentLanguage(),
                        wfUrlProtocols(),
-                       $services->getSpecialPageFactory()
+                       $services->getSpecialPageFactory(),
+                       $services->getMainConfig()
                );
        },
 
index f8f3d1c..8d0971e 100644 (file)
@@ -1665,11 +1665,8 @@ class DifferenceEngine extends ContextSource {
         * @param Language $lang
         * @since 1.19
         */
-       public function setTextLanguage( $lang ) {
-               if ( !$lang instanceof Language ) {
-                       wfDeprecated( __METHOD__ . ' with other type than Language for $lang', '1.32' );
-               }
-               $this->mDiffLang = wfGetLangObj( $lang );
+       public function setTextLanguage( Language $lang ) {
+               $this->mDiffLang = $lang;
        }
 
        /**
index dcb2c89..db04077 100644 (file)
@@ -273,25 +273,30 @@ class Parser {
        /** @var SpecialPageFactory */
        private $specialPageFactory;
 
+       /** @var Config */
+       private $siteConfig;
+
        /**
-        * @param array $conf See $wgParserConf documentation
+        * @param array $parserConf See $wgParserConf documentation
         * @param MagicWordFactory|null $magicWordFactory
         * @param Language|null $contLang Content language
         * @param ParserFactory|null $factory
         * @param string|null $urlProtocols As returned from wfUrlProtocols()
         * @param SpecialPageFactory|null $spFactory
+        * @param Config|null $siteConfig
         */
        public function __construct(
-               array $conf = [], MagicWordFactory $magicWordFactory = null, Language $contLang = null,
-               ParserFactory $factory = null, $urlProtocols = null, SpecialPageFactory $spFactory = null
+               array $parserConf = [], MagicWordFactory $magicWordFactory = null,
+               Language $contLang = null, ParserFactory $factory = null, $urlProtocols = null,
+               SpecialPageFactory $spFactory = null, Config $siteConfig = null
        ) {
-               $this->mConf = $conf;
+               $this->mConf = $parserConf;
                $this->mUrlProtocols = $urlProtocols ?? wfUrlProtocols();
                $this->mExtLinkBracketedRegex = '/\[(((?i)' . $this->mUrlProtocols . ')' .
                        self::EXT_LINK_ADDR .
                        self::EXT_LINK_URL_CLASS . '*)\p{Zs}*([^\]\\x00-\\x08\\x0a-\\x1F\\x{FFFD}]*?)\]/Su';
-               if ( isset( $conf['preprocessorClass'] ) ) {
-                       $this->mPreprocessorClass = $conf['preprocessorClass'];
+               if ( isset( $parserConf['preprocessorClass'] ) ) {
+                       $this->mPreprocessorClass = $parserConf['preprocessorClass'];
                } elseif ( wfIsHHVM() ) {
                        # Under HHVM Preprocessor_Hash is much faster than Preprocessor_DOM
                        $this->mPreprocessorClass = Preprocessor_Hash::class;
@@ -314,6 +319,7 @@ class Parser {
 
                $this->factory = $factory ?? $services->getParserFactory();
                $this->specialPageFactory = $spFactory ?? $services->getSpecialPageFactory();
+               $this->siteConfig = $siteConfig ?? MediaWikiServices::getInstance()->getMainConfig();
        }
 
        /**
@@ -542,8 +548,6 @@ class Parser {
         * @return string
         */
        protected function makeLimitReport() {
-               global $wgShowHostnames;
-
                $maxIncludeSize = $this->mOptions->getMaxIncludeSize();
 
                $cpuTime = $this->mOutput->getTimeSinceStart( 'cpu' );
@@ -584,7 +588,7 @@ class Parser {
                Hooks::run( 'ParserLimitReportPrepare', [ $this, $this->mOutput ] );
 
                $limitReport = "NewPP limit report\n";
-               if ( $wgShowHostnames ) {
+               if ( $this->siteConfig->get( 'ShowHostnames' ) ) {
                        $limitReport .= 'Parsed by ' . wfHostname() . "\n";
                }
                $limitReport .= 'Cached time: ' . $this->mOutput->getCacheTime() . "\n";
@@ -635,7 +639,7 @@ class Parser {
                $this->mOutput->setLimitReportData( 'limitreport-timingprofile', $profileReport );
 
                // Add other cache related metadata
-               if ( $wgShowHostnames ) {
+               if ( $this->siteConfig->get( 'ShowHostnames' ) ) {
                        $this->mOutput->setLimitReportData( 'cachereport-origin', wfHostname() );
                }
                $this->mOutput->setLimitReportData( 'cachereport-timestamp',
@@ -2153,8 +2157,6 @@ class Parser {
         * @private
         */
        public function replaceInternalLinks2( &$s ) {
-               global $wgExtraInterlanguageLinkPrefixes;
-
                static $tc = false, $e1, $e1_img;
                # the % is needed to support urlencoded titles as well
                if ( !$tc ) {
@@ -2359,7 +2361,7 @@ class Parser {
                                if (
                                        $iw && $this->mOptions->getInterwikiMagic() && $nottalk && (
                                                Language::fetchLanguageName( $iw, null, 'mw' ) ||
-                                               in_array( $iw, $wgExtraInterlanguageLinkPrefixes )
+                                               in_array( $iw, $this->siteConfig->get( 'ExtraInterlanguageLinkPrefixes' ) )
                                        )
                                ) {
                                        # T26502: filter duplicates
@@ -2541,9 +2543,6 @@ class Parser {
         * @return string
         */
        public function getVariableValue( $index, $frame = false ) {
-               global $wgSitename, $wgServer, $wgServerName;
-               global $wgArticlePath, $wgScriptPath, $wgStylePath;
-
                if ( is_null( $this->mTitle ) ) {
                        // If no title set, bad things are going to happen
                        // later. Title should always be set since this
@@ -2845,22 +2844,21 @@ class Parser {
                                $value = SpecialVersion::getVersion();
                                break;
                        case 'articlepath':
-                               return $wgArticlePath;
+                               return $this->siteConfig->get( 'ArticlePath' );
                        case 'sitename':
-                               return $wgSitename;
+                               return $this->siteConfig->get( 'Sitename' );
                        case 'server':
-                               return $wgServer;
+                               return $this->siteConfig->get( 'Server' );
                        case 'servername':
-                               return $wgServerName;
+                               return $this->siteConfig->get( 'ServerName' );
                        case 'scriptpath':
-                               return $wgScriptPath;
+                               return $this->siteConfig->get( 'ScriptPath' );
                        case 'stylepath':
-                               return $wgStylePath;
+                               return $this->siteConfig->get( 'StylePath' );
                        case 'directionmark':
                                return $pageLang->getDirMark();
                        case 'contentlanguage':
-                               global $wgLanguageCode;
-                               return $wgLanguageCode;
+                               return $this->siteConfig->get( 'LanguageCode' );
                        case 'pagelanguage':
                                $value = $pageLang->getCode();
                                break;
@@ -3803,9 +3801,7 @@ class Parser {
         * @return string
         */
        public function interwikiTransclude( $title, $action ) {
-               global $wgEnableScaryTranscluding, $wgTranscludeCacheExpiry;
-
-               if ( !$wgEnableScaryTranscluding ) {
+               if ( !$this->siteConfig->get( 'EnableScaryTranscluding' ) ) {
                        return wfMessage( 'scarytranscludedisabled' )->inContentLanguage()->text();
                }
 
@@ -3825,7 +3821,7 @@ class Parser {
                                ( $wikiId !== false ) ? $wikiId : 'external',
                                sha1( $url )
                        ),
-                       $wgTranscludeCacheExpiry,
+                       $this->siteConfig->get( 'TranscludeCacheExpiry' ),
                        function ( $oldValue, &$ttl ) use ( $url, $fname, $cache ) {
                                $req = MWHttpRequest::factory( $url, [], $fname );
 
@@ -4127,8 +4123,6 @@ class Parser {
         * @private
         */
        public function formatHeadings( $text, $origText, $isMain = true ) {
-               global $wgMaxTocLevel;
-
                # Inhibit editsection links if requested in the page
                if ( isset( $this->mDoubleUnderscores['noeditsection'] ) ) {
                        $maybeShowEditLink = false;
@@ -4199,6 +4193,7 @@ class Parser {
 
                $headlines = $numMatches !== false ? $matches[3] : [];
 
+               $maxTocLevel = $this->siteConfig->get( 'MaxTocLevel' );
                foreach ( $headlines as $headline ) {
                        $isTemplate = false;
                        $titleText = false;
@@ -4221,7 +4216,7 @@ class Parser {
                                # Increase TOC level
                                $toclevel++;
                                $sublevelCount[$toclevel] = 0;
-                               if ( $toclevel < $wgMaxTocLevel ) {
+                               if ( $toclevel < $maxTocLevel ) {
                                        $prevtoclevel = $toclevel;
                                        $toc .= Linker::tocIndent();
                                        $numVisible++;
@@ -4243,8 +4238,8 @@ class Parser {
                                if ( $i == 0 ) {
                                        $toclevel = 1;
                                }
-                               if ( $toclevel < $wgMaxTocLevel ) {
-                                       if ( $prevtoclevel < $wgMaxTocLevel ) {
+                               if ( $toclevel < $maxTocLevel ) {
+                                       if ( $prevtoclevel < $maxTocLevel ) {
                                                # Unindent only if the previous toc level was shown :p
                                                $toc .= Linker::tocUnindent( $prevtoclevel - $toclevel );
                                                $prevtoclevel = $toclevel;
@@ -4254,7 +4249,7 @@ class Parser {
                                }
                        } else {
                                # No change in level, end TOC line
-                               if ( $toclevel < $wgMaxTocLevel ) {
+                               if ( $toclevel < $maxTocLevel ) {
                                        $toc .= Linker::tocLineEnd();
                                }
                        }
@@ -4379,7 +4374,7 @@ class Parser {
                                ) . ' ' . $headline;
                        }
 
-                       if ( $enoughToc && ( !isset( $wgMaxTocLevel ) || $toclevel < $wgMaxTocLevel ) ) {
+                       if ( $enoughToc && ( !isset( $maxTocLevel ) || $toclevel < $maxTocLevel ) ) {
                                $toc .= Linker::tocLine( $linkAnchor, $tocline,
                                        $numbering, $toclevel, ( $isTemplate ? false : $sectionIndex ) );
                        }
@@ -4460,7 +4455,7 @@ class Parser {
                }
 
                if ( $enoughToc ) {
-                       if ( $prevtoclevel > 0 && $prevtoclevel < $wgMaxTocLevel ) {
+                       if ( $prevtoclevel > 0 && $prevtoclevel < $maxTocLevel ) {
                                $toc .= Linker::tocUnindent( $prevtoclevel - 1 );
                        }
                        $toc = Linker::tocList( $toc, $this->mOptions->getUserLangObj() );
@@ -4639,8 +4634,6 @@ class Parser {
         * @return string
         */
        public function getUserSig( &$user, $nickname = false, $fancySig = null ) {
-               global $wgMaxSigChars;
-
                $username = $user->getName();
 
                # If not given, retrieve from the user object.
@@ -4654,7 +4647,7 @@ class Parser {
 
                $nickname = $nickname == null ? $username : $nickname;
 
-               if ( mb_strlen( $nickname ) > $wgMaxSigChars ) {
+               if ( mb_strlen( $nickname ) > $this->siteConfig->get( 'MaxSigChars' ) ) {
                        $nickname = $username;
                        wfDebug( __METHOD__ . ": $username has overlong signature.\n" );
                } elseif ( $fancySig !== false ) {
@@ -5931,9 +5924,9 @@ class Parser {
                return '#' . Sanitizer::escapeIdForLink( $sectionName );
        }
 
-       private static function makeLegacyAnchor( $sectionName ) {
-               global $wgFragmentMode;
-               if ( isset( $wgFragmentMode[1] ) && $wgFragmentMode[1] === 'legacy' ) {
+       private function makeLegacyAnchor( $sectionName ) {
+               $fragmentMode = $this->config->get( 'FragmentMode' );
+               if ( isset( $fragmentMode[1] ) && $fragmentMode[1] === 'legacy' ) {
                        // ForAttribute() and ForLink() are the same for legacy encoding
                        $id = Sanitizer::escapeIdForAttribute( $sectionName, Sanitizer::ID_FALLBACK );
                } else {
@@ -5971,7 +5964,7 @@ class Parser {
                # Strip out wikitext links(they break the anchor)
                $text = $this->stripSectionName( $text );
                $sectionName = self::getSectionNameFromStrippedText( $text );
-               return self::makeLegacyAnchor( $sectionName );
+               return $this->makeLegacyAnchor( $sectionName );
        }
 
        /**
index 4238b27..eb05ace 100644 (file)
@@ -26,7 +26,7 @@ use MediaWiki\Special\SpecialPageFactory;
  */
 class ParserFactory {
        /** @var array */
-       private $conf;
+       private $parserConf;
 
        /** @var MagicWordFactory */
        private $magicWordFactory;
@@ -40,23 +40,28 @@ class ParserFactory {
        /** @var SpecialPageFactory */
        private $specialPageFactory;
 
+       /** @var Config */
+       private $siteConfig;
+
        /**
-        * @param array $conf See $wgParserConf documentation
+        * @param array $parserConf See $wgParserConf documentation
         * @param MagicWordFactory $magicWordFactory
         * @param Language $contLang Content language
         * @param string $urlProtocols As returned from wfUrlProtocols()
         * @param SpecialPageFactory $spFactory
+        * @param Config $siteConfig
         * @since 1.32
         */
        public function __construct(
-               array $conf, MagicWordFactory $magicWordFactory, Language $contLang, $urlProtocols,
-               SpecialPageFactory $spFactory
+               array $parserConf, MagicWordFactory $magicWordFactory, Language $contLang, $urlProtocols,
+               SpecialPageFactory $spFactory, Config $siteConfig
        ) {
-               $this->conf = $conf;
+               $this->parserConf = $parserConf;
                $this->magicWordFactory = $magicWordFactory;
                $this->contLang = $contLang;
                $this->urlProtocols = $urlProtocols;
                $this->specialPageFactory = $spFactory;
+               $this->siteConfig = $siteConfig;
        }
 
        /**
@@ -64,7 +69,7 @@ class ParserFactory {
         * @since 1.32
         */
        public function create() : Parser {
-               return new Parser( $this->conf, $this->magicWordFactory, $this->contLang, $this,
-                       $this->urlProtocols, $this->specialPageFactory );
+               return new Parser( $this->parserConf, $this->magicWordFactory, $this->contLang, $this,
+                       $this->urlProtocols, $this->specialPageFactory, $this->siteConfig );
        }
 }
index f545532..1889167 100644 (file)
@@ -1610,21 +1610,14 @@ abstract class Skin extends ContextSource {
         * @param string $section The designation of the section being pointed to,
         *   to be included in the link, like "&section=$section"
         * @param string|null $tooltip The tooltip to use for the link: will be escaped
-        *   and wrapped in the 'editsectionhint' message.
-        *   Not setting this parameter is deprecated.
-        * @param Language|string $lang Language object or language code string.
-        *   Type string is deprecated. Not setting this parameter is deprecated.
+        *   and wrapped in the 'editsectionhint' message
+        * @param Language $lang Language object
         * @return string HTML to use for edit link
         */
-       public function doEditSectionLink( Title $nt, $section, $tooltip = null, $lang = false ) {
+       public function doEditSectionLink( Title $nt, $section, $tooltip, Language $lang ) {
                // HTML generated here should probably have userlangattributes
                // added to it for LTR text on RTL pages
 
-               if ( !$lang instanceof Language ) {
-                       wfDeprecated( __METHOD__ . ' with other type than Language for $lang', '1.32' );
-                       $lang = wfGetLangObj( $lang );
-               }
-
                $attribs = [];
                if ( !is_null( $tooltip ) ) {
                        $attribs['title'] = $this->msg( 'editsectionhint' )->rawParams( $tooltip )
index ac100af..2789571 100644 (file)
@@ -30,25 +30,38 @@ class ReleaseNotesTest extends MediaWikiTestCase {
                );
 
                foreach ( $notesFiles as $index => $fileName ) {
-                       $file = file( $fileName, FILE_IGNORE_NEW_LINES );
+                       $this->assertFileLength( "Release Notes", $fileName );
+               }
 
-                       $this->assertFalse(
-                               !$file,
-                               "Release Notes file '$fileName' is inaccessible."
-                       );
+               // Also test the README and similar files
+               $otherFiles = [ "$IP/COPYING", "$IP/FAQ", "$IP/INSTALL", "$IP/README", "$IP/SECURITY" ];
 
-                       $lines = count( $file );
+               foreach ( $otherFiles as $index => $fileName ) {
+                       $this->assertFileLength( "Help", $fileName );
+               }
+       }
 
-                       for ( $i = 0; $i < $lines; $i++ ) {
-                               $line = $file[$i];
+       /**
+        */
+       private function assertFileLength( $type, $fileName ) {
+               $file = file( $fileName, FILE_IGNORE_NEW_LINES );
 
-                               $this->assertLessThanOrEqual(
-                                       // FILE_IGNORE_NEW_LINES drops the \n at the EOL, so max length is 80 not 81.
-                                       80,
-                                       mb_strlen( $line ),
-                                       "Release notes file '$fileName' line $i is longer than 80 chars:\n\t'$line'"
-                               );
-                       }
+               $this->assertFalse(
+                       !$file,
+                       "$type file '$fileName' is inaccessible."
+               );
+
+               $lines = count( $file );
+
+               for ( $i = 0; $i < $lines; $i++ ) {
+                       $line = $file[$i];
+
+                       $this->assertLessThanOrEqual(
+                               // FILE_IGNORE_NEW_LINES drops the \n at the EOL, so max length is 80 not 81.
+                               80,
+                               mb_strlen( $line ),
+                               "$type file '$fileName' line $i is longer than 80 chars:\n\t'$line'"
+                       );
                }
        }
 }
index 53e6f46..211169e 100644 (file)
@@ -1430,6 +1430,7 @@ class OutputPageTest extends MediaWikiTestCase {
         * @dataProvider provideAddWikiText
         * @covers OutputPage::addWikiText
         * @covers OutputPage::addWikiTextAsInterface
+        * @covers OutputPage::wrapWikiTextAsInterface
         * @covers OutputPage::addWikiTextAsContent
         * @covers OutputPage::addWikiTextWithTitle
         * @covers OutputPage::addWikiTextTitle
@@ -1545,6 +1546,21 @@ class OutputPageTest extends MediaWikiTestCase {
                                        '<div class="mw-editintro">' . "Some page\n</div>"
                                ],
                        ],
+                       'wrapWikiTextAsInterface' => [
+                               'Simple' => [
+                                       [ 'wrapperClass', 'text' ],
+                                       "<div class=\"wrapperClass\"><p>text\n</p></div>"
+                               ], 'Spurious </div>' => [
+                                       [ 'wrapperClass', 'text</div><div>more' ],
+                                       "<div class=\"wrapperClass\"><p>text</p><div>more\n</div></div>"
+                               ], 'Extra newlines would break <p> wrappers' => [
+                                       [ 'two classes', "1\n\n2\n\n3" ],
+                                       "<div class=\"two classes\"><p>1\n</p><p>2\n</p><p>3\n</p></div>"
+                               ], 'Other unclosed tags' => [
+                                       [ 'error', 'a<b>c<i>d' ],
+                                       "<div class=\"error\"><p>a<b>c<i>d\n</i></b></p></div>"
+                               ],
+                       ],
                ];
 
                // Test all the others on addWikiTextTitle as well
index cc166a3..e5e5551 100644 (file)
@@ -1601,4 +1601,38 @@ abstract class RevisionDbTestBase extends MediaWikiTestCase {
                $this->assertSame( $expected, $rev->getTextId() );
        }
 
+       public function provideGetRevisionText() {
+               yield [
+                       [ 'text' ]
+               ];
+       }
+
+       /**
+        * @dataProvider provideGetRevisionText
+        * @covers Revision::getRevisionText
+        */
+       public function testGetRevisionText( array $queryInfoOptions, array $queryInfoExtra = [] ) {
+               $rev = $this->testPage->getRevisionRecord();
+
+               $queryInfo = Revision::getQueryInfo( $queryInfoOptions );
+               $queryInfo['tables'] = array_merge( $queryInfo['tables'], $queryInfoExtra['tables'] ?? [] );
+               $queryInfo['fields'] = array_merge( $queryInfo['fields'], $queryInfoExtra['fields'] ?? [] );
+               $queryInfo['joins'] = array_merge( $queryInfo['joins'], $queryInfoExtra['joins'] ?? [] );
+
+               $conds = [ 'rev_id' => $rev->getId() ];
+               $row = $this->db->selectRow(
+                       $queryInfo['tables'],
+                       $queryInfo['fields'],
+                       $conds,
+                       __METHOD__,
+                       [],
+                       $queryInfo['joins']
+               );
+
+               $expected = $rev->getContent( SlotRecord::MAIN )->serialize();
+
+               $this->hideDeprecated( 'Revision::getRevisionText (MCR without SCHEMA_COMPAT_WRITE_OLD)' );
+               $this->assertSame( $expected, Revision::getRevisionText( $row ) );
+       }
+
 }
index d6ac35b..2da2275 100644 (file)
@@ -46,4 +46,10 @@ class RevisionMcrDbTest extends RevisionDbTestBase {
                yield [ $rec, 789 ];
        }
 
+       public function provideGetRevisionText() {
+               yield 'no text table' => [
+                       []
+               ];
+       }
+
 }
index df54f56..64de854 100644 (file)
@@ -42,4 +42,18 @@ class RevisionMcrReadNewDbTest extends RevisionDbTestBase {
                yield [ $rec, 789 ];
        }
 
+       public function provideGetRevisionText() {
+               yield 'no text table' => [
+                       []
+               ];
+               yield 'force text table' => [
+                       [],
+                       [
+                               'tables' => [ 'text' ],
+                               'fields' => [ 'old_id', 'old_text', 'old_flags', 'rev_text_id' ],
+                               'joins' => [ 'text' => [ 'INNER JOIN', 'old_id=rev_text_id' ] ]
+                       ]
+               ];
+       }
+
 }
index 5868b8d..c053104 100644 (file)
@@ -289,16 +289,6 @@ class RevisionTest extends MediaWikiTestCase {
                Wikimedia\restoreWarnings();
        }
 
-       public function provideGetRevisionText() {
-               yield 'Generic test' => [
-                       'This is a goat of revision text.',
-                       [
-                               'old_flags' => '',
-                               'old_text' => 'This is a goat of revision text.',
-                       ],
-               ];
-       }
-
        public function provideGetId() {
                yield [
                        [],
@@ -365,6 +355,20 @@ class RevisionTest extends MediaWikiTestCase {
                $this->assertSame( $expected, $rev->getParentId() );
        }
 
+       public function provideGetRevisionText() {
+               yield 'Generic test' => [
+                       'This is a goat of revision text.',
+                       (object)[
+                               'old_flags' => '',
+                               'old_text' => 'This is a goat of revision text.',
+                       ],
+               ];
+               yield 'garbage in, garbage out' => [
+                       false,
+                       false,
+               ];
+       }
+
        /**
         * @covers Revision::getRevisionText
         * @dataProvider provideGetRevisionText
@@ -372,13 +376,13 @@ class RevisionTest extends MediaWikiTestCase {
        public function testGetRevisionText( $expected, $rowData, $prefix = 'old_', $wiki = false ) {
                $this->assertEquals(
                        $expected,
-                       Revision::getRevisionText( (object)$rowData, $prefix, $wiki ) );
+                       Revision::getRevisionText( $rowData, $prefix, $wiki ) );
        }
 
        public function provideGetRevisionTextWithZlibExtension() {
                yield 'Generic gzip test' => [
                        'This is a small goat of revision text.',
-                       [
+                       (object)[
                                'old_flags' => 'gzip',
                                'old_text' => gzdeflate( 'This is a small goat of revision text.' ),
                        ],
@@ -397,7 +401,7 @@ class RevisionTest extends MediaWikiTestCase {
        public function provideGetRevisionTextWithZlibExtension_badData() {
                yield 'Generic gzip test' => [
                        'This is a small goat of revision text.',
-                       [
+                       (object)[
                                'old_flags' => 'gzip',
                                'old_text' => 'DEAD BEEF',
                        ],
@@ -481,7 +485,7 @@ class RevisionTest extends MediaWikiTestCase {
                        "Wiki est l'\xc3\xa9cole superieur !",
                        'fr',
                        'iso-8859-1',
-                       [
+                       (object)[
                                'old_flags' => 'utf-8',
                                'old_text' => "Wiki est l'\xc3\xa9cole superieur !",
                        ]
@@ -490,7 +494,7 @@ class RevisionTest extends MediaWikiTestCase {
                        "Wiki est l'\xc3\xa9cole superieur !",
                        'fr',
                        'iso-8859-1',
-                       [
+                       (object)[
                                'old_flags' => '',
                                'old_text' => "Wiki est l'\xe9cole superieur !",
                        ]
@@ -519,7 +523,7 @@ class RevisionTest extends MediaWikiTestCase {
                        "Wiki est l'\xc3\xa9cole superieur !",
                        'fr',
                        'iso-8859-1',
-                       [
+                       (object)[
                                'old_flags' => 'gzip,utf-8',
                                'old_text' => gzdeflate( "Wiki est l'\xc3\xa9cole superieur !" ),
                        ]
@@ -528,7 +532,7 @@ class RevisionTest extends MediaWikiTestCase {
                        "Wiki est l'\xc3\xa9cole superieur !",
                        'fr',
                        'iso-8859-1',
-                       [
+                       (object)[
                                'old_flags' => 'gzip',
                                'old_text' => gzdeflate( "Wiki est l'\xe9cole superieur !" ),
                        ]
@@ -729,13 +733,6 @@ class RevisionTest extends MediaWikiTestCase {
                );
        }
 
-       /**
-        * @covers Revision::getRevisionText
-        */
-       public function testGetRevisionText_returnsFalseWhenNoTextField() {
-               $this->assertFalse( Revision::getRevisionText( new stdClass() ) );
-       }
-
        public function provideTestGetRevisionText_returnsDecompressedTextFieldWhenNotExternal() {
                yield 'Just text' => [
                        (object)[ 'old_text' => 'SomeText' ],