Merge "Make statsd sampling rates configurable"
[lhc/web/wiklou.git] / includes / DefaultSettings.php
index 425e153..a990525 100644 (file)
@@ -75,7 +75,7 @@ $wgConfigRegistry = [
  * MediaWiki version number
  * @since 1.2
  */
-$wgVersion = '1.27.0-alpha';
+$wgVersion = '1.28.0-alpha';
 
 /**
  * Name of the site. It must be changed in LocalSettings.php
@@ -284,10 +284,10 @@ $wgLogo = false;
  *
  * @par Example:
  * @code
- * $wgLogoHD = array(
+ * $wgLogoHD = [
  *     "1.5x" => "path/to/1.5x_version.png",
  *     "2x" => "path/to/2x_version.png"
- * );
+ * ];
  * @endcode
  *
  * @since 1.25
@@ -398,9 +398,13 @@ $wgAllowImageMoving = true;
 $wgEnableAsyncUploads = false;
 
 /**
- * These are additional characters that should be replaced with '-' in filenames
+ * Additional characters that are not allowed in filenames. They are replaced with '-' when
+ * uploading. Like $wgLegalTitleChars, this is a regexp character class.
+ *
+ * Slashes and backslashes are disallowed regardless of this setting, but included here for
+ * completeness.
  */
-$wgIllegalFileChars = ":";
+$wgIllegalFileChars = ":\\/\\\\";
 
 /**
  * What directory to place deleted uploads in.
@@ -529,11 +533,74 @@ $wgUseInstantCommons = false;
  * Array of foreign file repo names (set in $wgForeignFileRepos above) that
  * are allowable upload targets. These wikis must have some method of
  * authentication (i.e. CentralAuth), and be CORS-enabled for this wiki.
+ * The string 'local' signifies the default local file repository.
  *
  * Example:
- * $wgForeignUploadTargets = array( 'shared' );
+ * $wgForeignUploadTargets = [ 'shared' ];
  */
-$wgForeignUploadTargets = [];
+$wgForeignUploadTargets = [ 'local' ];
+
+/**
+ * Configuration for file uploads using the embeddable upload dialog
+ * (https://www.mediawiki.org/wiki/Upload_dialog).
+ *
+ * This applies also to foreign uploads to this wiki (the configuration is loaded by remote wikis
+ * using the action=query&meta=siteinfo API).
+ *
+ * See below for documentation of each property. None of the properties may be omitted.
+ */
+$wgUploadDialog = [
+       // Fields to make available in the dialog. `true` means that this field is visible, `false` means
+       // that it is hidden. The "Name" field can't be hidden. Note that you also have to add the
+       // matching replacement to the 'filepage' format key below to make use of these.
+       'fields' => [
+               'description' => true,
+               'date' => false,
+               'categories' => false,
+       ],
+       // Suffix of localisation messages used to describe the license under which the uploaded file will
+       // be released. The same value may be set for both 'local' and 'foreign' uploads.
+       'licensemessages' => [
+               // The 'local' messages are used for local uploads on this wiki:
+               // * upload-form-label-own-work-message-generic-local
+               // * upload-form-label-not-own-work-message-generic-local
+               // * upload-form-label-not-own-work-local-generic-local
+               'local' => 'generic-local',
+               // The 'foreign' messages are used for cross-wiki uploads from other wikis to this wiki:
+               // * upload-form-label-own-work-message-generic-foreign
+               // * upload-form-label-not-own-work-message-generic-foreign
+               // * upload-form-label-not-own-work-local-generic-foreign
+               'foreign' => 'generic-foreign',
+       ],
+       // Upload comments to use for 'local' and 'foreign' uploads. This can also be set to a single
+       // string value, in which case it is used for both kinds of uploads. Available replacements:
+       // * $HOST - domain name from which a cross-wiki upload originates
+       // * $PAGENAME - wiki page name from which an upload originates
+       'comment' => [
+               'local' => '',
+               'foreign' => '',
+       ],
+       // Format of the file page wikitext to be generated from the fields input by the user.
+       'format' => [
+               // Wrapper for the whole page. Available replacements:
+               // * $DESCRIPTION - file description, as input by the user (only if the 'description' field is
+               //   enabled), wrapped as defined below in the 'description' key
+               // * $DATE - file creation date, as input by the user (only if the 'date' field is enabled)
+               // * $SOURCE - as defined below in the 'ownwork' key, may be extended in the future
+               // * $AUTHOR - linked user name, may be extended in the future
+               // * $LICENSE - as defined below in the 'license' key, may be extended in the future
+               // * $CATEGORIES - file categories wikitext, as input by the user (only if the 'categories'
+               //   field is enabled), or if no input, as defined below in the 'uncategorized' key
+               'filepage' => '$DESCRIPTION',
+               // Wrapped for file description. Available replacements:
+               // * $LANGUAGE - source wiki's content language
+               // * $TEXT - input by the user
+               'description' => '$TEXT',
+               'ownwork' => '',
+               'license' => '',
+               'uncategorized' => '',
+       ],
+];
 
 /**
  * File backend structure configuration.
@@ -618,7 +685,7 @@ $wgUseSharedUploads = false;
 /**
  * Full path on the web server where shared uploads can be found
  */
-$wgSharedUploadPath = "http://commons.wikimedia.org/shared/images";
+$wgSharedUploadPath = null;
 
 /**
  * Fetch commons image description pages and display them on the local wiki?
@@ -628,7 +695,7 @@ $wgFetchCommonsDescriptions = false;
 /**
  * Path on the file system where shared uploads can be found.
  */
-$wgSharedUploadDirectory = "/var/www/wiki3/images";
+$wgSharedUploadDirectory = null;
 
 /**
  * DB name with metadata about shared directory.
@@ -692,10 +759,10 @@ $wgCopyUploadTimeout = false;
  *
  * @par Example:
  * @code
- * $wgMaxUploadSize = array(
+ * $wgMaxUploadSize = [
  *     '*' => 250 * 1024,
  *     'url' => 500 * 1024,
- * );
+ * ];
  * @endcode
  * Sets the maximum for all uploads to 250 kB except for upload-by-url, which
  * will have a maximum of 500 kB.
@@ -878,22 +945,11 @@ $wgTrustedMediaFormats = [
 /**
  * Plugins for media file type handling.
  * Each entry in the array maps a MIME type to a class name
+ *
+ * Core media handlers are listed in MediaHandlerFactory,
+ * and extensions should use extension.json.
  */
-$wgMediaHandlers = [
-       'image/jpeg' => 'JpegHandler',
-       'image/png' => 'PNGHandler',
-       'image/gif' => 'GIFHandler',
-       'image/tiff' => 'TiffHandler',
-       'image/webp' => 'WebPHandler',
-       'image/x-ms-bmp' => 'BmpHandler',
-       '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
-];
+$wgMediaHandlers = [];
 
 /**
  * Plugins for page content model handling.
@@ -980,6 +1036,27 @@ $wgCustomConvertCommand = false;
  */
 $wgJpegTran = '/usr/bin/jpegtran';
 
+/**
+ * At default setting of 'yuv420', JPEG thumbnails will use 4:2:0 chroma
+ * subsampling to reduce file size, at the cost of possible color fringing
+ * at sharp edges.
+ *
+ * See https://en.wikipedia.org/wiki/Chroma_subsampling
+ *
+ * Supported values:
+ *   false - use scaling system's default (same as pre-1.27 behavior)
+ *   'yuv444' - luma and chroma at same resolution
+ *   'yuv422' - chroma at 1/2 resolution horizontally, full vertically
+ *   'yuv420' - chroma at 1/2 resolution in both dimensions
+ *
+ * This setting is currently supported only for the ImageMagick backend;
+ * others may default to 4:2:0 or 4:4:4 or maintaining the source file's
+ * sampling in the thumbnail.
+ *
+ * @since 1.27
+ */
+$wgJpegPixelFormat = 'yuv420';
+
 /**
  * Some tests and extensions use exiv2 to manipulate the Exif metadata in some
  * image formats.
@@ -1079,9 +1156,9 @@ $wgMaxAnimatedGifArea = 1.25e7;
  * @par Example:
  * @code
  *  // PNG is lossless, but inefficient for photos
- *  $wgTiffThumbnailType = array( 'png', 'image/png' );
+ *  $wgTiffThumbnailType = [ 'png', 'image/png' ];
  *  // JPEG is good for photos, but has no transparency support. Bad for diagrams.
- *  $wgTiffThumbnailType = array( 'jpg', 'image/jpeg' );
+ *  $wgTiffThumbnailType = [ 'jpg', 'image/jpeg' ];
  * @endcode
  */
 $wgTiffThumbnailType = false;
@@ -1237,7 +1314,7 @@ $wgTrivialMimeDetection = false;
 
 /**
  * Additional XML types we can allow via MIME-detection.
- * array = ( 'rootElement' => 'associatedMimeType' )
+ * array = [ 'rootElement' => 'associatedMimeType' ]
  */
 $wgXMLMimeTypes = [
        'http://www.w3.org/2000/svg:svg' => 'image/svg+xml',
@@ -1294,7 +1371,7 @@ $wgThumbnailBuckets = null;
  * needs in order to be used as the reference for a given thumbnail. For example, with the
  * following buckets:
  *
- * $wgThumbnailBuckets = array ( 128, 256, 512 );
+ * $wgThumbnailBuckets = [ 128, 256, 512 ];
  *
  * and a distance of 50:
  *
@@ -1360,7 +1437,10 @@ $wgGalleryOptions = [
        '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")
-       'captionLength' => 25, // Length of caption to truncate (in characters)
+       'captionLength' => true, // Deprecated @since 1.28
+                                // Length to truncate filename to in caption when using "showfilename".
+                                // A value of 'true' will truncate the filename to one line using CSS
+                                // and will be the behaviour after deprecation.
        'showBytes' => true, // Show the filesize in bytes in categories
        'mode' => 'traditional',
 ];
@@ -1540,14 +1620,14 @@ $wgPasswordExpireGrace = 3600 * 24 * 7; // 7 days
  * Default to false or fill an array :
  *
  * @code
- * $wgSMTP = array(
+ * $wgSMTP = [
  *     'host'     => 'SMTP domain',
  *     'IDHost'   => 'domain for MessageID',
  *     'port'     => '25',
  *     'auth'     => [true|false],
  *     'username' => [SMTP username],
  *     'password' => [SMTP password],
- * );
+ * ];
  * @endcode
  */
 $wgSMTP = false;
@@ -1590,6 +1670,9 @@ $wgEnotifWatchlist = false;
 /**
  * Allow users to enable email notification ("enotif") when someone edits their
  * user talk page.
+ *
+ * The owner of the user talk page must also have the 'enotifusertalkpages' user
+ * preference set to true.
  */
 $wgEnotifUserTalk = false;
 
@@ -1600,9 +1683,17 @@ $wgEnotifUserTalk = false;
 $wgEnotifRevealEditorAddress = false;
 
 /**
- * Send notification mails on minor edits to watchlist pages. This is enabled
- * by default. User talk notifications are affected by this, $wgEnotifUserTalk, and
- * the nominornewtalk user right.
+ * Potentially send notification mails on minor edits to pages. This is enabled
+ * by default.  If this is false, users will never be notified on minor edits.
+ *
+ * If it is true, editors with the 'nominornewtalk' right (typically bots) will still not
+ * trigger notifications for minor edits they make (to any page, not just user talk).
+ *
+ * Finally, if the watcher/recipient has the 'enotifminoredits' user preference set to
+ * false, they will not receive notifications for minor edits.
+ *
+ * User talk notifications are also affected by $wgEnotifMinorEdits, the above settings,
+ * $wgEnotifUserTalk, and the preference described there.
  */
 $wgEnotifMinorEdits = true;
 
@@ -1813,7 +1904,7 @@ $wgSharedSchema = false;
  *                  to several groups, the most specific group defined here is used.
  *
  *   - flags:       bit field
- *                  - DBO_DEFAULT -- turns on DBO_TRX only if !$wgCommandLineMode (recommended)
+ *                  - DBO_DEFAULT -- turns on DBO_TRX only if "cliMode" is off (recommended)
  *                  - DBO_DEBUG -- equivalent of $wgDebugDumpSql
  *                  - DBO_TRX -- wrap entire request in a transaction
  *                  - DBO_NOBUFFER -- turn off buffering (not useful in LocalSettings.php)
@@ -1823,6 +1914,10 @@ $wgSharedSchema = false;
  *                                    if available
  *
  *   - max lag:     (optional) Maximum replication lag before a slave will taken out of rotation
+ *   - is static:   (optional) Set to true if the dataset is static and no replication is used.
+ *   - cliMode:     (optional) Connection handles will not assume that requests are short-lived
+ *                  nor that INSERT..SELECT can be rewritten into a buffered SELECT and INSERT.
+ *                  [Default: uses value of $wgCommandLineMode]
  *
  *   These and any other user-defined properties will be assigned to the mLBInfo member
  *   variable of the Database object.
@@ -1983,7 +2078,7 @@ $wgCompressRevisions = false;
  *
  * Short names of ExternalStore classes may be specified in an array here:
  * @code
- * $wgExternalStores = array("http","file","custom")...
+ * $wgExternalStores = [ "http","file","custom" ]...
  * @endcode
  *
  * CAUTION: Access to database might lead to code execution
@@ -1996,9 +2091,9 @@ $wgExternalStores = [];
  * @par Example:
  * Create a cluster named 'cluster1' containing three servers:
  * @code
- * $wgExternalServers = array(
- *     'cluster1' => array( 'srv28', 'srv29', 'srv30' )
- * );
+ * $wgExternalServers = [
+ *     'cluster1' => [ 'srv28', 'srv29', 'srv30' ]
+ * ];
  * @endcode
  *
  * Used by LBFactorySimple, may be ignored if $wgLBFactoryConf is set to
@@ -2015,7 +2110,7 @@ $wgExternalServers = [];
  *
  * @par Example:
  * @code
- * $wgDefaultExternalStore = array( 'DB://cluster1', 'DB://cluster2' );
+ * $wgDefaultExternalStore = [ 'DB://cluster1', 'DB://cluster2' ];
  * @endcode
  *
  * @var array
@@ -2169,7 +2264,7 @@ $wgLanguageConverterCacheType = CACHE_ANYTHING;
  * given, giving a callable function which will generate a suitable cache object.
  */
 $wgObjectCaches = [
-       CACHE_NONE => [ 'class' => 'EmptyBagOStuff' ],
+       CACHE_NONE => [ 'class' => 'EmptyBagOStuff', 'reportDupes' => false ],
        CACHE_DB => [ 'class' => 'SqlBagOStuff', 'loggroup' => 'SQLBagOStuff' ],
 
        CACHE_ANYTHING => [ 'factory' => 'ObjectCache::newAnything' ],
@@ -2189,12 +2284,12 @@ $wgObjectCaches = [
                'loggroup'  => 'SQLBagOStuff'
        ],
 
-       'apc' => [ 'class' => 'APCBagOStuff' ],
-       'xcache' => [ 'class' => 'XCacheBagOStuff' ],
-       'wincache' => [ 'class' => 'WinCacheBagOStuff' ],
+       'apc' => [ 'class' => 'APCBagOStuff', 'reportDupes' => false ],
+       'xcache' => [ 'class' => 'XCacheBagOStuff', 'reportDupes' => false ],
+       'wincache' => [ 'class' => 'WinCacheBagOStuff', 'reportDupes' => false ],
        'memcached-php' => [ 'class' => 'MemcachedPhpBagOStuff', 'loggroup' => 'memcached' ],
        'memcached-pecl' => [ 'class' => 'MemcachedPeclBagOStuff', 'loggroup' => 'memcached' ],
-       'hash' => [ 'class' => 'HashBagOStuff' ],
+       'hash' => [ 'class' => 'HashBagOStuff', 'reportDupes' => false ],
 ];
 
 /**
@@ -2223,27 +2318,24 @@ $wgMainWANCache = false;
  *
  * The format is an associative array where the key is a cache identifier, and
  * the value is an associative array of parameters. The "cacheId" parameter is
- * a cache identifier from $wgObjectCaches. The "relayerConfig" parameter is an
- * array used to construct an EventRelayer object. The "pool" parameter is a
- * string that is used as a PubSub channel prefix. The "loggroup" parameter
- * controls where log events are sent.
+ * a cache identifier from $wgObjectCaches. The "channels" parameter is a map of
+ * actions ('purge') to PubSub channels defined in $wgEventRelayerConfig.
+ * The "loggroup" parameter controls where log events are sent.
  *
  * @since 1.26
  */
 $wgWANObjectCaches = [
        CACHE_NONE => [
-               'class'         => 'WANObjectCache',
-               'cacheId'       => CACHE_NONE,
-               'pool'          => 'mediawiki-main-none',
-               'relayerConfig' => [ 'class' => 'EventRelayerNull' ]
+               'class'    => 'WANObjectCache',
+               'cacheId'  => CACHE_NONE,
+               'channels' => []
        ]
        /* Example of a simple single data-center cache:
-       'memcached-php' => array(
-               'class'         => 'WANObjectCache',
-               'cacheId'       => 'memcached-php',
-               'pool'          => 'mediawiki-main-memcached',
-               'relayerConfig' => array( 'class' => 'EventRelayerNull' )
-       )
+       'memcached-php' => [
+               'class'    => 'WANObjectCache',
+               'cacheId'  => 'memcached-php',
+               'channels' => [ 'purge' => 'wancache-main-memcached-purge' ]
+       ]
        */
 ];
 
@@ -2309,6 +2401,13 @@ $wgSessionHandler = null;
  */
 $wgPHPSessionHandling = 'enable';
 
+/**
+ * Number of internal PBKDF2 iterations to use when deriving session secrets.
+ *
+ * @since 1.28
+ */
+$wgSessionPbkdf2Iterations = 10001;
+
 /**
  * If enabled, will send MemCached debugging information to $wgDebugLogFile
  */
@@ -2428,7 +2527,7 @@ $wgFileCacheDepth = 2;
 
 /**
  * Kept for extension compatibility; see $wgParserCacheType
- * @deprecated 1.26
+ * @deprecated since 1.26
  */
 $wgEnableParserCache = true;
 
@@ -2462,12 +2561,6 @@ $wgSidebarCacheExpiry = 86400;
  */
 $wgUseGzip = false;
 
-/**
- * Whether MediaWiki should send an ETag header. Seems to cause
- * broken behavior with Squid 2.6, see bug 7098.
- */
-$wgUseETag = false;
-
 /**
  * Clock skew or the one-second resolution of time() can occasionally cause cache
  * problems when the user requests two pages within a short period of time. This
@@ -2589,6 +2682,13 @@ $wgCdnMaxageLagged = 30;
  */
 $wgCdnReboundPurgeDelay = 0;
 
+/**
+ * Cache timeout for the CDN when a response is known to be wrong or incomplete (due to load)
+ * @see $wgSquidMaxage
+ * @since 1.27
+ */
+$wgCdnMaxageSubstitute = 60;
+
 /**
  * Default maximum age for raw CSS/JS accesses
  *
@@ -2648,16 +2748,16 @@ $wgSquidPurgeUseHostHeader = true;
  * @par Example configuration to send purges for upload.wikimedia.org to one
  * multicast group and all other purges to another:
  * @code
- * $wgHTCPRouting = array(
- *         '|^https?://upload\.wikimedia\.org|' => array(
+ * $wgHTCPRouting = [
+ *         '|^https?://upload\.wikimedia\.org|' => [
  *                 'host' => '239.128.0.113',
  *                 'port' => 4827,
- *         ),
- *         '' => array(
+ *         ],
+ *         '' => [
  *                 'host' => '239.128.0.112',
  *                 'port' => 4827,
- *         ),
- * );
+ *         ],
+ * ];
  * @endcode
  *
  * You can also pass an array of hosts to send purges too. This is useful when
@@ -2666,16 +2766,16 @@ $wgSquidPurgeUseHostHeader = true;
  *
  * @par Example of sending purges to multiple hosts:
  * @code
- * $wgHTCPRouting = array(
- *     '' => array(
+ * $wgHTCPRouting = [
+ *     '' => [
  *         // Purges to text caches using multicast
- *         array( 'host' => '239.128.0.114', 'port' => '4827' ),
+ *         [ 'host' => '239.128.0.114', 'port' => '4827' ],
  *         // Purges to a hardcoded list of caches
- *         array( 'host' => '10.88.66.1', 'port' => '4827' ),
- *         array( 'host' => '10.88.66.2', 'port' => '4827' ),
- *         array( 'host' => '10.88.66.3', 'port' => '4827' ),
- *     ),
- * );
+ *         [ 'host' => '10.88.66.1', 'port' => '4827' ],
+ *         [ 'host' => '10.88.66.2', 'port' => '4827' ],
+ *         [ 'host' => '10.88.66.3', 'port' => '4827' ],
+ *     ],
+ * ];
  * @endcode
  *
  * @since 1.22
@@ -2792,15 +2892,6 @@ $wgDummyLanguageCodes = [
        'zh-yue' => 'yue',
 ];
 
-/**
- * Character set for use in the article edit box. Language-specific encodings
- * may be defined.
- *
- * This historic feature is one of the first that was added by former MediaWiki
- * team leader Brion Vibber, and is used to support the Esperanto x-system.
- */
-$wgEditEncoding = '';
-
 /**
  * Set this to true to replace Arabic presentation forms with their standard
  * forms in the U+0600-U+06FF block. This only works if $wgLanguageCode is
@@ -2998,7 +3089,7 @@ $wgLoginLanguageSelector = false;
  * To allow language-specific main page and community
  * portal:
  * @code
- *     $wgForceUIMsgAsContentMsg = array( 'mainpage', 'portal-url' );
+ *     $wgForceUIMsgAsContentMsg = [ 'mainpage', 'portal-url' ];
  * @endcode
  */
 $wgForceUIMsgAsContentMsg = [];
@@ -3106,22 +3197,13 @@ $wgHTMLFormAllowTableFormat = true;
 $wgUseMediaWikiUIEverywhere = false;
 
 /**
- * Should we try to make our HTML output well-formed XML?  If set to false,
- * output will be a few bytes shorter, and the HTML will arguably be more
- * readable.  If set to true, life will be much easier for the authors of
- * screen-scraping bots, and the HTML will arguably be more readable.
- *
- * Setting this to false may omit quotation marks on some attributes, omit
- * slashes from some self-closing tags, omit some ending tags, etc., where
- * permitted by HTML5.  Setting it to true will not guarantee that all pages
- * will be well-formed, although non-well-formed pages should be rare and it's
- * a bug if you find one.  Conversely, setting it to false doesn't mean that
- * all XML-y constructs will be omitted, just that they might be.
+ * Whether to label the store-to-database-and-show-to-others button in the editor
+ * as "Save page"/"Save changes" if false (the default) or, if true, instead as
+ * "Publish page"/"Publish changes".
  *
- * Because of compatibility with screen-scraping bots, and because it's
- * controversial, this is currently left to true by default.
+ * @since 1.28
  */
-$wgWellFormedXml = true;
+$wgEditSubmitButtonLabelPublish = false;
 
 /**
  * Permit other namespaces in addition to the w3.org default.
@@ -3386,13 +3468,13 @@ $wgMangleFlashPolicy = true;
  *
  * @par Example:
  * @code
- *   $wgResourceModules['ext.myExtension'] = array(
+ *   $wgResourceModules['ext.myExtension'] = [
  *      'scripts' => 'myExtension.js',
  *      'styles' => 'myExtension.css',
- *      'dependencies' => array( 'jquery.cookie', 'jquery.tabIndex' ),
+ *      'dependencies' => [ 'jquery.cookie', 'jquery.tabIndex' ],
  *      'localBasePath' => __DIR__,
  *      'remoteExtPath' => 'MyExtension',
- *   );
+ *   ];
  * @endcode
  */
 $wgResourceModules = [];
@@ -3407,27 +3489,27 @@ $wgResourceModules = [];
  *
  * @par Example:
  * @code
- *   $wgResourceModules['bar'] = array(
+ *   $wgResourceModules['bar'] = [
  *     'scripts' => 'resources/bar/bar.js',
  *     'styles' => 'resources/bar/main.css',
- *   );
+ *   ];
  *
- *   $wgResourceModuleSkinStyles['foo'] = array(
+ *   $wgResourceModuleSkinStyles['foo'] = [
  *     'bar' => 'skins/Foo/bar.css',
- *   );
+ *   ];
  * @endcode
  *
  * This is mostly equivalent to:
  *
  * @par Equivalent:
  * @code
- *   $wgResourceModules['bar'] = array(
+ *   $wgResourceModules['bar'] = [
  *     'scripts' => 'resources/bar/bar.js',
  *     'styles' => 'resources/bar/main.css',
- *     'skinStyles' => array(
+ *     'skinStyles' => [
  *       'foo' => skins/Foo/bar.css',
- *     ),
- *   );
+ *     ],
+ *   ];
  * @endcode
  *
  * If the module already defines its own entry in `skinStyles` for a given skin, then
@@ -3438,34 +3520,34 @@ $wgResourceModules = [];
  *
  * @par Example:
  * @code
- *   $wgResourceModules['bar'] = array(
+ *   $wgResourceModules['bar'] = [
  *     'scripts' => 'resources/bar/bar.js',
  *     'styles' => 'resources/bar/basic.css',
- *     'skinStyles' => array(
- *       'default' => 'resources/bar/additional.css',
- *     ),
- *   );
+ *     'skinStyles' => [
+ *      'default' => 'resources/bar/additional.css',
+ *     ],
+ *   ];
  *   // Note the '+' character:
- *   $wgResourceModuleSkinStyles['foo'] = array(
+ *   $wgResourceModuleSkinStyles['foo'] = [
  *     '+bar' => 'skins/Foo/bar.css',
- *   );
+ *   ];
  * @endcode
  *
  * This is mostly equivalent to:
  *
  * @par Equivalent:
  * @code
- *   $wgResourceModules['bar'] = array(
+ *   $wgResourceModules['bar'] = [
  *     'scripts' => 'resources/bar/bar.js',
  *     'styles' => 'resources/bar/basic.css',
- *     'skinStyles' => array(
+ *     'skinStyles' => [
  *       'default' => 'resources/bar/additional.css',
- *       'foo' => array(
+ *       'foo' => [
  *         'resources/bar/additional.css',
  *         'skins/Foo/bar.css',
- *       ),
- *     ),
- *   );
+ *       ],
+ *     ],
+ *   ];
  * @endcode
  *
  * In other words, as a module author, use the `styles` list for stylesheets that may not be
@@ -3477,12 +3559,12 @@ $wgResourceModules = [];
  *
  * @par Example:
  * @code
- *   $wgResourceModuleSkinStyles['foo'] = array(
+ *   $wgResourceModuleSkinStyles['foo'] = [
  *     'bar' => 'bar.css',
  *     'quux' => 'quux.css',
  *     'remoteSkinPath' => 'Foo',
  *     'localBasePath' => __DIR__,
- *   );
+ *   ];
  * @endcode
  */
 $wgResourceModuleSkinStyles = [];
@@ -3639,11 +3721,11 @@ $wgResourceLoaderValidateStaticJS = false;
  *
  * @par Example:
  * @code
- *   $wgResourceLoaderLESSVars = array(
+ *   $wgResourceLoaderLESSVars = [
  *     'baseFontSize'  => '1em',
  *     'smallFontSize' => '0.75em',
  *     'WikimediaBlue' => '#006699',
- *   );
+ *   ];
  * @endcode
  * @since 1.22
  */
@@ -3677,10 +3759,8 @@ $wgResourceLoaderLESSImportPaths = [
 /**
  * Whether ResourceLoader should attempt to persist modules in localStorage on
  * browsers that support the Web Storage API.
- *
- * @since 1.23 - Client-side module persistence is experimental. Exercise care.
  */
-$wgResourceLoaderStorageEnabled = false;
+$wgResourceLoaderStorageEnabled = true;
 
 /**
  * Cache version for client-side ResourceLoader module storage. You can trigger
@@ -3741,12 +3821,12 @@ $wgMetaNamespaceTalk = false;
  *
  * @par Example:
  * @code
- * $wgExtraNamespaces = array(
+ * $wgExtraNamespaces = [
  *    100 => "Hilfe",
  *    101 => "Hilfe_Diskussion",
  *    102 => "Aide",
  *    103 => "Discussion_Aide"
- * );
+ * ];
  * @endcode
  *
  * @todo Add a note about maintenance/namespaceDupes.php
@@ -3773,10 +3853,10 @@ $wgExtraGenderNamespaces = [];
  *
  * @par Example:
  * @code
- *    $wgNamespaceAliases = array(
+ *    $wgNamespaceAliases = [
  *        'Wikipedian' => NS_USER,
  *        'Help' => 100,
- *    );
+ *    ];
  * @endcode
  */
 $wgNamespaceAliases = [];
@@ -4103,7 +4183,7 @@ $wgAllowExternalImages = false;
  * @par Examples:
  * @code
  * $wgAllowExternalImagesFrom = 'http://127.0.0.1/';
- * $wgAllowExternalImagesFrom = array( 'http://127.0.0.1/', 'http://example.com' );
+ * $wgAllowExternalImagesFrom = [ 'http://127.0.0.1/', 'http://example.com' ];
  * @endcode
  */
 $wgAllowExternalImagesFrom = '';
@@ -4144,6 +4224,8 @@ $wgAllowImageTag = false;
  *    - RaggettInternalHHVM: Use the limited-functionality HHVM extension
  *    - RaggettInternalPHP: Use the PECL extension
  *    - RaggettExternal: Shell out to an external binary (tidyBin)
+ *    - Html5Depurate: Use external Depurate service
+ *    - Html5Internal: Use the built-in HTML5 balancer
  *
  *  - tidyConfigFile: Path to configuration file for any of the Raggett drivers
  *  - debugComment: True to add a comment to the output with warning messages
@@ -4196,7 +4278,13 @@ $wgDebugTidy = false;
 $wgRawHtml = false;
 
 /**
- * Set a default target for external links, e.g. _blank to pop up a new window
+ * Set a default target for external links, e.g. _blank to pop up a new window.
+ *
+ * This will also set the "noreferrer" and "noopener" link rel to prevent the
+ * attack described at https://mathiasbynens.github.io/rel-noopener/ .
+ * Some older browsers may not support these link attributes, hence
+ * setting $wgExternalLinkTarget to _blank may represent a security risk
+ * to some of your users.
  */
 $wgExternalLinkTarget = false;
 
@@ -4219,8 +4307,7 @@ $wgNoFollowNsExceptions = [];
  * (or any subdomains) will not be set to rel="nofollow" regardless of the
  * value of $wgNoFollowLinks.  For instance:
  *
- * $wgNoFollowDomainExceptions = array( 'en.wikipedia.org', 'wiktionary.org',
- * 'mediawiki.org' );
+ * $wgNoFollowDomainExceptions = [ 'en.wikipedia.org', 'wiktionary.org', 'mediawiki.org' ];
  *
  * This would add rel="nofollow" to links to de.wikipedia.org, but not
  * en.wikipedia.org, wiktionary.org, en.wiktionary.org, us.en.wikipedia.org,
@@ -4381,6 +4468,178 @@ $wgPasswordPolicy = [
        ],
 ];
 
+/**
+ * Configure AuthManager
+ *
+ * All providers are constructed using ObjectFactory, see that for the general
+ * structure. The array may also contain a key "sort" used to order providers:
+ * providers are stably sorted by this value, which should be an integer
+ * (default is 0).
+ *
+ * Elements are:
+ * - preauth: Array (keys ignored) of specifications for PreAuthenticationProviders
+ * - primaryauth: Array (keys ignored) of specifications for PrimaryAuthenticationProviders
+ * - secondaryauth: Array (keys ignored) of specifications for SecondaryAuthenticationProviders
+ *
+ * @since 1.27
+ * @note If this is null or empty, the value from $wgAuthManagerAutoConfig is
+ *  used instead. Local customization should generally set this variable from
+ *  scratch to the desired configuration. Extensions that want to
+ *  auto-configure themselves should use $wgAuthManagerAutoConfig instead.
+ */
+$wgAuthManagerConfig = null;
+
+/**
+ * @see $wgAuthManagerConfig
+ * @since 1.27
+ */
+$wgAuthManagerAutoConfig = [
+       'preauth' => [
+               MediaWiki\Auth\LegacyHookPreAuthenticationProvider::class => [
+                       'class' => MediaWiki\Auth\LegacyHookPreAuthenticationProvider::class,
+                       'sort' => 0,
+               ],
+               MediaWiki\Auth\ThrottlePreAuthenticationProvider::class => [
+                       'class' => MediaWiki\Auth\ThrottlePreAuthenticationProvider::class,
+                       'sort' => 0,
+               ],
+       ],
+       'primaryauth' => [
+               // TemporaryPasswordPrimaryAuthenticationProvider should come before
+               // any other PasswordAuthenticationRequest-based
+               // PrimaryAuthenticationProvider (or at least any that might return
+               // FAIL rather than ABSTAIN for a wrong password), or password reset
+               // won't work right. Do not remove this (or change the key) or
+               // auto-configuration of other such providers in extensions will
+               // probably auto-insert themselves in the wrong place.
+               MediaWiki\Auth\TemporaryPasswordPrimaryAuthenticationProvider::class => [
+                       'class' => MediaWiki\Auth\TemporaryPasswordPrimaryAuthenticationProvider::class,
+                       'args' => [ [
+                               // Fall through to LocalPasswordPrimaryAuthenticationProvider
+                               'authoritative' => false,
+                       ] ],
+                       'sort' => 0,
+               ],
+               MediaWiki\Auth\LocalPasswordPrimaryAuthenticationProvider::class => [
+                       'class' => MediaWiki\Auth\LocalPasswordPrimaryAuthenticationProvider::class,
+                       'args' => [ [
+                               // Last one should be authoritative, or else the user will get
+                               // a less-than-helpful error message (something like "supplied
+                               // authentication info not supported" rather than "wrong
+                               // password") if it too fails.
+                               'authoritative' => true,
+                       ] ],
+                       'sort' => 100,
+               ],
+       ],
+       'secondaryauth' => [
+               MediaWiki\Auth\CheckBlocksSecondaryAuthenticationProvider::class => [
+                       'class' => MediaWiki\Auth\CheckBlocksSecondaryAuthenticationProvider::class,
+                       'sort' => 0,
+               ],
+               MediaWiki\Auth\ResetPasswordSecondaryAuthenticationProvider::class => [
+                       'class' => MediaWiki\Auth\ResetPasswordSecondaryAuthenticationProvider::class,
+                       'sort' => 100,
+               ],
+               // Linking during login is experimental, enable at your own risk - T134952
+               // MediaWiki\Auth\ConfirmLinkSecondaryAuthenticationProvider::class => [
+               //      'class' => MediaWiki\Auth\ConfirmLinkSecondaryAuthenticationProvider::class,
+               //      'sort' => 100,
+               // ],
+               MediaWiki\Auth\EmailNotificationSecondaryAuthenticationProvider::class => [
+                       'class' => MediaWiki\Auth\EmailNotificationSecondaryAuthenticationProvider::class,
+                       'sort' => 200,
+               ],
+       ],
+];
+
+/**
+ * Time frame for re-authentication.
+ *
+ * With only password-based authentication, you'd just ask the user to re-enter
+ * their password to verify certain operations like changing the password or
+ * changing the account's email address. But under AuthManager, the user might
+ * not have a password (you might even have to redirect the browser to a
+ * third-party service or something complex like that), you might want to have
+ * both factors of a two-factor authentication, and so on. So, the options are:
+ * - Incorporate the whole multi-step authentication flow within everything
+ *   that needs to do this.
+ * - Consider it good if they used Special:UserLogin during this session within
+ *   the last X seconds.
+ * - Come up with a third option.
+ *
+ * MediaWiki currently takes the second option. This setting configures the
+ * "X seconds".
+ *
+ * This allows for configuring different time frames for different
+ * "operations". The operations used in MediaWiki core include:
+ * - LinkAccounts
+ * - UnlinkAccount
+ * - ChangeCredentials
+ * - RemoveCredentials
+ * - ChangeEmail
+ *
+ * Additional operations may be used by extensions, either explicitly by
+ * calling AuthManager::securitySensitiveOperationStatus(),
+ * ApiAuthManagerHelper::securitySensitiveOperation() or
+ * SpecialPage::checkLoginSecurityLevel(), or implicitly by overriding
+ * SpecialPage::getLoginSecurityLevel() or by subclassing
+ * AuthManagerSpecialPage.
+ *
+ * The key 'default' is used if a requested operation isn't defined in the array.
+ *
+ * @since 1.27
+ * @var int[] operation => time in seconds. A 'default' key must always be provided.
+ */
+$wgReauthenticateTime = [
+       'default' => 300,
+];
+
+/**
+ * Whether to allow security-sensitive operations when re-authentication is not possible.
+ *
+ * If AuthManager::canAuthenticateNow() is false (e.g. the current
+ * SessionProvider is not able to change users, such as when OAuth is in use),
+ * AuthManager::securitySensitiveOperationStatus() cannot sensibly return
+ * SEC_REAUTH. Setting an operation true here will have it return SEC_OK in
+ * that case, while setting it false will have it return SEC_FAIL.
+ *
+ * The key 'default' is used if a requested operation isn't defined in the array.
+ *
+ * @since 1.27
+ * @see $wgReauthenticateTime
+ * @var bool[] operation => boolean. A 'default' key must always be provided.
+ */
+$wgAllowSecuritySensitiveOperationIfCannotReauthenticate = [
+       'default' => true,
+];
+
+/**
+ * List of AuthenticationRequest class names which are not changeable through
+ * Special:ChangeCredentials and the changeauthenticationdata API.
+ * This is only enforced on the client level; AuthManager itself (e.g.
+ * AuthManager::allowsAuthenticationDataChange calls) is not affected.
+ * Class names are checked for exact match (not for subclasses).
+ * @since 1.27
+ * @var string[]
+ */
+$wgChangeCredentialsBlacklist = [
+       \MediaWiki\Auth\TemporaryPasswordAuthenticationRequest::class
+];
+
+/**
+ * List of AuthenticationRequest class names which are not removable through
+ * Special:RemoveCredentials and the removeauthenticationdata API.
+ * This is only enforced on the client level; AuthManager itself (e.g.
+ * AuthManager::allowsAuthenticationDataChange calls) is not affected.
+ * Class names are checked for exact match (not for subclasses).
+ * @since 1.27
+ * @var string[]
+ */
+$wgRemoveCredentialsBlacklist = [
+       \MediaWiki\Auth\PasswordAuthenticationRequest::class,
+];
+
 /**
  * For compatibility with old installations set to false
  * @deprecated since 1.24 will be removed in future
@@ -4428,14 +4687,14 @@ $wgPasswordDefault = 'pbkdf2';
  *
  * An advanced example:
  * @code
- * $wgPasswordConfig['bcrypt-peppered'] = array(
+ * $wgPasswordConfig['bcrypt-peppered'] = [
  *     'class' => 'EncryptedPassword',
  *     'underlying' => 'bcrypt',
- *     'secrets' => array(),
+ *     'secrets' => [],
  *     'cipher' => MCRYPT_RIJNDAEL_256,
  *     'mode' => MCRYPT_MODE_CBC,
  *     'cost' => 5,
- * );
+ * ];
  * @endcode
  *
  * @since 1.24
@@ -4467,9 +4726,9 @@ $wgPasswordConfig = [
        ],
        'pbkdf2' => [
                'class' => 'Pbkdf2Password',
-               'algo' => 'sha256',
-               'cost' => '10000',
-               'length' => '128',
+               'algo' => 'sha512',
+               'cost' => '30000',
+               'length' => '64',
        ],
 ];
 
@@ -4562,6 +4821,7 @@ $wgDefaultUserOptions = [
        'watchcreations' => 1,
        'watchdefault' => 1,
        'watchdeletion' => 0,
+       'watchuploads' => 1,
        'watchlistdays' => 3.0,
        'watchlisthideanons' => 0,
        'watchlisthidebots' => 0,
@@ -4640,7 +4900,7 @@ $wgSessionProviders = [
        MediaWiki\Session\BotPasswordSessionProvider::class => [
                'class' => MediaWiki\Session\BotPasswordSessionProvider::class,
                'args' => [ [
-                       'priority' => 40,
+                       'priority' => 75,
                ] ],
        ],
 ];
@@ -4723,7 +4983,7 @@ $wgWhitelistRead = false;
  * @par Example:
  * To whitelist [[Main Page]]:
  * @code
- * $wgWhitelistReadRegexp = array( "/Main Page/" );
+ * $wgWhitelistReadRegexp = [ "/Main Page/" ];
  * @endcode
  *
  * @note Unless ^ and/or $ is specified, a regular expression might match
@@ -4733,7 +4993,7 @@ $wgWhitelistRead = false;
  * @par Example:
  * To allow reading any page starting with 'User' regardless of the case:
  * @code
- * $wgWhitelistReadRegexp = array( "@^UsEr.*@i" );
+ * $wgWhitelistReadRegexp = [ "@^UsEr.*@i" ];
  * @endcode
  * Will allow both [[User is banned]] and [[User:JohnDoe]]
  *
@@ -4768,7 +5028,7 @@ $wgHideIdentifiableRedirects = true;
  * combined with the permissions of all groups that a given user is listed
  * in in the user_groups table.
  *
- * Note: Don't set $wgGroupPermissions = array(); unless you know what you're
+ * Note: Don't set $wgGroupPermissions = []; unless you know what you're
  * doing! This will wipe all permissions, and may mean that your users are
  * unable to perform certain essential tasks or access new functionality
  * when new permissions are introduced and default grants established.
@@ -4812,7 +5072,7 @@ $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']['purge'] = true;
 $wgGroupPermissions['user']['sendemail'] = true;
 $wgGroupPermissions['user']['applychangetags'] = true;
 $wgGroupPermissions['user']['changetags'] = true;
@@ -4877,6 +5137,7 @@ $wgGroupPermissions['sysop']['suppressredirect'] = true;
 # $wgGroupPermissions['sysop']['upload_by_url'] = true;
 $wgGroupPermissions['sysop']['mergehistory'] = true;
 $wgGroupPermissions['sysop']['managechangetags'] = true;
+$wgGroupPermissions['sysop']['deletechangetags'] = true;
 
 // Permission to change users' group assignments
 $wgGroupPermissions['bureaucrat']['userrights'] = true;
@@ -4933,13 +5194,13 @@ $wgImplicitGroups = [ '*', 'user', 'autoconfirmed' ];
  * @par Example:
  * To allow sysops to add themselves to the "bot" group:
  * @code
- *    $wgGroupsAddToSelf = array( 'sysop' => array( 'bot' ) );
+ *    $wgGroupsAddToSelf = [ 'sysop' => [ 'bot' ] ];
  * @endcode
  *
  * @par Example:
  * Implicit groups may be used for the source group, for instance:
  * @code
- *    $wgGroupsRemoveFromSelf = array( '*' => true );
+ *    $wgGroupsRemoveFromSelf = [ '*' => true ];
  * @endcode
  * This allows users in the '*' group (i.e. any user) to remove themselves from
  * any group that they happen to be in.
@@ -5057,18 +5318,18 @@ $wgAutoConfirmCount = 0;
  * @todo Redocument $wgAutopromote
  *
  * The format is
- *   array( '&' or '|' or '^' or '!', cond1, cond2, ... )
+ *   [ '&' or '|' or '^' or '!', cond1, cond2, ... ]
  * where cond1, cond2, ... are themselves conditions; *OR*
  *   APCOND_EMAILCONFIRMED, *OR*
- *   array( APCOND_EMAILCONFIRMED ), *OR*
- *   array( APCOND_EDITCOUNT, number of edits ), *OR*
- *   array( APCOND_AGE, seconds since registration ), *OR*
- *   array( APCOND_INGROUPS, group1, group2, ... ), *OR*
- *   array( APCOND_ISIP, ip ), *OR*
- *   array( APCOND_IPINRANGE, range ), *OR*
- *   array( APCOND_AGE_FROM_EDIT, seconds since first edit ), *OR*
- *   array( APCOND_BLOCKED ), *OR*
- *   array( APCOND_ISBOT ), *OR*
+ *   [ APCOND_EMAILCONFIRMED ], *OR*
+ *   [ APCOND_EDITCOUNT, number of edits ], *OR*
+ *   [ APCOND_AGE, seconds since registration ], *OR*
+ *   [ APCOND_INGROUPS, group1, group2, ... ], *OR*
+ *   [ APCOND_ISIP, ip ], *OR*
+ *   [ APCOND_IPINRANGE, range ], *OR*
+ *   [ APCOND_AGE_FROM_EDIT, seconds since first edit ], *OR*
+ *   [ APCOND_BLOCKED ], *OR*
+ *   [ APCOND_ISBOT ], *OR*
  *   similar constructs defined by extensions.
  *
  * If $wgEmailAuthentication is off, APCOND_EMAILCONFIRMED will be true for any
@@ -5089,7 +5350,7 @@ $wgAutopromote = [
  *
  * The format is:
  * @code
- *    array( event => criteria, ... )
+ *    [ event => criteria, ... ]
  * @endcode
  * Where event is either:
  *    - 'onEdit' (when user edits)
@@ -5120,15 +5381,15 @@ $wgAutopromoteOnceLogInRC = true;
  * @endcode
  * Bureaucrats can only remove bots and sysops:
  * @code
- * $wgRemoveGroups['bureaucrat'] = array( 'bot', 'sysop' );
+ * $wgRemoveGroups['bureaucrat'] = [ 'bot', 'sysop' ];
  * @endcode
  * Sysops can make bots:
  * @code
- * $wgAddGroups['sysop'] = array( 'bot' );
+ * $wgAddGroups['sysop'] = [ 'bot' ];
  * @endcode
  * Sysops can disable other sysops in an emergency, and disable bots:
  * @code
- * $wgRemoveGroups['sysop'] = array( 'sysop', 'bot' );
+ * $wgRemoveGroups['sysop'] = [ 'sysop', 'bot' ];
  * @endcode
  */
 $wgAddGroups = [];
@@ -5199,15 +5460,15 @@ $wgEnableDnsBlacklist = false;
  *
  * @par Example:
  * @code
- * $wgDnsBlacklistUrls = array(
+ * $wgDnsBlacklistUrls = [
  *   // String containing URL
  *   'http.dnsbl.sorbs.net.',
  *   // Array with URL and key, for services that require a key
- *   array( 'dnsbl.httpbl.net.', 'mykey' ),
+ *   [ 'dnsbl.httpbl.net.', 'mykey' ],
  *   // Array with just the URL. While this works, it is recommended that you
  *   // just use a string as shown above
- *   array( 'opm.tornevall.org.' )
- * );
+ *   [ 'opm.tornevall.org.' ]
+ * ];
  * @endcode
  *
  * @note You should end the domain name with a . to avoid searching your
@@ -5239,21 +5500,21 @@ $wgApplyIpBlocksToXff = false;
  * @par Example:
  * To set a generic maximum of 4 hits in 60 seconds:
  * @code
- *     $wgRateLimits = array( 4, 60 );
+ *     $wgRateLimits = [ 4, 60 ];
  * @endcode
  *
  * @par Example:
  * You could also limit per action and then type of users.
  * @code
- *     $wgRateLimits = array(
- *         'edit' => array(
- *             'anon' => array( x, y ), // any and all anonymous edits (aggregate)
- *             'user' => array( x, y ), // each logged-in user
- *             'newbie' => array( x, y ), // each new autoconfirmed accounts; overrides 'user'
- *             'ip' => array( x, y ), // each anon and recent account
- *             'subnet' => array( x, y ), // ... within a /24 subnet in IPv4 or /64 in IPv6
- *         )
- *     )
+ *     $wgRateLimits = [
+ *         'edit' => [
+ *             'anon' => [ x, y ], // any and all anonymous edits (aggregate)
+ *             'user' => [ x, y ], // each logged-in user
+ *             'newbie' => [ x, y ], // each new autoconfirmed accounts; overrides 'user'
+ *             'ip' => [ x, y ], // each anon and recent account
+ *             'subnet' => [ x, y ], // ... within a /24 subnet in IPv4 or /64 in IPv6
+ *         ]
+ *     ]
  * @endcode
  *
  * @warning Requires that $wgMainCacheType is set to something persistent
@@ -5378,7 +5639,6 @@ $wgGrantPermissions = [];
 
 $wgGrantPermissions['basic']['autoconfirmed'] = true;
 $wgGrantPermissions['basic']['autopatrol'] = true;
-$wgGrantPermissions['basic']['autoreview'] = true;
 $wgGrantPermissions['basic']['editsemiprotected'] = true;
 $wgGrantPermissions['basic']['ipblock-exempt'] = true;
 $wgGrantPermissions['basic']['nominornewtalk'] = true;
@@ -5386,7 +5646,6 @@ $wgGrantPermissions['basic']['patrolmarks'] = true;
 $wgGrantPermissions['basic']['purge'] = true;
 $wgGrantPermissions['basic']['read'] = true;
 $wgGrantPermissions['basic']['skipcaptcha'] = true;
-$wgGrantPermissions['basic']['torunblocked'] = true;
 $wgGrantPermissions['basic']['writeapi'] = true;
 
 $wgGrantPermissions['highvolume']['bot'] = true;
@@ -5461,6 +5720,8 @@ $wgGrantPermissions['sendemail']['sendemail'] = true;
 
 $wgGrantPermissions['createaccount']['createaccount'] = true;
 
+$wgGrantPermissions['privateinfo']['viewmyprivateinfo'] = true;
+
 /**
  * @var Array Map of grants to their UI grouping
  * @since 1.27
@@ -5494,6 +5755,8 @@ $wgGrantPermissionGroups = [
        'createaccount'       => 'administration',
 
        'highvolume'          => 'high-volume',
+
+       'privateinfo'         => 'private-information',
 ];
 
 /**
@@ -5554,14 +5817,6 @@ $wgProxyList = [];
  */
 $wgCookieExpiration = 180 * 86400;
 
-/**
- * The identifiers of the login cookies that can have their lifetimes
- * extended independently of all other login cookies.
- *
- * @var string[]
- */
-$wgExtendedLoginCookies = [ 'UserID', 'Token' ];
-
 /**
  * Default login cookie lifetime, in seconds. Setting
  * $wgExtendLoginCookieExpiration to null will use $wgCookieExpiration to
@@ -5718,6 +5973,12 @@ $wgTrxProfilerLimits = [
                'writes' => 0,
                'readQueryTime' => 5
        ],
+       // Deferred updates that run after HTTP response is sent
+       'PostSend' => [
+               'readQueryTime' => 5,
+               'writeQueryTime' => 1,
+               'maxAffected' => 500
+       ],
        // Background job runner
        'JobRunner' => [
                'readQueryTime' => 30,
@@ -5754,11 +6015,11 @@ $wgTrxProfilerLimits = [
  *
  * @par Advanced example:
  * @code
- * $wgDebugLogGroups['memcached'] = array(
+ * $wgDebugLogGroups['memcached'] = [
  *     'destination' => '/var/log/mediawiki/memcached.log',
  *     'sample' => 1000,  // log 1 message out of every 1,000.
  *     'level' => \Psr\Log\LogLevel::WARNING
- * );
+ * ];
  * @endcode
  */
 $wgDebugLogGroups = [];
@@ -5777,7 +6038,7 @@ $wgDebugLogGroups = [];
  *
  * @par To completely disable logging:
  * @code
- * $wgMWLoggerDefaultSpi = array( 'class' => '\\MediaWiki\\Logger\\NullSpi' );
+ * $wgMWLoggerDefaultSpi = [ 'class' => '\\MediaWiki\\Logger\\NullSpi' ];
  * @endcode
  *
  * @since 1.25
@@ -5895,7 +6156,7 @@ $wgStatsdServer = false;
 /**
  * Prefix for metric names sent to $wgStatsdServer.
  *
- * @see RequestContext::getStats
+ * @see MediaWikiServices::getStatsdDataFactory
  * @see BufferingStatsdDataFactory
  * @since 1.25
  */
@@ -6095,10 +6356,10 @@ $wgSitemapNamespaces = false;
  * This should be a map of namespace IDs to priority
  * @par Example:
  * @code
- *  $wgSitemapNamespacesPriorities = array(
+ *  $wgSitemapNamespacesPriorities = [
  *      NS_USER => '0.9',
  *      NS_HELP => '0.0',
- *  );
+ *  ];
  * @endcode
  */
 $wgSitemapNamespacesPriorities = false;
@@ -6305,18 +6566,18 @@ $wgRCLinkDays = [ 1, 3, 7, 14, 30 ];
  *  The JSON-specific options are:
  *   * 'channel' -- if set, the 'channel' parameter is also set in JSON values.
  *
- * @example $wgRCFeeds['example'] = array(
+ * @example $wgRCFeeds['example'] = [
  *             'formatter' => 'JSONRCFeedFormatter',
  *             'uri' => "udp://localhost:1336",
  *             'add_interwiki_prefix' => false,
  *             'omit_bots' => true,
- *     );
- * @example $wgRCFeeds['exampleirc'] = array(
+ *     ];
+ * @example $wgRCFeeds['exampleirc'] = [
  *             'formatter' => 'IRCColourfulRCFeedFormatter',
  *             'uri' => "udp://localhost:1338",
  *             'add_interwiki_prefix' => false,
  *             'omit_bots' => true,
- *     );
+ *     ];
  * @since 1.22
  */
 $wgRCFeeds = [];
@@ -6478,7 +6739,7 @@ $wgUnwatchedPageThreshold = false;
  *
  * To register a new one:
  * @code
- * $wgRecentChangesFlags['flag'] => array(
+ * $wgRecentChangesFlags['flag'] => [
  *   // message for the letter displayed next to rows on changes lists
  *   'letter' => 'letter-msg',
  *   // message for the tooltip of the letter
@@ -6491,7 +6752,7 @@ $wgUnwatchedPageThreshold = false;
  *   // will set the top-level flag if any line contains the flag, 'all' will
  *   // only be set if all lines contain the flag.
  *   'grouping' => 'any',
- * );
+ * ];
  * @endcode
  *
  * @since 1.22
@@ -6597,11 +6858,11 @@ $wgShowCreditsIfMax = true;
  * subprojects on the interwiki map of the target wiki, or a mix of the two,
  * e.g.
  * @code
- *     $wgImportSources = array(
- *         'wikipedia' => array( 'cs', 'en', 'fr', 'zh' ),
+ *     $wgImportSources = [
+ *         'wikipedia' => [ 'cs', 'en', 'fr', 'zh' ],
  *         'wikispecies',
- *         'wikia' => array( 'animanga', 'brickipedia', 'desserts' ),
- *     );
+ *         'wikia' => [ 'animanga', 'brickipedia', 'desserts' ],
+ *     ];
  * @endcode
  *
  * If you have a very complex import sources setup, you can lazy-load it using
@@ -6729,11 +6990,11 @@ $wgExtensionMessagesFiles = [];
  *
  * @par Complex example:
  * @code
- *    $wgMessagesDirs['Example'] = array(
+ *    $wgMessagesDirs['Example'] = [
  *        __DIR__ . '/lib/ve/i18n',
  *        __DIR__ . '/lib/oojs-ui/i18n',
  *        __DIR__ . '/i18n',
- *    )
+ *    ]
  * @endcode
  * @since 1.23
  */
@@ -6803,18 +7064,18 @@ $wgAutoloadAttemptLowercase = true;
  * All but 'name', 'path' and 'author' can be omitted.
  *
  * @code
- * $wgExtensionCredits[$type][] = array(
+ * $wgExtensionCredits[$type][] = [
  *     'path' => __FILE__,
  *     'name' => 'Example extension',
  *     'namemsg' => 'exampleextension-name',
- *     'author' => array(
+ *     'author' => [
  *         'Foo Barstein',
- *     ),
+ *     ],
  *     'version' => '1.9.0',
  *     'url' => 'http://example.org/example-extension/',
  *     'descriptionmsg' => 'exampleextension-desc',
  *     'license-name' => 'GPL-2.0+',
- * );
+ * ];
  * @endcode
  *
  * The extensions are listed on Special:Version. This page also looks for a file
@@ -6854,6 +7115,7 @@ $wgExtensionCredits = [];
 /**
  * Authentication plugin.
  * @var $wgAuth AuthPlugin
+ * @deprecated since 1.27 use $wgAuthManagerConfig instead
  */
 $wgAuth = null;
 
@@ -6872,11 +7134,11 @@ $wgAuth = null;
  * @endcode
  * - A function with some data:
  * @code
- *     $wgHooks['event_name'][] = array( $function, $data );
+ *     $wgHooks['event_name'][] = [ $function, $data ];
  * @endcode
  * - A an object method:
  * @code
- *     $wgHooks['event_name'][] = array( $object, 'method' );
+ *     $wgHooks['event_name'][] = [ $object, 'method' ];
  * @endcode
  * - A closure:
  * @code
@@ -7001,7 +7263,7 @@ $wgSpecialPageCacheUpdates = [
  * Hooks that are used for outputting exceptions.  Format is:
  *   $wgExceptionHooks[] = $funcname
  * or:
- *   $wgExceptionHooks[] = array( $class, $funcname )
+ *   $wgExceptionHooks[] = [ $class, $funcname ]
  * Hooks should return strings or false
  */
 $wgExceptionHooks = [];
@@ -7117,10 +7379,7 @@ $wgLogRestrictions = [
  *
  * @par Example:
  * @code
- *   $wgFilterLogTypes = array(
- *      'move' => true,
- *      'import' => false,
- *   );
+ *   $wgFilterLogTypes = [ 'move' => true, 'import' => false ];
  * @endcode
  *
  * Will display show/hide links for the move and import logs. Move logs will be
@@ -7273,7 +7532,7 @@ $wgActionFilteredLogs = [
        ],
        'newusers' => [
                'create' => [ 'create', 'newusers' ],
-               'create2' => ['create2' ],
+               'create2' => [ 'create2' ],
                'autocreate' => [ 'autocreate' ],
                'byemail' => [ 'byemail' ],
        ],
@@ -7285,7 +7544,7 @@ $wgActionFilteredLogs = [
                'protect' => [ 'protect' ],
                'modify' => [ 'modify' ],
                'unprotect' => [ 'unprotect' ],
-               'move_prot' => ['move_prot'],
+               'move_prot' => [ 'move_prot' ],
        ],
        'rights' => [
                'rights' => [ 'rights' ],
@@ -7404,7 +7663,7 @@ $wgDefaultRobotPolicy = 'index,follow';
  *
  * @par Example:
  * @code
- *   $wgNamespaceRobotPolicies = array( NS_TALK => 'noindex' );
+ *   $wgNamespaceRobotPolicies = [ NS_TALK => 'noindex' ];
  * @endcode
  */
 $wgNamespaceRobotPolicies = [];
@@ -7416,23 +7675,23 @@ $wgNamespaceRobotPolicies = [];
  *
  * @par Example:
  * @code
- * $wgArticleRobotPolicies = array(
+ * $wgArticleRobotPolicies = [
  *         'Main Page' => 'noindex,follow',
  *         'User:Bob' => 'index,follow',
- * );
+ * ];
  * @endcode
  *
  * @par Example that DOES NOT WORK because the names are not canonical text
  * forms:
  * @code
- *   $wgArticleRobotPolicies = array(
+ *   $wgArticleRobotPolicies = [
  *     # Underscore, not space!
  *     'Main_Page' => 'noindex,follow',
  *     # "Project", not the actual project name!
  *     'Project:X' => 'index,follow',
  *     # Needs to be "Abc", not "abc" (unless $wgCapitalLinks is false for that namespace)!
  *     'abc' => 'noindex,nofollow'
- *   );
+ *   ];
  * @endcode
  */
 $wgArticleRobotPolicies = [];
@@ -7444,7 +7703,7 @@ $wgArticleRobotPolicies = [];
  *
  * @par Example:
  * @code
- *   $wgExemptFromUserRobotsControl = array( NS_MAIN, NS_TALK, NS_PROJECT );
+ *   $wgExemptFromUserRobotsControl = [ NS_MAIN, NS_TALK, NS_PROJECT ];
  * @endcode
  */
 $wgExemptFromUserRobotsControl = null;
@@ -7513,14 +7772,14 @@ $wgDebugAPI = false;
  *
  * @code
  *  $wgAPIModules['foo'] = 'ApiFoo';
- *  $wgAPIModules['bar'] = array(
+ *  $wgAPIModules['bar'] = [
  *    'class' => 'ApiBar',
  *    'factory' => function( $main, $name ) { ... }
- *  );
- *  $wgAPIModules['xyzzy'] = array(
+ *  ];
+ *  $wgAPIModules['xyzzy'] = [
  *    'class' => 'ApiXyzzy',
- *    'factory' => array( 'XyzzyFactory', 'newApiModule' )
- *  );
+ *    'factory' => [ 'XyzzyFactory', 'newApiModule' ]
+ *  ];
  * @endcode
  *
  * Extension modules may override the core modules.
@@ -7650,12 +7909,12 @@ $wgAjaxEditStash = true;
  *
  * @par Example:
  * @code
- * $wgCrossSiteAJAXdomains = array(
+ * $wgCrossSiteAJAXdomains = [
  *     'www.mediawiki.org',
  *     '*.wikipedia.org',
  *     '*.wikimedia.org',
  *     '*.wiktionary.org',
- * );
+ * ];
  * @endcode
  */
 $wgCrossSiteAJAXdomains = [];
@@ -7792,9 +8051,13 @@ $wgJobRunRate = 1;
  * When $wgJobRunRate > 0, try to run jobs asynchronously, spawning a new process
  * to handle the job execution, instead of blocking the request until the job
  * execution finishes.
+ *
  * @since 1.23
  */
-$wgRunJobsAsync = true;
+$wgRunJobsAsync = (
+       !function_exists( 'register_postsend_function' ) &&
+       !function_exists( 'fastcgi_finish_request' )
+);
 
 /**
  * Number of rows to update per job
@@ -7815,10 +8078,9 @@ $wgUpdateRowsPerQuery = 100;
 
 /**
  * Name of the external diff engine to use. Supported values:
- * * false: default PHP implementation, DairikiDiff
- * * 'wikidiff2': Wikimedia's fast difference engine implemented as a PHP/HHVM module
- * * 'wikidiff3': newer PHP-based difference engine
- * * any other string is treated as a path to external diff executable
+ * * string: path to an external diff executable
+ * * false: wikidiff2 PHP/HHVM module if installed, otherwise the default PHP implementation
+ * * 'wikidiff', 'wikidiff2', and 'wikidiff3' are treated as false for backwards compatibility
  */
 $wgExternalDiffEngine = false;
 
@@ -7872,13 +8134,13 @@ $wgRedirectOnLogin = null;
  *
  * @par Example:
  * @code
- *   $wgPoolCounterConf = array( 'ArticleView' => array(
+ *   $wgPoolCounterConf = [ 'ArticleView' => [
  *     'class' => 'PoolCounter_Client',
  *     'timeout' => 15, // wait timeout in seconds
  *     'workers' => 5, // maximum number of active threads in each pool
  *     'maxqueue' => 50, // maximum number of total threads in each pool
  *     ... any extension-specific options...
- *   );
+ *   ];
  * @endcode
  */
 $wgPoolCounterConf = null;
@@ -7941,13 +8203,6 @@ $wgTextModelsToParse = [
        CONTENT_MODEL_CSS, // Make categories etc work, people put them into comments.
 ];
 
-/**
- * Whether the user must enter their password to change their e-mail address
- *
- * @since 1.20
- */
-$wgRequirePasswordforEmailChange = true;
-
 /**
  * Register handlers for specific types of sites.
  *
@@ -7972,6 +8227,23 @@ $wgPagePropsHaveSortkey = true;
  */
 $wgHttpsPort = 443;
 
+/**
+ * Secret for session storage.
+ * This should be set in LocalSettings.php, otherwise wgSecretKey will
+ * be used.
+ * @since 1.27
+ */
+$wgSessionSecret = false;
+
+/**
+ * If for some reason you can't install the PHP OpenSSL or mcrypt extensions,
+ * you can set this to true to make MediaWiki work again at the cost of storing
+ * sensitive session data insecurely. But it would be much more secure to just
+ * install the OpenSSL extension.
+ * @since 1.27
+ */
+$wgSessionInsecureSecrets = false;
+
 /**
  * Secret for hmac-based key derivation function (fast,
  * cryptographically secure random numbers).
@@ -8000,24 +8272,43 @@ $wgPageLanguageUseDB = false;
 
 /**
  * Global configuration variable for Virtual REST Services.
- * Parameters for different services are to be declared inside
- * $wgVirtualRestConfig['modules'], which is to be treated as an associative
- * array. Global parameters will be merged with service-specific ones. The
- * result will then be passed to VirtualRESTService::__construct() in the
- * module.
+ *
+ * Use the 'path' key to define automatically mounted services. The value for this
+ * key is a map of path prefixes to service configuration. The later is an array of:
+ *   - class : the fully qualified class name
+ *   - options : map of arguments to the class constructor
+ * Such services will be available to handle queries under their path from the VRS
+ * singleton, e.g. MediaWikiServices::getInstance()->getVirtualRESTServiceClient();
+ *
+ * Auto-mounting example for Parsoid:
+ *
+ * $wgVirtualRestConfig['paths']['/parsoid/'] = [
+ *     'class' => 'ParsoidVirtualRESTService',
+ *     'options' => [
+ *         'url' => 'http://localhost:8000',
+ *         'prefix' => 'enwiki',
+ *         'domain' => 'en.wikipedia.org'
+ *     ]
+ * ];
+ *
+ * Parameters for different services can also be declared inside the 'modules' value,
+ * which is to be treated as an associative array. The parameters in 'global' will be
+ * merged with service-specific ones. The result will then be passed to
+ * VirtualRESTService::__construct() in the module.
  *
  * Example config for Parsoid:
  *
- *   $wgVirtualRestConfig['modules']['parsoid'] = array(
+ *   $wgVirtualRestConfig['modules']['parsoid'] = [
  *     'url' => 'http://localhost:8000',
  *     'prefix' => 'enwiki',
  *     'domain' => 'en.wikipedia.org',
- *   );
+ *   ];
  *
  * @var array
  * @since 1.25
  */
 $wgVirtualRestConfig = [
+       'paths' => [],
        'modules' => [],
        'global' => [
                # Timeout in seconds
@@ -8060,7 +8351,7 @@ $wgPopularPasswordFile = __DIR__ . '/../serialized/commonpasswords.cdb';
 $wgMaxUserDBWriteDuration = false;
 
 /**
- * Mapping of event channels to EventRelayer configuration.
+ * Mapping of event channels (or channel categories) to EventRelayer configuration.
  *
  * By setting up a PubSub system (like Kafka) and enabling a corresponding EventRelayer class
  * that uses it, MediaWiki can broadcast events to all subscribers. Certain features like WAN
@@ -8068,7 +8359,13 @@ $wgMaxUserDBWriteDuration = false;
  * subscribe to the channel and take actions based on the events. For example, a local daemon
  * can run on each CDN cache node and perfom local purges based on the URL purge channel events.
  *
- * The 'default' channel is for all channels without an explicit entry here.
+ * Some extensions may want to use "channel categories" so that different channels can also share
+ * the same custom relayer instance (e.g. when it's likely to be overriden). They can use
+ * EventRelayerGroup::getRelayer() based on the category but call notify() on various different
+ * actual channels. One reason for this would be that some system have very different performance
+ * vs durability needs, so one system (e.g. Kafka) may not be suitable for all uses.
+ *
+ * The 'default' key is for all channels (or channel categories) without an explicit entry here.
  *
  * @since 1.27
  */
@@ -8078,6 +8375,43 @@ $wgEventRelayerConfig = [
        ]
 ];
 
+/**
+ * Share data about this installation with MediaWiki developers
+ *
+ * When set to true, MediaWiki will periodically ping https://www.mediawiki.org/ with basic
+ * data about this MediaWiki instance. This data includes, for example, the type of system,
+ * PHP version, and chosen database backend. The Wikimedia Foundation shares this data with
+ * MediaWiki developers to help guide future development efforts.
+ *
+ * For details about what data is sent, see: https://www.mediawiki.org/wiki/Manual:$wgPingback
+ *
+ * @var bool
+ * @since 1.28
+ */
+$wgPingback = false;
+
+/**
+ * List of urls which appear often to be triggering CSP reports
+ * but do not appear to be caused by actual content, but by client
+ * software inserting scripts (i.e. Ad-Ware).
+ * List based on results from Wikimedia logs.
+ *
+ * @since 1.28
+ */
+$wgCSPFalsePositiveUrls = [
+       'https://3hub.co' => true,
+       'https://morepro.info' => true,
+       'https://p.ato.mx' => true,
+       'https://s.ato.mx' => true,
+       'https://adserver.adtech.de' => true,
+       'https://ums.adtechus.com' => true,
+       'https://cas.criteo.com' => true,
+       'https://cat.nl.eu.criteo.com' => true,
+       'https://atpixel.alephd.com' => true,
+       'https://rtb.metrigo.com' => true,
+       'https://d5p.de17a.com' => true,
+];
+
 /**
  * For really cool vim folding this needs to be at the end:
  * vim: foldmarker=@{,@} foldmethod=marker